Electron打包应用中如何正确使用better-sqlite3原生Node模块?
解决Electron Forge打包后better-sqlite3模块找不到的问题
针对你用TypeScript+Electron+Vite+React+Electron Forge构建应用,打包后better-sqlite3模块无法加载的问题,按以下步骤排查解决:
1. 正确配置Vite与Electron Forge的外部依赖及解压规则
- Vite配置:将
better-sqlite3设为全局外部依赖,Vite不会打包该原生模块,交给Electron处理。在vite.config.ts中添加:import { defineConfig } from 'vite'; export default defineConfig({ // ...其他渲染/主进程配置 build: { rollupOptions: { external: ['better-sqlite3'], }, }, }); - Electron Forge配置:确保
@@electron-forge/plugin-auto-unpack-natives插件生效,同时在forge.config.ts中配置asarUnpack,将原生模块文件从asar包中解压出来:export default { packagerConfig: { asar: true, asarUnpack: ['node_modules/better-sqlite3/**/*'], }, plugins: [ ['@electron-forge/plugin-vite', { /* 你的Vite插件配置 */ }], ['@electron-forge/plugin-auto-unpack-natives'], ], };
2. 调整preload脚本与数据库初始化逻辑
- 预加载脚本运行在Node环境,直接用
require导入better-sqlite3更可靠(避免ES模块打包路径问题):// database.ts const Database = require('better-sqlite3'); const { app } = require('electron'); const path = require('path'); // 数据库文件放在应用数据目录,避免asar包读写限制 const dbPath = path.join(app.getPath('userData'), 'app.db'); const db = new Database(dbPath); // 通过contextBridge暴露给渲染进程 const { contextBridge } = require('electron'); contextBridge.exposeInMainWorld('db', { // 暴露你的数据库操作方法 }); - 确保preload脚本被Electron Forge正确识别,在
forge.config.ts的Vite插件配置中指定preload入口:plugins: [ ['@electron-forge/plugin-vite', { preload: { entry: 'src/preload.ts', }, // ...主进程、渲染进程配置 }], ],
3. 重新编译better-sqlite3适配Electron版本
原生模块需要匹配当前Electron的Node版本,执行以下命令重新编译:
npx electron-rebuild -f -w better-sqlite3
也可以在package.json中添加postinstall脚本,每次安装依赖后自动编译:
"scripts": { "postinstall": "electron-rebuild -f -w better-sqlite3" }
4. 验证打包后的文件结构
打包完成后,检查应用目录下的app.asar.unpacked/node_modules/better-sqlite3/build/Release/路径,确认better_sqlite3.node文件存在。如果路径异常,可在preload脚本中打印require.resolve('better-sqlite3')调试实际加载路径。
内容的提问来源于stack exchange,提问作者HellNoki
相关产品推荐
相关产品推荐

