背景
arm64架构的mac使用electron-builder打包better-sqlite3时无法适配其他架构和平台。
在electron-builder配置文件中设置了构建x64和arm64的包
最终构建出来的包中,x64的包使用的better-sqlite3是基于arm64 rebuild出来的二进制文件,导致运行失败。
解决方案
electron-builder执行时有有六个步骤
- load configuraton 加载配置
- rebuilding native dependencies 构建适配当前架构的二进制文件
- installing production dependencies(install prebuilt binary) 安装依赖
- packaging 打包
- signing 签名
- building 构建
解决方案是使用electron-builder的钩子函数:www.electron.build/hooks#befor…
在打包前把适配架构平台的better-sqlte3提前写入到构建包中。
打包入口
rebuilding native dependencies是生成二进制文件,名为better_sqlite3.node
better-sqlite3二进制最终会生成在主进程文件下的native_modules目录下。
所以我们要做的是提前把适配架构平台的better-sqlte3提前写入到native_modules/build/Release文件夹中。
适配包
我们要如何找到适配的包呢?
我当前使用的是版本号是:v9.4.3
我们去better-sqlite3的版本库,通过版本号搜索
版本号对应格式为:
better-sqlite3-版本号-electron-模块号-平台-架构-gz
1.检查项目的模块号:
在项目中打印:
console.log(process.versions.modules) // 119
我当前使用的是119。
2.平台
(1)drawin
(2)win32
(3)linux
3.架构
(1)arm64
(2)x64
(3)ai32
其他.....
根据上面的格式,下载windows和mac的文件
better-sqlite3-v9.4.3-electron-v119-darwin-x64.tar.gz
better-sqlite3-v9.4.3-electron-v119-darwin-arm64.tar.gz
better-sqlite3-v9.4.3-electron-v119-win32-ia32.tar.gz
better-sqlite3-v9.4.3-electron-v119-win32-x64.tar.gz
项目位置
下载之后存放到项目根目录的resources文件夹内;
我这里是使用 规则 为 平台-架构 来区分
钩子
我们使用before-pick钩子,它会在打包之前要运行,也就是步骤4。
在electron-builder.json中新增beforePack,运行的文件是./scripts/before-pack.js
在根目录下新增一个scripts/before-pack.js文件
const fs = require('fs')
const path = require('path')
function copyFileSync(destDirName) {
const target = path.join(__dirname, `../resources/prebuiltBinaries/${destDirName}/better_sqlite3.node`);
const dest = path.join(__dirname, '../.webpack/main/native_modules/build/Release/better_sqlite3.node');
fs.copyFileSync(target, dest);
}
exports.default = function (context) {
if (context.packager.platform.nodeName === 'darwin') {
// 具体枚举参考文档:https://www.electron.build/app-builder-lib.enumeration.arch
if (context.arch === 1) { // x64
copyFileSync("darwin-x64")
console.log('【darwin-x64】 better-sqlite3拷贝成功')
} else if (context.arch === 3) { // arm64
copyFileSync("darwin-arm64")
console.log('【darwin-arm64】 better-sqlite3拷贝成功')
}
} else if (context.packager.platform.nodeName === 'win32') {
if (context.arch === 1) { // x64
copyFileSync("win32-x64")
console.log('【win32-x64】 better-sqlite3拷贝成功')
}
} else if (context.packager.platform.nodeName === 'linux') {
copyFileSync("linux-x64")
console.log('【linux-x64】 better-sqlite3拷贝成功')
}
}
当打包之前把响应的better-sqlite3写入到native_modules中。
我们已经手动安装好了二进制文件,就不需要electron-builder二次rebuild了,所以需要设置npmRebuild为false
总结
electron-builder不再执行rebuild,并且能够构建不同平台。