buildcheck包报错问题排查

2,064 阅读3分钟

最近项目开发中遇到 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 包。

image.png

  • cpu-features 包依赖了 buildcheck 包;并且在包安装的时候执行了 install 命令,运行了 buildcheck.js 脚本来检查node的构建环境;而 buildcheck.js 里引用了 buildcheck 包,执行其源码。

image.png

buildcheck.js 代码:

image.png

  • buildcheck 包里代码在执行时,匹配不到系统可支持的工具类型,就抛错了。

image.png

通过 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 的依赖。当拉取包文件的时候,优先从私仓拉取。

项目中也是采用这个方法来解决。如果大家有更好的办法,欢迎留言。

总结

遇到问题不能逃避,抽丝剥茧,总能解决的,无非是时间问题罢了。