最近项目开发中遇到 buildcheck 包抛错,因修复该报错占用了一点时间,特此这里记录下。
问题
因项目本地部署需要上传打包文件,使用到了 ssh2-sftp-client 包,在拉取包的时候控制台抛如下错误:
warning Error running install script for optional dependency: "D:\\Projects\\xxx\\node_modules\\cpu-features: Command failed.
Exit code: 1
Command: node buildcheck.js > buildcheck.gypi && node-gyp rebuild
Arguments:
Directory: D:\\Projects\\xxx\\node_modules\\cpu-features
Output:
D:\\Projects\\xxx\\node_modules\\buildcheck\\lib\\index.js:133
throw new Error('Unable to detect compiler type');
^
Error: Unable to detect compiler type
at new BuildEnvironment (D:\\Projects\\vite-ui\\packages\\HtUpssh\\node_modules\\buildcheck\\lib\\index.js:133:15)
at Object.<anonymous> (D:\\Projects\\vite-ui\\packages\\HtUpssh\\node_modules\\cpu-features\\buildcheck.js:5:12)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
at internal/main/run_main_module.js:17:47"
该错误不会影响文件上传功能,但是有问题还是要想办法解决掉。
原因
经过排查发现,该报错是因为:
- ssh2-sftp-client 包依赖了 ssh2 包。
- ssh2 包依赖了可选包 cpu-features 包。
- cpu-features 包依赖了 buildcheck 包;并且在包安装的时候执行了 install 命令,运行了 buildcheck.js 脚本来检查node的构建环境;而 buildcheck.js 里引用了 buildcheck 包,执行其源码。
buildcheck.js 代码:
- buildcheck 包里代码在执行时,匹配不到系统可支持的工具类型,就抛错了。
通过 buildcheck 包源码的排查,当是 windows 系统时,会去查找系统安装的工具包,匹配其版本号,获取其类型,根据不同的类型走不同的编译逻辑。(buildcheck 包源码没有细看,粗略看了下,理解错误的话麻烦指正)
我电脑上查找出的 packages 里 Microsoft.VisualStudio.Component.Windows10SDK 没有版本号,所以匹配失败,导致检测不出编译类型,从而抛错。
解决
以上报错是在 buildcheck 包执行时的报错。所以解决思路是:
- Windows10SDK 补充版本号
- buildcheck 包源码仅下载不执行
- 移除对 cpu-features 包的依赖
因为 buildcheck 包源码执行是在 install 的时候,所以通过打补丁的方法也不能解决,补丁是在 install 之后。
方法一
Windows10SDK 补充版本号的话需要通过 vs staller 勾选 window10SDK 组件后重装,重装成本较高,且安装文件较大。该方法被否决。
方法二
buildcheck 包仅下载不执行。可以在 npm 命令行中使用 --ignore-scripts 实现。
yarn add -D buildcheck --ignore-scripts
或者 .yarnrc 文件中配置:
ignore-scripts 'true'
或者 .npmrc 文件中配置:
ignore-scripts = true
添加 ignore-scripts 后,npm scripts 命令将不会执行。那 buildcheck 包源码逻辑也就不会执行了。但是这个命令会导致 npm 其他的命令也不执行,会有一定风险。该方法也不建议。
方法三
移除对 cpu-featurs 包的依赖。因为我的需求场景是仅支持文件上传即可。cpu-features 包不是必须包,可以移除。而 cpu-features 包是在 ssh2 包中被引入的。
可以在 packages-lock.json 去掉对 cpu-features 包的依赖。
或者在 yarn.lock 去掉对 cpu-features 包的依赖。
但是锁包的文件容易被篡改,而且增加维护成本。该方法也不是特别适合。
方法四
重发 ssh2 包,移除对 cpu-features 包的依赖。因为我们包在私仓维护,所以在私仓里发布了同名的 ssh2 包,packages.json 里移除了对 cpu-features 的依赖。当拉取包文件的时候,优先从私仓拉取。
项目中也是采用这个方法来解决。如果大家有更好的办法,欢迎留言。
总结
遇到问题不能逃避,抽丝剥茧,总能解决的,无非是时间问题罢了。