首页 » 前端 » 正文

node-sass、node-gyp依赖问题排查

最近公司买了一套系统,我clone下来在本地运行,项目install的报错,后面好多流程就都被阻塞了,也是吭哧了好久,记录一下,项目环境要求:

  • Node.js:12.22.12
  • Yarn:1.22.19
  • Python:2.7 # node-sass需要

难怪报错,都tm这么旧的版本.

1、问题信息

先看下面这个最初的报错:

gyp ERR! UNCAUGHT EXCEPTION
gyp ERR! stack Error: spawn C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\15.0\Bin\MSBuild.exe ENOENT
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:277:19)
gyp ERR! stack     at onErrorNT (internal/child_process.js:472:16)
gyp ERR! stack     at processTicksAndRejections (internal/process/task_queues.js:82:21)
gyp ERR! System Windows_NT 10.0.22000
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "E:\\dm-web\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd E:\dm-web\node_modules\node-sass
gyp ERR! node -v v14.21.3
gyp ERR! node-gyp -v v3.8.0
gyp ERR! This is a bug in `node-gyp`.
gyp ERR! Try to update node-gyp and file an Issue if it does not help:

看到说node-gyp报错,那就升级一下,先看看版本

E:\dm-web>node-gyp -v
C:\Users\lenovo\AppData\Roaming\nvm\v12.22.12\node_modules\node-gyp\bin\node-gyp.js:81
    const args = await prog.commands[command.name](command.args) ??| []
                                                                  ^

SyntaxError: Unexpected token '?'
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

不识别ES6语法,应该是版本过高了,至于高底,可以网上查一下对应版本,我这里查的改成低版本

npm install -g node-gyp@5.1.0

修改后再次install,发现报错还在,从另一个方向看:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\15.0\Bin\MSBuild.exe但是这个并不存在,它需C++解析,但是现在看是Visual Studio Build Tools 缺失,MSBuild.exe 路径无效或编译链缺失。

解决方案:下载并安装 Visual Studio 2019 Build Tools ,勾选 “C++桌面开发” 和 “Windows SDK” 组件17。

763DB529-9DD1-4d33-A65B-22D76095BEB8.png

其实安装后还是有报错,既然路径有问题,那就配置 npm 指定版本的MSBuild路径:

node-gyp configure --msbuild_path="C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe"

好吧,还是报错,说没有binding.gyp

gyp: binding.gyp not found (cwd: E:\dm-web) while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Users\lenovo\AppData\Roaming\nvm\v12.22.12\node_modules\node-gyp\lib\configure.js:351:16)
gyp ERR! stack     at ChildProcess.emit (events.js:314:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)
gyp ERR! System Windows_NT 10.0.22000
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\node-gyp\\bin\\node-gyp.js" "configure" "--msbuild_path=C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\MSBuild\\Current\\Bin\\MSBuild.exe"
gyp ERR! cwd E:\dm-web
gyp ERR! node -v v12.22.12
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok

目前来看是走到了死胡同,每走一步都遇到问题,每解决一步都会有新的阻塞……总结有几种问题:

  • E:\dm-web\node_modules\node-sass:Command failed,node-sass已经不维护,官方推荐使用sass和sass-loader;
  • 卸载node-sass,发现打包结果丢失index.html;
  • node-gyp手动全局下载,但是无法进行path修改;

2、解决方法

// 在package.json项目dev中添加node-gyp依赖
"devDependencies": {
    "node-gyp": "3.8.0"
}

// 在yarn.lock文件添加对应的依赖限制,如果没有lock应该就不用处理这个
node-gyp@3.8.0, node-gyp@^3.8.0:
Dingtalk_20250303092914.jpg

另外还需要先清理缓存再install

yarn cache clean
// 有必要的话把node_modules都删除
yarn install

3、问题分析

之前的node-gyp是install -g全局安装的,这个时候我得骂那个对接人@%#¥¥*&¥%#

1. 版本兼容性问题

  • 全局版本不匹配:全局安装的 node-gyp 版本可能与项目依赖的原生模块(如 node-sassbcrypt 等)存在兼容性问题。某些模块会强制要求特定版本的 node-gyp,而全局安装的版本可能过旧或过新。
  • 本地版本精准控制:将 node-gyp 写入 devDependencies 后,项目会安装并锁定特定版本,确保与其他依赖的兼容性。

2. 模块加载优先级规则

  • 本地优先原则:Node.js 的模块加载机制会优先使用项目 node_modules 中的依赖,即使全局已安装同名工具。当 devDependencies 中声明了 node-gyp,本地安装后,项目会直接调用此版本,而非全局版本。
  • 路径隔离性:全局安装的 node-gyp 路径可能未被正确识别(如权限问题或环境变量冲突),而本地版本通过 npm scripts 或 npx 调用时路径更明确。

3. 构建环境依赖链

  • 隐式子依赖要求:某些原生模块在安装时,会隐式依赖项目内的 node-gyp 作为编译工具链的一部分。全局版本可能因环境配置(如 Python 版本、M- SBuild 路径)不符合项目要求而失败。
  • 环境隔离性:本地 node-gyp 可以继承项目配置(如通过 .npmrc 或环境变量指定 Python 路径),而全局版本可能依赖系统级配置,导致编译环境不一致。

4. npm 依赖管理机制

  • 依赖树完整性:当 node-gyp 被写入 devDependencies 后,npm install 会确保其作为项目依赖树的一部分完整安装,避免因全局工具链缺失导致构建失败。
  • 清除缓存影响:全局安装可能残留旧版本缓存,而本地安装会强制重新下载并验证依赖完整性。

总结

根本原因:全局 node-gyp 的版本或环境配置与项目需求不兼容,而本地安装通过版本锁定和环境隔离解决了这一问题。

赞 (0)