Electron中从extraResources的JS文件导入npm包失败
问题
我在extraResources目录下有一个导入了npm包的batch.js文件,在Electron主进程中通过exec()执行子进程运行该文件,命令为:
exec('node ${process.extraResources}/extra_resources/batch.js')
开发模式下运行正常,但打包应用后无法加载npm包。
项目基于electron-builder的electron-vite初始化,项目结构如下:
src/extra_resources/batch.js src/main/... src/preload/... src/renderer
electron-builder.yml配置:
appId: com.electron.app productName: automation-electron directories: buildResources: build files: - '!**/.vscode/*' - '!src/*' - '!electron.vite.config.{js,ts,mjs,cjs}' - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' asarUnpack: - resources/** win: executableName: automation-electron extraResources: from: './src/extra_resources/' to: extra_resources filter: - '**/*' nsis: artifactName: ${name}-${version}-setup.${ext} shortcutName: ${productName} uninstallDisplayName: ${productName} createDesktopShortcut: always mac: entitlementsInherit: build/entitlements.mac.plist extendInfo: - NSCameraUsageDescription: Application requests access to the device's camera. - NSMicrophoneUsageDescription: Application requests access to the device's microphone. - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. notarize: false dmg: artifactName: ${name}-${version}.${ext} linux: target: - AppImage - snap - deb maintainer: electronjs.org category: Utility appImage: artifactName: ${name}-${version}.${ext} npmRebuild: false publish: provider: generic url: https://example.com/auto-updates
解决方案
原因
打包后batch.js作为额外资源被放到独立目录,但它依赖的npm包要么被打包进主进程的asar包,要么未被复制到该目录,导致子进程运行时找不到依赖文件。
具体解决方法
方法1:复制依赖包到extraResources目录
- 在项目根目录新建
dependencies文件夹,将batch.js需要的npm包安装到该目录,或从项目根目录的node_modules复制对应包过来 - 修改
electron-builder.yml的extraResources配置,把依赖包也纳入打包范围:
extraResources: - from: './src/extra_resources/' to: extra_resources filter: - '**/*' - from: './dependencies/' to: extra_resources/node_modules filter: - '**/*'
- 在
batch.js开头添加模块路径配置,确保能找到依赖:
const path = require('path'); process.env.NODE_PATH = path.join(__dirname, 'node_modules'); require('module').Module._initPaths(); // 后续正常导入npm包 const targetPackage = require('target-package');
方法2:复用Electron内置Node环境与主进程依赖
- 修改
asarUnpack配置,确保extra_resources目录被解压(子进程无法直接读取asar内部文件):
asarUnpack: - extra_resources/**
- 调整主进程的
exec命令,使用Electron可执行文件运行batch.js,共享主进程的依赖:
const { exec } = require('child_process'); const path = require('path'); const electronExecPath = process.execPath; const batchFilePath = path.join(process.resourcesPath, 'extra_resources', 'batch.js'); exec(`"${electronExecPath}" "${batchFilePath}"`);
方法3:将batch.js打包为独立可执行文件
- 安装打包工具
pkg:npm install -g pkg - 进入
src/extra_resources目录,执行打包命令(根据你的Electron Node版本调整target参数):
pkg batch.js --targets node18-win-x64,node18-mac-x64,node18-linux-x64
- 将打包后的可执行文件替换原
batch.js,修改主进程的exec命令:
const { exec } = require('child_process'); const path = require('path'); const batchExecPath = path.join(process.resourcesPath, 'extra_resources', 'batch'); // 对应平台的可执行文件名 exec(`"${batchExecPath}"`);
内容的提问来源于stack exchange,提问作者Intaek
相关产品推荐
相关产品推荐

