npm node-sass安装失败解决方法

node-sass安装失败,提示如下:

gyp verb check python checking for Python executable "python" in the PATH
gyp verb `which` succeeded python D:\Program Files\Python38\python.EXE
gyp ERR! configure error
gyp ERR! stack Error: Command failed: D:\Program Files\Python38\python.EXE -c import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack   File "<string>", line 1
gyp ERR! stack     import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack                       ^
gyp ERR! stack SyntaxError: invalid syntax
gyp ERR! stack
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:303:12)
gyp ERR! stack     at ChildProcess.emit (events.js:310:20)
gyp ERR! stack     at maybeClose (internal/child_process.js:1021:16)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
gyp ERR! System Windows_NT 10.0.18362
gyp ERR! command "D:\\Program Files\\nodejs\\node.exe" "E:\\JDProject\\renren-fast-vue\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd E:\JDProject\renren-fast-vue\node_modules\node-sass
gyp ERR! node -v v12.16.3
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Build failed with error code: 1
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.9.0 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node-sass@4.9.0 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\HP\AppData\Roaming\npm-cache\_logs\2020-05-23T06_27_44_952Z-debug.log

  

原因

print "%s.%s.%s" % sys.version_info[:3];

为python2.x版本的语法,如果本地安装的是python3.x,就会报此错误

 

解决方法:

 1. 删除项目中的package-lock.json文件,清除缓存,更新版本号

  #后续步骤运行npm install 命令时会重新生成package-lock.json文件

 

1 npm cache clear --force
2 修改 package.json 文件 提高 node-sass 版本
"node-sass": "4.14.1",
    "npm": "^6.14.5",  #sass-loader版本为可选项,如果项目很旧,sass-loader版本最好不要改动,否则容易引起项目启动异常
    "sass-loader": "8.0.2",
3 保存后重新 npm install 即可



之所以报 就是上面那个该死的 "C\Python27\python.exe"找不到。 

原因是 node-sass跟node就版本对应的问题的。

打开命令行 查看 node版本: node  -v

 

node版本不对应,升级node或者降级

查看node-sass和sass-loader版本是否对应
以下是部分版本号对应,具体可百度

sass-loader 4.1.1,node-sass 4.3.0
sass-loader 7.0.3,node-sass 4.7.2
sass-loader 7.3.1,node-sass 4.7.2
sass-loader 7.3.1,node-sass 4.14.1

 


在项目环境中执行

npm uninstall node-sass sass-loader
npm install sass-loader@版本号 node-sass@版本号 --save-dev //安装对应的版本

 

 

 

 

 

----------------------------------------------------------

