electron打包后托盘图标丢失优雅解决方案

502 阅读2分钟

*electron forge似乎已经没有这个问题了,使用绝对路径:path.join(__dirname,'path/img.jpg')

--by 2024.09.03*


在electron打包(package)后,托盘图标丢失导致托盘不显示,打包工具是官网推荐的electron forge。

(electron forge的打包工具是electron package,经过查询electron builder也有这问题)。


解决方案1:使用环境变量进行if(){}else{}判断。
electron forge模板在引用html时就是用该方法,开发一个路径,打包后一个路径。

但是,即使指定了打包后路径,图片资源并不会被打包工具打包,因为你的路径本质只是字符串。
所以需要复制icon资源到打包后路径,每次打包动作都会清空输出路径下的原文件,icon也会被清掉,每次手动复制十分繁琐。让js自动处理吧!(利用electron package的extraResource配置或hook钩子)。

electron forge文档的构建生命周期中提到,打包是electron package做的,配置路径在forge.config.js配置文件的packagerConfig: { /* 填这里 */ }下,再根据electron package文档,配置项是extraResource?: string | string[](electron builder不同的是extraResources?: string | object[],可以配置from和to)。导出路径是{app}/resources,用process.resourcesPath可以直接获取路径。

// forge.config.js
module.exports = {
  packagerConfig: {
    asar: true,
    extraResource: 'path',
  }
}
// main.js
const iconPath = is.dev && process.env['ELECTRON_RENDERER_URL']
? '/path/icon.ico'
: path.join(process.resourcesPath, '/path/icon.ico')

解决方案2:不管跳过
打包后终究还是要做成安装向导文件的,可以在这步解决该问题。

在打包后直接使用inno setup之类的工具生成安装向导,在选择程序文件夹时,除了选择打包输出后的路径,也选择上vite项目的public路径(图标之类的放到public),因为inno选择public,安装后只会有public下的资源,并不会有public文件夹,所以在编写路径时输出路径[Files]public的DestDir要加上{APP}/public,不然还是要if开发和生产环境,然后把iss脚本文件保存到out文件夹下。打包后没托盘图标想测试,可以用nativeImage.createFromPath('path/icon.ico')做new Tray(icon)的icon。除了没图标,点击的功能都可以正常进行。


解决方案3(优雅解决方案):交给构建工具:使用Electron⚡️Vite 、electron-vite、electron-forge

Electron⚡️Vite是vite的electron模板

npm create electron-vite@latest

electron-vite是npm包,作用类似electron-fore,针对electron主进程静态资源处理优化,也可以像vue3+vite模板一样使用import静态资源,来import托盘图标(vite静态资源处理只对渲染进程有用,主进程是不行的。)。

npm create @quick-start/electron@latest //electron-vite脚手架工具Project name: … <electron-app>
✔ Select a framework: › vue
✔ Add TypeScript? … No / YesAdd Electron updater plugin? … No / YesEnable Electron download mirror proxy? … No / Yes

Scaffolding project in ./<electron-app>...
Done.

electron-forge有vite插件,可以用electron-forge/cli创建模板

electron-forge init my-app  -- --template=vite

--template:
-   `webpack`
-   `webpack-typescript`
-   `vite`
-   `vite-typescript`