1. 配置files解决打包后找不到代码文件的问题
在开发electron项目时,可能会遇到这种情况:
使用命令 electron .
启动应用,应用正常运行;
使用electron-builder
打包,运行打包后的应用程序,出现资源404的情况,应用无法正常运行,如下图:
首先介绍一下我的项目结构:
项目根目录
| main:electron主进程相关的代码
| └─── main.js
| └─── preload.js
| build:打包后的页面代码
| └─── index.html
| └─── js文件、css文件、……略
| package.json
| ……略
打包后的应用程序找不到对应文件是因为electron-builder
打包时没有包含必要的“项目代码文件”,没有对应的文件自然就404了。
在electron-builder的配置中添加files配置项,包含必要的项目代码文件即可解决:
{
productName: 'xxx',
appId: 'xxx',
files: ['./main', './build'], // 包含的文件
}
electron-build打包后的Windows应用程序文件结构如下:
应用程序根目录
| locales
| └─── ……略
| resources
| └─── app.asar
| swiftshader
| └─── ……略
| 应用名.exe
| ……省略一堆文件
重点看resource文件夹下的app.asar文件,这个文件就是electron-builder打包后的应用入口文件,打开应用时查看console可以看到:
上图请求路径
app.asar/build/index.html
中的build文件夹就是files中配置的build文件夹;同理,files中配置的main文件夹路径就是app.asar/main
。因此,可以把
app.asar
这个文件看成打包后项目的“根目录”,electron-builder配置项files中包含的文件都在应用程序根目录/resources/app.asar/
目录下。
但是app.asar
是一个文件,为什么可以被electron
当作一个目录来使用呢?本人使用文本编辑器打开app.asar粗略的看了一下,发现所有files配置项指定的代码文件,都被打包进了app.asar这个文件中。个人猜测当浏览器访问app.asar/xxx时,electron会去app.asar中解析出对应的xxx文件返回给浏览器。
2. 除了files之外,electron-builder还有其它文件相关的配置,可以打包指定文件:
{
extraFiles: ['filePath'],
extraResources: ['filePath'],
}
顾名思义,extraFiles
为额外文件,extraResources
为额外资源,它们的作用就是打包额外的文件;
比如有这么一个需求:在用户没有网络时,为用户提供某个静态文件的下载;那就必须将这个静态文件打包进应用程序,用户下载时使用electron主进程的node程序读取这个文件返回给用户。
或者有和我一样的需求,为支持puppeteer
需要将整个chromium浏览器
打包进应用程序中。
配置extraFiles
后,electron-builder会在打包时将extraFiles
中指定的文件复制到打包后应用程序的根目录下(Windows/Linux)
,或者Content目录下(MacOS)
配置extraResources
后,electron-builder会在打包时将extraResources
中指定的文件复制到打包后应用程序的根目录/resources文件夹下(Windows)
,或者Content/resources文件夹下(MacOS)
另外,files
、extraFiles
、extraResources
还都支持from-to
指定路径的配置方式,具体参见官方文档的相关章节。
3. 打包后的额外文件,在electron主进程中如何获取呢?如何保证开发中和打包后的“额外文件路径”一致呢?
如果你使用的是extraFiles
配置项,可以这样做:
- 将“存放额外文件的文件夹”放在项目根目录下;
- 配置
extraFiles
将“存放额外文件的文件夹”打包到应用程序的根目录,确保“存放额外文件的文件夹”不管是在开发时还是打包后都在根目录下; - 使用
process.cwd()
获取Node.js进程当前的工作目录,开发时获取到的是项目根目录,使用electron-builder打包后获取到的是应用程序根目录; - 有了根目录的路径,直接访问
根目录/存放额外文件的文件夹/xxx文件
就可以获取对应的文件:
electron-builder配置:
{
extraFiles: ['./extra-files'],
}
electron主进程:
function getExtraFilesPath(filename: string): string {
return path.join(process.cwd(), `/extra-files/${filename}`);
}
let filePath = getExtraFilesPath('xxx文件名');
这样无论是在开发中还是打包后都可以获取到正确的文件路径。
如果你使用的是extraResources
配置项,也可以使用类似的办法来获取文件。