<template>
  <el-dialog 
    v-model="innerVisible" 
    :title="dialogTitle" 
    width="800px" 
    :top="'5vh'"
    :align-center="false"
  >
    <el-form :model="form" label-width="100px" :rules="rules">
      <!-- 基本信息 -->
      <div class="section-title">
        <div class="section-line"></div>
        <span class="title-text">基本信息</span>
      </div>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="规则代码" prop="ruleCode" required>
            <el-input v-model="form.ruleCode" placeholder="请输入" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="规则名称" prop="ruleName" required>
            <el-input v-model="form.ruleName" placeholder="请输入" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="是否内置" required>
            <el-radio-group v-model="form.isBuiltin">
              <el-radio :label="true">是</el-radio>
              <el-radio :label="false">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.isBuiltin">
          <el-form-item label="研发组织" required>
            <el-select v-model="form.devOrg" placeholder="请选择">
              <el-option label="研发一部" value="dev1" />
              <el-option label="研发二部" value="dev2" />
              <el-option label="PPMI-SBU1" value="PPMI-SBU1" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="描述">
        <el-input v-model="form.desc" type="textarea" rows="3" />
      </el-form-item>

      <!-- 编码配置 -->
      <div class="config-header">
        <div class="section-title">
          <div class="section-line"></div>
          <span class="title-text">编码配置</span>
        </div>
        <el-button type="primary" class="add-button" @click="addSection">
          <el-icon><Plus /></el-icon> 新增
        </el-button>
      </div>
      
      <el-form-item label="编码示例">
        <el-input v-model="form.example" disabled />
        <div style="margin-top: 5px; color: #666;">
          说明:1. 字段可以配置多个,2. 每个配置都必须填写
        </div>
      </el-form-item>

      <!-- 使用vuedraggable实现拖拽排序 -->
      <draggable 
        v-model="form.sections" 
        item-key="id"
        handle=".drag-handle"
        :animation="150"
        ghost-class="ghost"
      >
        <template #item="{element, index}">
          <div class="code-section" :class="`section-${index + 1}`">
            <div class="section-header">
              <div class="section-left">
                <el-icon class="drag-handle"><Operation /></el-icon>
                <span>编码{{ numberToChinese(index + 1) }}段</span>
              </div>
              <div class="section-right">
                <el-select 
                  v-model="element.type" 
                  placeholder="请选择" 
                  class="type-select"
                >
                  <el-option label="常量" value="constant" />
                  <el-option label="日期" value="date" />
                  <el-option label="流水码" value="sequence" />
                  <el-option label="业务字段" value="business" />
                </el-select>
                <el-button 
                  type="danger" 
                  :icon="Delete" 
                  circle 
                  size="small"
                  @click="removeSection(index)"
                  class="delete-btn"
                ></el-button>
              </div>
            </div>
            
            <!-- 不同类型的编码显示不同的表单项 -->
            <div class="section-content">
              <!-- 常量类型 -->
              <template v-if="element.type === 'constant'">
                <el-form-item label="设置值" required>
                  <el-input v-model="element.value" placeholder="请输入" />
                </el-form-item>
              </template>
              
              <!-- 日期类型 -->
              <template v-if="element.type === 'date'">
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="日期格式" required>
                      <el-select v-model="element.dateFormat" placeholder="请选择">
                        <el-option label="年月日" value="yyyyMMdd" />
                        <el-option label="年月" value="yyyyMM" />
                        <el-option label="月日" value="MMdd" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="码制" required>
                      <el-select v-model="element.codeSystem" placeholder="请选择">
                        <el-option label="10进制" value="10" />
                        <el-option label="16进制" value="16" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="段间分隔符">
                  <el-select v-model="element.separator" placeholder="请选择">
                    <el-option label="-" value="-" />
                    <el-option label="_" value="_" />
                    <el-option label="/" value="/" />
                    <el-option label="无" value="" />
                  </el-select>
                </el-form-item>
              </template>
              
              <!-- 流水码类型 -->
              <template v-if="element.type === 'sequence'">
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="长度" required>
                      <el-input v-model.number="element.length" type="number" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="步长" required>
                      <el-input v-model.number="element.step" type="number" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="码制" required>
                      <el-select v-model="element.codeSystem" placeholder="请选择">
                        <el-option label="10进制" value="10" />
                        <el-option label="16进制" value="16" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="自动升位">
                      <el-switch 
                        v-model="element.autoIncrement" 
                        class="green-switch"
                        active-color="#67c23a"
                        inactive-color="#dcdfe6"
                      />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="段间分隔符">
                  <el-select v-model="element.separator" placeholder="请选择">
                    <el-option label="-" value="-" />
                    <el-option label="_" value="_" />
                    <el-option label="/" value="/" />
                    <el-option label="无" value="" />
                  </el-select>
                </el-form-item>
              </template>
              
              <!-- 业务字段类型 -->
              <template v-if="element.type === 'business'">
                <el-form-item label="业务字段" required>
                  <el-select v-model="element.businessField" placeholder="请选择">
                    <el-option label="产品名称" value="productName" />
                    <el-option label="客户编号" value="customerCode" />
                    <el-option label="订单号" value="orderId" />
                  </el-select>
                </el-form-item>
                <el-form-item label="截取模式">
                  <el-select v-model="element.extractMode" placeholder="请选择">
                    <el-option label="前缀截取" value="prefix" />
                    <el-option label="后缀截取" value="suffix" />
                    <el-option label="无截取" value="none" />
                  </el-select>
                </el-form-item>
                <el-form-item label="段间分隔符">
                  <el-select v-model="element.separator" placeholder="请选择">
                    <el-option label="-" value="-" />
                    <el-option label="_" value="_" />
                    <el-option label="/" value="/" />
                    <el-option label="无" value="" />
                  </el-select>
                </el-form-item>
              </template>
            </div>
          </div>
        </template>
      </draggable>

    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="success" @click="submit">提交</el-button>
        <el-button @click="innerVisible = false">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, watch, defineProps, defineEmits, computed } from 'vue'
import { Delete, Plus, Operation } from '@element-plus/icons-vue'
import draggable from 'vuedraggable'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '新增'
  },
  isEdit: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['update:visible'])

const innerVisible = ref(props.visible)
const dialogTitle = computed(() => props.title)

watch(() => props.visible, val => {
  innerVisible.value = val
})
watch(innerVisible, val => {
  emit('update:visible', val)
})

// 将数字转换为中文数字
function numberToChinese(num) {
  if (typeof num !== 'number') {
    num = parseInt(num);
  }
  
  if (isNaN(num) || num < 1) {
    return '一';
  }
  
  const digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
  const positions = ['', '十', '百', '千', '万', '十万', '百万', '千万', '亿'];
  
  // 处理1-10的数字
  if (num >= 1 && num <= 10) {
    if (num === 10) return '十';
    return digits[num];
  }
  
  // 处理11-99的数字
  if (num > 10 && num < 100) {
    const tens = Math.floor(num / 10);
    const ones = num % 10;
    
    if (tens === 1) {
      return ones > 0 ? '十' + digits[ones] : '十';
    } else {
      return ones > 0 ? digits[tens] + '十' + digits[ones] : digits[tens] + '十';
    }
  }
  
  // 处理100以上的数字(保险起见,虽然一般不会有超过100个编码段)
  let result = '';
  const numStr = num.toString();
  const len = numStr.length;
  
  for (let i = 0; i < len; i++) {
    const digit = parseInt(numStr[i]);
    const pos = len - i - 1;
    
    if (digit === 0) {
      // 避免零零这样的重复
      if (result.charAt(result.length - 1) !== '零') {
        result += '零';
      }
    } else {
      result += digits[digit] + positions[pos];
    }
  }
  
  // 处理一些零的情况
  result = result.replace(/零+$/, '');
  result = result.replace(/零+/, '零');
  
  return result || '零';
}

