electron-builder构建better-sqlite3

1,101 阅读2分钟

背景

arm64架构的mac使用electron-builder打包better-sqlite3时无法适配其他架构和平台。

在electron-builder配置文件中设置了构建x64和arm64的包

最终构建出来的包中,x64的包使用的better-sqlite3是基于arm64 rebuild出来的二进制文件,导致运行失败。

解决方案

electron-builder执行时有有六个步骤

  1. load configuraton 加载配置
  2. rebuilding native dependencies 构建适配当前架构的二进制文件
  3. installing production dependencies(install prebuilt binary) 安装依赖
  4. packaging 打包
  5. signing 签名
  6. 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的版本库,通过版本号搜索

github.com/WiseLibs/be…

版本号对应格式为:

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,并且能够构建不同平台。