这篇文章不会讲打包的细节,网上类似的文章应该很多,本文主要是从如何打一个双架构的包,满足提交 Mac App Store 的要求。
为什么需要双架构包
从2020年11月开始,苹果推出了基于自家M1芯片的Mac产品,这款芯片是基于ARM架构设计的,而非过去的Intel x86架构。因此,如果你希望你的应用在所有Mac设备上运行得更好,包括新的使用了M1芯片的设备,你就需要构建一个支持这两种架构(即双架构)的应用。
另外,2021年12月起,苹果官方规定,所有提交到Mac App Store的新应用,以及应用的更新版本,必须是支持M1芯片(即ARM64架构)的,否则将不予接受。因此,对于基于Electron的应用,如果要提交到App Store,那就需要打包成双架构,即同时支持Intel x86_64和ARM64两种架构。
需要注意的是,打包成双架构的应用体积会比只支持一种架构的应用体积大。但是,这也意味着你的应用能在所有Mac设备上运行,而无论它们是基于Intel还是基于ARM架构。因此,从兼容性和应用市场接受度的角度来看,打包成双架构应用是有意义的。
我的开发的应用 GitHeat 打包完 pkg 就有 163M
, 这对一个小应用来说,是相当大的。
Electron 应用如何打双架构包
其实很简单,只需要在 build 的配置文件中,添加相应的配置就可以
mac: {
target: [{
target: 'mas',
arch: ['universal']// ['x64', 'arm64']
},
{
target: 'dmg',
arch: ['x64', 'arm64'], // ['x64', 'arm64']
}],
......其它配置
},
target 为 mas
的时候,是给 Mac App Store
打的包, 这个时候我们才需要双架构包,arch 赋值为['universal']即可。对于 Mac App store , 有个好处是,下载的时候会自动区分架构,然后只下载对应的部分。
但是对于不走 App Store 的分发,建议还是别打双架构包了,大小会乘 2,用户下载的包也大。
如果你的应用没有依赖任何原生模块,只依赖 JS 模块,那么恭喜你,打包将会很简单,上面的配置就够了。
但是如果依赖了原生模块,那么你的原生模块需要在不同平台上进行编译。
有原生模块的情况下,如何编译双架构
之前博客中有提到了用better-sqlite3
,这个模块包含了原生模块。而且安装到 Electron 中,大概率因为 Nodejs 的编译版本不一样,导致需要重新编译。
Electron 安装 better-sqlite3 报错解决 - CamelGeek
上面文章中讲了如何重新编译,但是如果在本地开发,这是可以的,你的电脑肯定只是属于一种架构的,但是如果要打包双架构的话,你这个重新编译的模块,将会不满足要求。
这时候你可以通过以下方式解决问题:
- 找到第三方模块和 Electron 中 NodeJs 版本匹配的版本
我一开始也想固定版本,找到一个匹配的,结果不管怎么尝试,永远都差一点点。 - 通过改造打包脚本,不同架构引入不同的原生依赖
这个工作量感觉太大,而且不熟悉的话根本搞不定,不划算 - 将原生模块分别在
Intel
电脑和M 系列
电脑上分别打包,然后把原生模块合并起来。
对于第一次打包双架构,我花费时间最多的是如何通过 第 1,2 种方式,但是最终我用第 3 种方式解决了问题。
还是以better-sqlite3
为例, 你可以用Electron 安装 better-sqlite3 报错解决 - CamelGeek 中介绍的方式,分别打出x64
和arm64
的包,然后将/node_modules/better-sqlite3/build/Release/better_sqlite3.node
分别拷贝到同一个目录,需要重命名一下,比如better_sqlite3_x64.node
和better_sqlite3_arm64.node
两个文件,然后用下面的命令完成包的合并:
lipo better_sqlite3_x64.node better_sqlite3_arm64.node -create -output better_sqlite3.node
<span style='color:#2d98da'>合并之后,你可以看到better_sqlite3.node 的包大小是之前两个的 2 倍左右。</span>
最后将合并后的better_sqlite3.node
复制到/node_modules/better-sqlite3/build/Release/
目录下
用 electron-builder 打包即可。
最后,祝你顺利打包。
如果你的应用不上架 App Store,建议不同架构分别打包
发表回复