lmk123 / blog

个人技术博客,博文写在 Issues 里。
https://github.com/lmk123/blog/issues
623 stars 35 forks source link

尝试 Electron Forge #128

Open lmk123 opened 5 months ago

lmk123 commented 5 months ago

我错了,electron-builder 更简单好用 :joy:

以下是原文:


先贴环境:

macOS:14.2.1 Apple M1
Electron:v28.0.0

最近开发了一个小 Electron 应用,算是用来练习。由于业务逻辑不复杂,所以开发阶段很顺利,没有遇到什么问题,但是在打包阶段就踩到很多坑了,记录一下。

以前主流的打包工具是 electron-builder,但后来 Electron 官方重写了 electron-forge,所以我还是决定使用官方支持的。

第一个坑:Electron Forge 不支持 monorepo 项目结构(又或者 NPM / Yarn workspaces)

项目一开始使用了 monorepo 的形式,即以下结构:

myApp/
 apps/myElectronApp
   package.json
 packages/pkg1
   package.json
 node_modules
 package.json
 package-lock.json

其中程序的代码是写在 apps/myElectronApp 下的。开发阶段没有遇到问题,但是在使用 electron-forge package 生成了一个 myElectronApp.app 文件后,运行时会报错“找不到模块 lodash”。

在经过一番排查后,发现是因为项目使用了 monorepo,所以应用程序的依赖项(即 dependencies)被安装(或者说被“提升”)到了项目根目录的 node_modules 中,而不是 apps/myElectronApp/node_modules 中,而 electron-forge 使用的 @electron/packager 只会从当前目录的 node_modules(即 apps/myElectronApp/node_modules)中复制依赖项的代码,而这个文件夹是个空的,所以就没有把 lodash 的代码复制进去。

相关 issue:

不确定 electron-builder 是否也有这个问题,没试过。

知道原因之后,这个问题就有了两个解决方案:

为了方便起见,我把项目从 monorepo 改回来成传统的项目了。

第二个坑:packagerConfig.ignore

在使用 electron-forge package 打包之后,可以在 out/myElectronApp-darwin-arm64/myElectronApp.app/Contents/Resources/app 目录下看看有哪些文件被打包进去了,此时会发现有很多不必要的文件(比如 tsconfig.json 和用于存放 ts 文件的 src 目录),可以用 ignore 选项排除掉。

这个选项可以填写字符串或者正则表达式,但是填字符串的时候有个坑,比如我填了 src 之后,就发现它不仅排除掉了我自己的 src 目录,还把 node_modules 里的 src 目录(例如 node_modules/debug/src)也排除掉了,然后就会导致运行时报找不到文件的错误。

目前还不确定要怎么定位到自己项目的目录,文档上也没有写,需要一点点尝试。

另外,package.json 是不能排除的。

第三个坑:在 M1 电脑上同时生成 arm64 和 x64 的 .dmg 包及生成 Windows 系统的包

先说总结:跨平台打包有很多坑,还是老老实实的在单一平台打包。

也就是在 macOS 平台打包 macOS 的包、Windows 平台打包 Windows 的包。

参考链接:

我一开始是在 packagerConfig 里声明了 all: true,但是 electron-forge 报错了,说它不支持这个选项,所以我把 make 命令拆分成了以下三个:

先说 make:darwin

make:darwin 我一开始是这么写的:electron-forge make --arch=arm64,x64 --platform=darwin

首次运行时,electron-forge 会从网络上下载一些二进制包,而为了成功下载,你可能需要确保通过代理去下载——比如开启代理软件的 TUN Mode。

但它报错了:

> electron-forge make --arch=arm64,x64 --platform=darwin

✔ Checking your system
✔ Loading configuration
✔ Resolving make targets
› Making for the following targets:
✔ Running package command
✔ Preparing to package application
✔ Running packaging hooks
✔ Running generateAssets hook
✔ Running prePackage hook
✔ Packaging application
✔ Packaging for arm64 on darwin [1s]
✔ Packaging for x64 on darwin [1s]
✔ Running postPackage hook
✔ Running preMake hook
❯ Making distributables
✖ Making a dmg distributable for darwin/arm64
› Target already exists
✖ Making a dmg distributable for darwin/x64
◼ Running postMake hook

An unhandled rejection has occurred inside Forge:
Error: Target already exists
at /Users/xxx/WebstormProjects/myApp/node_modules/appdmg/lib/appdmg.js:80:53
at node:fs:2290:7
at FSReqCallback.oncomplete (node:fs:200:23)

而且 out/make 文件夹下只有一个 myElectronApp.dmg,但是我预期是有两个 dmg 的。

然后经过多次尝试,改成了:electron-forge make --arch=arm64 --platform=darwin && electron-forge make --arch=x64 --platform=darwin

这次就正常了,out/make 文件夹下有两个 dmg 文件,分别为 myElectronApp-1.0.0-arm64.dmgmyElectronApp-1.0.0-x64.dmg

再说 make:win

make:win 是这么写的:electron-forge make --arch=ia32,x64 --platform=win32

第一次运行时会报错,说需要 brew install --cask wine-stable

安装好了之后再次运行,会报错 无法打开 Wine Stabel,因为无法验证其开发者

这个时候需要进入系统设置 - 隐私与安全性 - 在【已阻止使用 Wine Stable,因为其来自身份不明的开发者。】下面点击【仍要打开】。

然后再次运行,这次会弹出几个 Wine Stable 的权限申请弹窗,都点击【允许】。

然后这次又报错了:Error: You must install both Mono and Wine on non-Windows

然后根据 https://www.mono-project.com/docs/getting-started/install/mac/ 的说明安装 Mono。

运行 Mono 的安装包时又会跳出【无法打开 xxx,因为无法验证其开发者】的弹窗,用同样的方法【仍要打开】即可。

安装完成后再次运行,还是报错了 Error: You must install both Mono and Wine on non-Windows……

我以为是同时声明了两个 arch 的问题,但改成一个之后还是报这个错。

不折腾了,感觉跨平台打包很多坑,还是老老实实在 GitHub Actions 里用 macOS / Windows / Ubuntu 系统分别打包吧。

使用体验

虽然有一些坑,但我觉得 Electron Forge 学习起来非常简单直观,只需几个简单的步骤就能成功打包应用。相比而言,在阅读 Electorn Builder 的文档的时候,看到一堆 Configuration 让我觉得很复杂,有点无从下手的感觉。

但另一方面,又不得不说 electron builder 要完善很多,比如打包的格式丰富多样、无需部署专门的更新服务器(只需一个静态文件服务器)就可以自动更新、双 package.json 结构等。

我决定下次试试 electron builder。

codedaybyday commented 4 months ago

没用过electron-forge,一直以为electron-builder文档太烂了,基本上就是一些注释(面向electorn-builder开发者,而非用户),很多东西需要翻源码看,被你这么一说,electron-forge可能更坑

lmk123 commented 4 months ago

@codedaybyday 是的,我一开始就是被 electron builder 的文档劝退了,但是实际使用之后还是 builder 香