Electron 44 + better-sqlite3:解决 electron-rebuild 无法识别 Visual Studio 2026 的问题
在 Windows 11 环境下使用 Electron 44、Node.js 24 和 `better-sqlite3` 开发 Electron 应用时,执行 `electron-rebuild` 遇到 `Could not find any Visual Studio installation to use`。本文记录完整排查过程,并总结 Visual Studio、node-gyp、electron-rebuild 以及 npm 依赖层级之间的关系。
一、问题背景
项目是一个基于 Electron 的 EPUB 阅读器:
D:\Desktop\EpubReader
项目使用了原生 Node.js 模块:
better-sqlite3
由于 Electron 与普通 Node.js 的 ABI 不完全一致,原生模块通常需要针对当前 Electron 版本重新编译,因此执行:
npx electron-rebuild
最初得到:
✖ Rebuild Failed
An unhandled error occurred inside electron-rebuild
node-gyp failed to rebuild 'D:\Desktop\EpubReader\node_modules\better-sqlite3'.
Error: Could not find any Visual Studio installation to use
表面上看,问题似乎是 Visual Studio 没有安装或没有被找到。
但继续排查后发现,真正的问题涉及 Visual Studio 工具链、vswhere、node-gyp 版本以及 electron-rebuild 版本几个层面。
二、确认 Node、Electron 和 better-sqlite3 版本
首先检查项目环境:
node -v
npm -v
npx node-gyp --version
npm list electron
npm list better-sqlite3
得到:
Node.js v24.18.0
npm 12.0.2
node-gyp v13.0.2
Electron 44.0.0
better-sqlite3 13.0.3
这些版本本身没有明显异常,因此没有必要一开始就通过降级 Node.js、Electron 或 better-sqlite3 来解决问题。
接下来检查 Windows C++ 编译环境。
三、确认 Visual Studio 和 C++ 编译工具链
Visual Studio 2026 实际安装在:
D:\Microsoft Visual Studio\18\Community
检查 MSVC 编译器:
where cl
检查 MSBuild:
where msbuild
在正确初始化 Visual Studio 开发环境后,可以看到:
D:\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.51.36231\bin\Hostx64\x64\cl.exe
以及:
D:\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\amd64\MSBuild.exe
进一步确认编译器文件:
dir "D:\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.51.36231\bin\Hostx64\x64\cl.exe"
结果证明:
Visual Studio、MSVC 和 MSBuild 实际上都已经安装。
因此问题并不是简单的“没有安装 Visual Studio”。
四、检查 Visual Studio 是否能够被 vswhere 发现
node-gyp 在 Windows 上需要发现 Visual Studio 安装实例,因此继续检查 vswhere。
执行:
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath
最初没有任何输出。
执行:
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -products * -all
同样无法发现 Visual Studio。
甚至:
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -path "D:\Microsoft Visual Studio\18\Community"
得到:
Error: Unknown error
这说明:
Visual Studio 文件存在
↓
MSVC 存在
↓
MSBuild 存在
↓
但 Visual Studio Installer 的实例发现机制异常
经过修复 Visual Studio 安装实例后,再次检查:
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationVersion
得到:
18.9.12120.119
以及:
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property displayName
得到:
Visual Studio Community 2026
至此,Visual Studio 实例发现问题解决。
五、问题进一步暴露:node-gyp 找到了 VS,却无法识别版本
重新打开 Developer Command Prompt for VS 2026,执行:
npx electron-rebuild
此时日志发生了变化:
gyp verb find VS running in VS Command Prompt, installation path is:
gyp verb find VS "D:\Microsoft Visual Studio\18\Community"
gyp verb find VS - will only use this version
gyp verb find VS unknown version "undefined" found at "D:\Microsoft Visual Studio\18\Community"
gyp verb find VS could not find a version of Visual Studio 2017 or newer to use
这段日志非常关键。
它说明:
node-gyp已经能够通过VSINSTALLDIR找到 Visual Studio,但无法正确识别 Visual Studio 2026 的版本。
继续检查环境变量:
echo %VisualStudioVersion%
得到:
18.0
echo %VSCMD_VER%
得到:
18.9.2
echo %VSINSTALLDIR%
得到:
D:\Microsoft Visual Studio\18\Community\
同时 vswhere 可以正确返回:
installationVersion:
18.9.12120.119
displayName:
Visual Studio Community 2026
因此可以确认:
Visual Studio 2026 本身以及开发环境变量都正常,问题开始指向正在使用的
node-gyp/electron-rebuild版本。
六、关键发现:项目中存在多个 node-gyp
执行:
npm list node-gyp
得到:
epubreader@1.0.0
│
├── electron-builder@26.15.3
│ └── app-builder-lib@26.15.3
│ └── @electron/rebuild@4.2.0
│ └── node-gyp@12.4.0
│
├── electron-rebuild@3.2.9
│ └── node-gyp@9.4.1
│
└── node-gyp@13.0.2
这解释了之前一个非常容易产生的误解。
虽然执行:
npx node-gyp --version
得到:
v13.0.2
但 electron-rebuild 并不一定使用这个版本。
项目实际上存在三条依赖关系:
项目
├── node-gyp@13.0.2
│
├── electron-rebuild@3.2.9
│ └── node-gyp@9.4.1
│
└── electron-builder@26.15.3
└── @electron/rebuild@4.2.0
└── node-gyp@12.4.0
因此实际执行:
npx electron-rebuild
走的是:
electron-rebuild@3.2.9
↓
node-gyp@9.4.1
↓
Visual Studio 2026
↓
unknown version "undefined"
而不是:
node-gyp@13.0.2
七、为什么 npm 中可以同时存在多个 node-gyp?
这是 npm 依赖树的正常机制。
不同 package 可以依赖不同版本的同一个 package,例如:
electron-rebuild@3.2.9
└── node-gyp@9.4.1
而另一个 package:
@electron/rebuild@4.2.0
└── node-gyp@12.4.0
npm 可以同时安装这两个版本,以满足不同依赖的版本要求。
因此:
npm list node-gyp
出现多个版本并不代表 npm 安装错误。
排查问题时真正重要的是:
哪个工具正在使用哪个版本。
八、真正的问题:项目使用了过旧的 electron-rebuild
继续检查:
npm list electron-rebuild
发现:
epubreader@1.0.0
└── electron-rebuild@3.2.9
而项目的 electron-builder@26.15.3 已经带来了:
@electron/rebuild@4.2.0
也就是说,项目同时存在:
electron-rebuild@3.2.9
和:
@electron/rebuild@4.2.0
这里应该使用新版的 @electron/rebuild。
九、删除旧版 electron-rebuild
首先删除旧版:
npm uninstall electron-rebuild
此时:
electron-rebuild@3.2.9
被移除。
项目中原本作为 electron-builder 间接依赖存在的:
@electron/rebuild@4.2.0
仍然存在。
但是此时直接执行:
npx @electron/rebuild
却无法正常工作。
这涉及 npm 中非常重要的直接依赖和间接依赖概念。
十、直接依赖、间接依赖和 --save-dev
在原来的依赖树中:
EpubReader
└── electron-builder
└── @electron/rebuild
@electron/rebuild 确实存在于 node_modules 中,但它是:
间接依赖(transitive dependency)
也就是说,项目本身没有声明需要 @electron/rebuild,只是因为 electron-builder 需要它,所以 npm 才安装了它。
而项目自己直接声明的 package 才叫:
直接依赖(direct dependency)
例如:
EpubReader
├── electron-builder
│
└── @electron/rebuild
此时 @electron/rebuild 就是项目的直接依赖。
如果项目的构建流程直接使用某个 package,就应该把它声明为自己的直接依赖,而不是依赖其他 package 恰好把它带进来。
--save-dev 和 -D
执行:
npm install --save-dev @electron/rebuild@4.2.0
也可以写成:
npm install -D @electron/rebuild@4.2.0
两者完全等价。
--save-dev 是完整写法,-D 是简写。
它们的作用是:
安装 package,并将其记录到
package.json的devDependencies中。
最终类似:
{
"devDependencies": {
"electron": "^44.0.0",
"electron-builder": "^26.15.3",
"@electron/rebuild": "4.2.0"
}
}
为什么 @electron/rebuild 应该放在 devDependencies?
因为它是构建工具。
它的作用是:
开发/构建阶段
↓
重新编译 native module
↓
better-sqlite3
↓
匹配 Electron ABI
最终用户运行已经打包好的 Electron 应用时,并不需要运行 @electron/rebuild。
因此:
构建工具
→ devDependencies
而如果应用运行时需要 SQLite:
better-sqlite3
→ dependencies
两者的用途不同。
十一、把 @electron/rebuild 声明为直接开发依赖
执行:
npm install -D @electron/rebuild@4.2.0
此时项目明确声明:
EpubReader
└── @electron/rebuild@4.2.0
同时 electron-builder 自己可能仍然依赖它:
EpubReader
├── @electron/rebuild@4.2.0
│
└── electron-builder@26.15.3
└── @electron/rebuild@4.2.0
从项目管理角度来看,这种关系更加可靠,因为:
项目直接使用
@electron/rebuild,因此项目自己明确声明了这个依赖。
这里可以把它通俗地理解为“提高了可见性”,但更准确的技术说法是:
把一个间接依赖声明为当前项目的直接开发依赖。
并不是简单修改了某种“可见等级”。
十二、为什么不应该依赖间接依赖?
假设未来:
electron-builder
某个版本不再依赖:
@electron/rebuild
那么:
EpubReader
└── electron-builder
升级后,@electron/rebuild 可能就不会再被安装。
如果项目自己的构建脚本仍然执行:
npx electron-rebuild
就可能突然失败。
而如果 package.json 明确声明:
{
"devDependencies": {
"@electron/rebuild": "4.2.0"
}
}
那么 electron-builder 是否依赖它就与项目自身无关。
因此一个重要的 npm 项目管理原则是:
如果项目代码或构建流程直接使用某个 package,就应该把它声明为自己的直接 dependency 或 devDependency。
不要依赖其他 package 恰好把它安装进来。
十三、最终重新执行 rebuild
安装新版:
npm install -D @electron/rebuild@4.2.0
然后:
npx electron-rebuild -v 44.0.0
最终成功完成 better-sqlite3 的 Electron 原生模块重编译。
最终工具链关系可以理解为:
Node.js 24.18.0
│
Electron 44.0.0
│
better-sqlite3 13.0.3
│
@electron/rebuild 4.2.0
│
node-gyp 12.4.0
│
Visual Studio 2026
│
MSVC 14.51.36231
十四、完整排查思路
这次问题最开始的错误是:
Could not find any Visual Studio installation to use
但最终解决方案并不是简单地“重新安装 Visual Studio”。
完整排查过程实际上是:
① 检查 Node / npm / Electron / better-sqlite3
↓
版本基本正常
② 检查 MSVC / MSBuild
↓
工具链实际存在
③ 检查 vswhere
↓
发现 VS Installer 实例发现异常
④ 修复 Visual Studio 实例发现
↓
vswhere 可以找到 VS 2026
⑤ 在 Developer Command Prompt 中重新运行
↓
node-gyp 已经找到 VS 路径
但版本为 undefined
⑥ npm list node-gyp
↓
发现项目中存在多个 node-gyp
⑦ npm list electron-rebuild
↓
发现实际使用的是 electron-rebuild@3.2.9
↓
其依赖 node-gyp@9.4.1
⑧ 删除旧版 electron-rebuild
↓
改用 @electron/rebuild@4.2.0
⑨ 将 @electron/rebuild 声明为直接 devDependency
↓
重新执行 electron-rebuild
↓
成功
十五、以后遇到类似问题的排查原则
遇到 Electron 原生模块编译问题时,不要看到:
node-gyp failed
就立即降级 Node.js 或 Electron。
建议按照以下顺序排查。
1. 检查环境版本
node -v
npm -v
npm list electron
2. 检查 native module
npm list better-sqlite3
3. 检查 C++ 工具链
where cl
where msbuild
4. 检查 Visual Studio 实例
vswhere -latest -products * -property installationPath
5. 检查 electron-rebuild
npm list electron-rebuild @electron/rebuild
6. 检查实际 node-gyp 依赖树
npm list node-gyp
特别注意:
npx node-gyp --version
显示的版本不一定是 electron-rebuild 实际使用的版本。
7. 确认构建工具是否为直接依赖
如果项目构建流程直接使用:
@electron/rebuild
应该在:
"devDependencies"
中明确声明,而不是依赖:
electron-builder
└── @electron/rebuild
这样的间接依赖关系。
十六、结论
这次问题实际上由几个环节共同造成:
- Visual Studio 2026 最初无法被
vswhere正确发现; - 修复后,
node-gyp已经能够找到 Visual Studio,但旧版本无法正确识别 VS 2026; - 项目中存在多个
node-gyp,容易误以为electron-rebuild使用的是项目中的node-gyp@13.0.2; - 实际使用的
electron-rebuild@3.2.9搭配的是较老的node-gyp@9.4.1; - 项目中虽然已经通过
electron-builder间接安装了@electron/rebuild@4.2.0,但项目自身没有直接声明这个依赖; - 删除旧版
electron-rebuild,并将@electron/rebuild@4.2.0明确安装为devDependency后,问题最终解决。
最终使用:
npm uninstall electron-rebuild
npm install -D @electron/rebuild@4.2.0
npx electron-rebuild -v 44.0.0
成功完成 better-sqlite3 的重编译。
附:本次问题中的关键命令
查看环境
node -v
npm -v
npx node-gyp --version
npm list electron
npm list better-sqlite3
查看依赖树
npm list electron-rebuild
npm list @electron/rebuild
npm list node-gyp
查看 Visual Studio
where cl
where msbuild
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationVersion
安装新版 Electron rebuild
npm install -D @electron/rebuild@4.2.0
重建原生模块
npx electron-rebuild -v 44.0.0
核心经验
遇到 Electron 原生模块编译问题时,最重要的不是盲目升级或降级,而是先搞清楚“谁在调用谁”。
npx node-gyp显示的版本、项目直接依赖的版本,以及electron-rebuild内部实际使用的版本可能完全不同。使用
npm list <package>查看完整依赖树,往往比单独查看某个 package 的版本更有价值。