// 表单校验规则
const rules = {
  ruleCode: [{ required: true, message: '请输入规则代码', trigger: 'blur' }],
  ruleName: [{ required: true, message: '请输入规则名称', trigger: 'blur' }]
}

// 生成唯一ID
const generateId = () => {
  return Date.now() + Math.floor(Math.random() * 1000)
}

// 默认的分隔符
const DEFAULT_SEPARATOR = '-'

const form = reactive({
  ruleCode: 'LX202504001',
  ruleName: '',
  isBuiltin: true,
  devOrg: 'PPMI-SBU1',
  desc: '',
  example: 'LX202504001',
  sections: [
    {
      id: generateId(),
      type: 'constant',
      value: 'LX'
    },
    {
      id: generateId(),
      type: 'date',
      dateFormat: 'yyyyMMdd',
      codeSystem: '10',
      separator: DEFAULT_SEPARATOR
    },
    {
      id: generateId(),
      type: 'sequence',
      length: 3,
      step: 1,
      codeSystem: '10',
      autoIncrement: true,
      separator: DEFAULT_SEPARATOR
    },
    {
      id: generateId(),
      type: 'business',
      businessField: 'productName',
      extractMode: 'none',
      separator: DEFAULT_SEPARATOR
    }
  ]
})

// 添加新编码段
function addSection() {
  form.sections.push({
    id: generateId(),
    type: 'constant',
    value: '',
    separator: DEFAULT_SEPARATOR
  })
}

// 移除编码段
function removeSection(index) {
  form.sections.splice(index, 1)
}

// 提交表单
function submit() {
  // 表单提交逻辑
  console.log('提交的表单数据:', form)
  innerVisible.value = false
}
</script>

<style scoped>
.section-title {
  display: flex;
  align-items: center;
  margin: 20px 0;
}

.section-line {
  width: 4px;
  height: 20px;
  background-color: #409EFF;
  margin-right: 8px;
  border-radius: 2px;
}

.title-text {
  font-size: 18px;
  font-weight: 600;
}

.config-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 20px 0;
  position: relative;
}

.divider-wrapper {
  flex: 1;
}

.add-button {
  z-index: 1;
  position: absolute;
  right: 0;
  background-color: #67c23a;
  border-color: #67c23a;
}

.code-section {
  margin-bottom: 15px;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 15px;
  border-bottom: 1px dashed #EBEEF5;
  background-color: #f0f9eb;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}

.section-left {
  display: flex;
  align-items: center;
}

.section-right {
  display: flex;
  align-items: center;
  gap: 20px;
}

.type-select {
  width: 120px;
}

.delete-btn {
  background-color: #f56c6c;
  border-color: #f56c6c;
}

.drag-handle {
  cursor: move;
  margin-right: 8px;
  color: #909399;
}

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

.section-content {
  padding: 15px;
  background-color: #ffffff;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.green-switch :deep(.el-switch__core) {
  background-color: #dcdfe6 !important;
  border-color: #dcdfe6 !important;
}

.green-switch :deep(.el-switch__core):hover {
  background-color: #dcdfe6 !important;
  border-color: #dcdfe6 !important;
}

.green-switch.is-checked :deep(.el-switch__core) {
  background-color: #67c23a !important;
  border-color: #67c23a !important;
}
</style> 

  

<script setup>
import { ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
import CodeConfigDialog from './components/CodeConfigDialog.vue'
import { Plus, Edit } from '@element-plus/icons-vue'

const showDialog = ref(false)
const dialogTitle = ref('新增')

function openDialog(title = '新增') {
  dialogTitle.value = title
  showDialog.value = true
}
</script>

<template>
  <div class="container">
    <div class="logo-container">
      <a href="https://vite.dev" target="_blank">
        <img src="/vite.svg" class="logo" alt="Vite logo" />
      </a>
      <a href="https://vuejs.org/" target="_blank">
        <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
      </a>
    </div>
    
    <HelloWorld msg="Vite + Vue" />
    
    <div class="button-container">
      <el-button type="primary" size="large" @click="openDialog()">
        <el-icon><Plus /></el-icon> 打开编码配置弹窗
      </el-button>
      <el-button type="warning" size="large" @click="openDialog('编辑')">
        <el-icon><Edit /></el-icon> 编辑编码配置
      </el-button>
    </div>
    
    <CodeConfigDialog v-model:visible="showDialog" :title="dialogTitle" />
  </div>
</template>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2rem;
  text-align: center;
}

.logo-container {
  display: flex;
  margin-bottom: 2rem;
}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}

.button-container {
  margin-top: 2rem;
  display: flex;
  gap: 1rem;
}
</style>

  

 

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

  

 

:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

.card {
  padding: 2em;
}

#app {
  max-width: 1280px;
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}

  

 




posted @ 2021-10-19 10:59  Samuel-Leung  阅读(5166)  评论(0)    收藏  举报