解决 node 在安装Visual Studio 2022后仍然无法使用 node-gyp 编译的问题

6,245 阅读3分钟

已安装 VS 2022 CUMMITY 和 python3.8.0

(图是借的, NODE.JS 可以不选, 包含c++的桌面开发选项就行) image.png

npm ERR! gyp ERR! stack Error: Could not find any Visual Studio installation to use
npm ERR! gyp ERR! stack     at VisualStudioFinder.fail (C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js:124:47)
npm ERR! gyp ERR! stack     at C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js:77:16
npm ERR! gyp ERR! stack     at VisualStudioFinder.findVisualStudio2013 (C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js:361:14)
npm ERR! gyp ERR! stack     at C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js:72:14
npm ERR! gyp ERR! stack     at C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js:382:16
npm ERR! gyp ERR! stack     at C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\util.js:54:7
npm ERR! gyp ERR! stack     at C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\util.js:33:16
npm ERR! gyp ERR! stack     at ChildProcess.exithandler (node:child_process:395:5)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:527:28)
npm ERR! gyp ERR! stack     at maybeClose (node:internal/child_process:1090:16)
npm ERR! gyp ERR! System Windows_NT 10.0.19044
npm ERR! gyp ERR! command "D:\\nodejs\\node.exe" "C:\\Users\\yulike\\AppData\\Roaming\\npm\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd C:\Users\yulike\AppData\Roaming\npm\node_modules\ijavascript\node_modules\zeromq
npm ERR! gyp ERR! node -v v18.2.0
npm ERR! gyp ERR! node-gyp -v v8.3.0
npm ERR! gyp ERR! not ok
npm ERR! npm ERR! code ENOENT
npm ERR! npm ERR! syscall open
npm ERR! npm ERR! path null/package.json
npm ERR! npm ERR! errno -4058
npm ERR! npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\yulike\AppData\Roaming\npm\node_modules\ijavascript\node_modules\zeromq\null\package.json'
npm ERR! npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! npm ERR! enoent
npm ERR!
npm ERR! npm ERR! A complete log of this run can be found in:
npm ERR! npm ERR!     C:\Users\yulike\AppData\Local\npm-cache\_logs\2022-05-27T06_58_53_169Z-debug.log

跟踪了半天源码,发现代码find-visualstudio.js里没有2022.

  // Helper - process version information
  getVersionInfo: function getVersionInfo (info) {
    this.addLog(`getVersionInfo  ${info.version}`)  //"17.2.32519.379"
    const match = /^(\d+)\.(\d+)\..*/.exec(info.version)
    if (!match) {
      this.log.silly('- failed to parse version:', info.version)
      return {}
    }
    this.log.silly('- version match = %j', match)
    this.addLog('- version match = %j', match)
    var ret = {
      version: info.version,
      versionMajor: parseInt(match[1], 10),
      versionMinor: parseInt(match[2], 10)
    }
    if (ret.versionMajor === 15) {
      ret.versionYear = 2017
      return ret
    }
    if (ret.versionMajor === 16) {
      ret.versionYear = 2019
      return ret
    }
    this.log.silly('- unsupported version:', ret.versionMajor)
    return {}
  },

但是源里面有.

最后发现是系统中有两份 Find-VisualStudio.js 其中一份是2022年的最新版,还有一份是2021年的. 路径分别为: C:\Users\yulike\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\lib\find-visualstudio.js 日期为2021年11月09日(这时候还没发VS2022) 和 C:\Users\yulike\AppData\Roaming\npm\node_modules\node-gyp\lib\find-visualstudio.js

系统调用的是路径更长的那份.

估计是不同版本 node.js 处理方式不同,没有删除干净残留记录导致.

于是删除C:\Users\你的用户名\AppData\Roaming\npm\node_modules整个目录后重试.

编译成功.

PS C:\Users\yulike\source\repos> npm install -g ijavascript
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.

added 8 packages in 28s

附带解读一下find-visualstudio.js源码:

node-gyp 通过这个里面定义的 VisualStudioFinder 来查找系统中的VS 安装情况,不同版本调用不同的处理逻辑.

首先是通过 WindowsPowerShell 运行 Find-VisualStudio.cs 来获得一个返回的已安装VS不同版本的列表.

powershell -ExecutionPolicy Unrestricted -Command "Add-Type -Path 'D:\nodejs\node_modules\npm\node_modules\node-gyp\lib\Find-VisualStudio.cs'; [VisualStudioConfiguration.Main]::PrintJson()"

返回:

[
    {
        "path": "D:\\VS2022",
        "version": "17.2.32519.379",
        "packages": [
            "Microsoft.VisualStudio.Product.Community",
            "Microsoft.VisualStudio.PackageGroup.LiveShare.VSCore",
            "Microsoft.VisualStudio.LiveShare.VSCore",
            ...
    }
]

然后遍历这个列表,通过正则表达式处理版本号: /^(\d+)\.(\d+)\..*/.exec(info.version) 我这里就得到了 versionMajor === 17

如果下面没有17对应的处理逻辑估计就是版本过期了.清干净C:\Users\你的用户名\AppData\Roaming\npm\node_modules整个目录后重试.

参考文档: nodejs/node-gyp: Node.js native addon build tool (github.com)