electron-forge打包asar文件过大问题的解决方案
electron-forge打包asar文件过大问题的解决方案
在使用electron-forge打包Electron应用时,asar文件过大的问题可能会严重影响应用的性能和用户体验。本文将详细介绍导致asar文件过大的原因,并提供具体的解决方案,帮助开发者优化打包过程,减小asar文件的大小。
环境配置
本文基于以下Electron环境:
{
"@electron-forge/cli": "^7.1.0",
"@electron-forge/maker-deb": "^7.1.0",
"@electron-forge/maker-rpm": "^7.1.0",
"@electron-forge/maker-squirrel": "^7.1.0",
"@electron-forge/maker-zip": "^7.1.0",
"@electron-forge/plugin-auto-unpack-natives": "^7.1.0",
"@electron-forge/plugin-vite": "^7.1.0",
"@electron/packager": "^18.3.3",
"@electron/rebuild": "^3.3.0",
"@vitejs/plugin-vue": "3.1.0",
"electron": "^27.1.0"
}
解决方案
1. 分析asar文件内容
如果你发现打包后的asar文件包含了项目的整个源代码,可以使用以下命令提取出asar文件包含的内容,从而分析asar是否包含了不需要包含的文件:
asar extract app.asar <输入目录>
如果包含了项目不需要打包进asar的文件,我们需要设置forge.config.js
文件的内容,需要配置ignore
属性的内容信息。关于ignore
属性的使用说明可以参考:https://electron.github.io/packager/main/interfaces/Options.html#ignore
示例配置:
module.exports = {
packagerConfig: {
asar: true,
ignore: [
'/.idea',
/^\/logs$/,
/^\/deps$/,
/^\/extensions$/,
/^\/src$/,
/^\/.device-config$/,
/^\/.gitignore$/,
/^\/package-lock.json$/,
/^[/\\]vite\.\w+\.config\.js$/
],
...其他配置
},
...其他配置
}
上边的ignore
解析方式是如果当前目录被忽略了,当前目录的子内容也会被忽略。起始路径是以forge.config.js
文件所在的目录开始,要忽略的文件和目录以相对的目录进行定义。
2. 设置不需要打包进asar的文件和目录
这里我们可以使用packagerConfig.extraResource
属性,这个属性会将配置的目录或文件路径不打包进asar文件中,但是将其放在/resources
目录下。/resources
目录是在你打包构建成exe后可见,但是在未构建的情况下,也能获取到/resources
目录的位置,这个位置就会是node_modules/electron
目录下的/resources
目录。我们可以通过process.resourcesPath
属性来获取。
建议使用process.cwd()
来自行构建生产和开发时的环境配置,以防指定的资源路径不一样导致的访问不到的问题。以下是pathutils
的代码示例:
export function getAppPath() {
if (process.env.NODE_ENV === "development") {
const targetPath = path.join(process.cwd(), 'out', 'app');
if (!fs.existsSync(targetPath)) {
fs.mkdirSync(targetPath, { recursive: true })
}
return path.join(process.cwd(), 'out', 'temp-root')
} else if (process.env.NODE_ENV === "production") {
return process.cwd();
} else {
console.error("未知的Node环境", process.env.NODE_ENV)
return null;
}
}
export function getAppResourcePath(devPaths, prodPaths) {
return path.join(getAppPath(),
process.env.NODE_ENV === "development" ? devPaths : "",
process.env.NODE_ENV === "production" ? prodPaths : "",
)
}
3. 处理process.env.NODE_ENV为undefined的问题
在构建打包成exe文件后,通过exe运行时获取到的process.env.NODE_ENV
环境变量的值是undefined。这里我们需要借助app.isPackaged
属性进行自己赋值环境变量的值。可以在main.js
的执行内容的最上方添加以下代码:
if (app.isPackaged) {
process.env.NODE_ENV = 'production'
}
app.isPackaged
属性是一个只读属性,返回一个boolean值,如果应用已经打包,返回true,否则返回false。这对于大多数应用程序来说,可以用于区分开发和生产环境。
4. electron-packager的ignore和asar配置说明
ignore
可以理解为是否要包含进asar文件的属性,如果这个属性指定的内容匹配上了,那么将不会出现在asar的文件中。asar.unpack
和asar.unpackDir
是对于将要打包进asar中的文件内容,进行不同的行为操作,一个是针对文件的,一个是针对目录的。asar.unpack
:所有与提供的 glob 表达式相匹配的文件都会被解压到app.asar.unpacked
目录下,并且这些文件不会被打包进 ASAR 文件中。asar.unpackdir
:与该属性值匹配的所有目录及其内容都将被解压到app.asar.unpacked
目录下。这意味着这些目录不会被包含在 ASAR 文件内。- 动态生成的文件或者需要频繁写入的日志文件通常会使用
unpack
或unpackDir
来确保它们不被包含在 ASAR 存档中。
其他参考资料
- Electron 应用程序打包体积过大常用的优化方法
- electron ASAR Archives
- github package volume size to large
- The packaged file volume is too large and contains nodes_modules electron-forge package (--template=vite)
- Undocumented breaking change for Vite plugin in v7.3.0
- vite plugin v7.3.0版本以上的版本,进行了一次大的变更,配置xxx.main.config.js等文件的方式进行了改变。
- electron-forge对于vite-plugins的使用说明在当前时间并未进行更新。
- feat: adds default fuses to templates
- 关于模板的初始默认配置的commit说明
- vite template can not generate asar
- packagerConfig in ForgeConfig ignores afterComplete hook functions
- 关于在packagerConfig中的配置afterComplete后,遇到构建进程挂起的问题。是因为执行完成后,别忘调用callback回调方法。我当时以为是错误的回调方法,原来是执行完成的执行方法,不执行callback就会一直挂起构建的进程。
- 最后一个是关于我当时提交的issue,有关asar打包文件大的问题