本地环境:pnpm v10 、 electron v30 、 electron-build v24
Electron failed to install correctly, please delete node_modules/electron and try installing again
解决方案 1
尝试手动执行安装
node node_modules/electron/install.js
解决方案 2(推荐!)
在 pageage.json 中添加以下配置:
"pnpm": {
"onlyBuiltDependencies": ["electron"]
},
或者在 .npmrc 里添加以下配置:
only-built-dependencies=electron
根本原因
这是 pnpm v10 的新特性,为了提升依赖管理的安全性,只有在 onlyBuiltDependencies 里列出的包才允许在安装期间内执行脚本。
dev无报错,打包无报错,但是运行App报错:cannot find module xxx
解决方案
step 1:确保被主进程引用的依赖都在 dependencies 内,而不是在 devDependencies。
step 2:在 .npmrc 中添加以下配置:
node-linker=hoisted
// or
shamefully-hoist=true
根本原因
electron-builder 的打包机制是罪魁祸首。在构建最终的可执行应用时,electron-builder 会遍历 node_modules 目录,找出 dependencies 所需要的模块,并把它们打包进最终的包(比如 asar 包)中。
而 pnpm 的特点是软链接 + 硬链接 + 非扁平化管理依赖,它的 node_modules 只包含 package.json 中明确声明的依赖(解决幽灵依赖)。且它通过硬链接(.pnpm)的方式来节省磁盘资源。
因此 pnpm + electron-builder 无法正确的把 node_modules 的依赖打进最终包,解决方案就是放弃 pnpm 的特性,生成一个扁平的 node_modules。
同时期待electron-builder 能解决寻找软连接、硬链接的依赖包的问题,这样我们就可以继续维持 pnpm 节省磁盘资源的特性。
本地调试第三方开源的源代码,修改node_modules中的依赖后无效
解决方案:使用 pnpm patch
pnpm 内置了给依赖打补丁的功能,这比传统的 patch-package 更符合 pnpm 的底层设计。
启动 Patch 模式: 在终端运行以下命令(替换 package-name 为报错的库名):
pnpm patch package-name
终端会输出一个临时目录的路径,例如:
You can now edit the following folder: /private/var/folders/xx/xxx/T/xxx
修改代码: 使用 IDE 打开那个临时目录。你会看到这个包的完整内容(即 dist 等文件)。在这里修改 dist/xxx.js 里的代码来修复报错。
应用补丁: 修改保存后,回到原来的终端窗口,运行:
pnpm patch-commit /private/var/folders/xx/xxx/T/xxx # 上一步给出的路径
结果:
pnpm 会在你的项目根目录下生成一个 patches 目录,里面包含你的修改 diff。
它会自动更新 pnpm-lock.yaml 中的 patchedDependencies 字段。
最重要的是:在你提交代码后,在别人重新安装依赖后依然保留该修复。