概述

基于Umi搭建Electron App——从0到1中,使用webpack+electron-builder打包之后,最终生成的dist包体积过大,应用下载或更新时会影响用户体验。

electron-builder版本

在此文章提到的electron-builder版本均为^22.10.15。

打包文件分析——简单工程

在对打包文件进行优化之前,首先需要分析一下打包后的文件都有什么,各自占多大空间,找到优化的突破点。为了防止其他因素的干扰,我们先用最简单的electron工程来试一下。

electron-quick-start

感谢由electron官方提供的快速启动模板electron-quick-start,这个模板的结构和内容非常简单,没有集成第三方dependencies。目录结构以及package.json如下图所示:
image.pngimage.png
在这个模板的基础上引入electron-builder作为打包工具,并做简单配置,如下图所示:
image.png

通过两种打包命令对比打包体积

electron-builder —dir、electron-builder

首先使用electron-builder —dir命令构建unpacked dir,使用这个命令构建出的包相较于直接使用electron-builder命令打出的包会少生成几个文件,其中占用空间最大的是.exe安装程序。对比图如下:
image.png
image.png
从图中可以看出来.exe程序大小达到了55.9MB。
再来对比一下dist包整体的大小:
image.png
image.png
从上面两张对比图可以看出来,这两种方式打包后包的体积差距在56MB,主要是差在安装程序Setup.exe文件上了。
ps:electron-builder 命令行接口请参考官方文档:Command Line Interface (CLI)

一个最最最基本的electron工程打包后的体积已然达到了231MB,那么实际的项目恐怕只多不少。

打包文件的目录结构

image.png
image.png
主要看.exe文件和asar文件。

.exe文件

我们运行的 electron.exe 可执行程序,实际上是早就已经编译好的文件。他的功能就是加载 resources/app.asar 文件中的内容,包括入口文件的位置,也是从 app.asar 中打包的 package.json 的 main 字段来获取加载。 打包工具需要做的事情只是把这个 electron.exe 文件修改下图标、作者、版本等信息即可。(你不知道的 Electron (二):了解 Electron 打包

这个最最最简单的electron工程的.exe文件大小为125MB

asar文件

asar是对源代码进行了打包封装。默认情况下,这些源代码是放置在resources/app目录下明文可见的。asar就是对源代码进行最最基础的加密,让别人没有那么容易的就找到你的源代码。
从图中看到,这个简单的eletron工程的asar文件才54KB。实际项目的代码逻辑会比这个空项目多,所以asar的体积也会变大。
使用asar extract app.asar ./app 命令可以解压asar文件,解压之后的目录结构如下图:
image.png
asar中node_modules里只包含dependencies,不包含devDependencies,开发依赖是不会被打包进去的。如下图:
image.png
image.png
再来跟开发目录对比一下:
image.png
主进程、渲染进程的代码文件都是原样复制到asar包里的。需要明确一点的是:asar并不会对代码进行混淆加密,解压之后还是能够看到原始的代码逻辑。

打包文件分析——复杂工程

basic-electron-umi-app

这个工程和electron-quick-start不同的是这个工程集成了umi、ant-design、react等等dependencies。而且打包方式相较于electron-quick-start也有很大的不同,如下图所示:(更多内容详见基于Umi搭建Electron App——从0到1
image.png

web应用打包体积

使用umi内置的打包命令umi dev对web应用进行打包,最终生成的打包文件夹build大小如下图所示:
image.png
从上图中可以看出来web应用打包体积为3.73MB。

electron-builder —dir打包

先使用electron-builder —dir命令构建unpacked dir,最终生成的打包文件夹dist大小如下图所示:
image.png
从上图中看出使用electron-builder —dir打包后的dist文件夹大小为347MB。electron-builder打包时,是直接将web应用打包后的文件夹build复制到dist文件夹中的。去除掉web应用打包文件的3.73MB,dist包的大小为343.27MB,比electron-quick-start使用electron-builder —dir打包后的文件整整多出了100+MB。

electron-builder打包

使用electron-builder打包后的dist大小如下图所示:
image.png
生成的.exe文件大小如下图所示:
image.png
与electron-quick-start工程使用electron-builder打包后对比:Setup.exe文件多出20+MB,dist包多出100+MB。

打包文件的目录结构

image.png
image.png
主要看.exe文件和asar文件。

.exe文件

没有想到。。。basic-electron-umi-app跟electron-quick-start的.exe文件的大小居然一毛一样的。。。都是125MB。

asar文件(找到优化突破口了!!)

basic-electron-umi-app的asar包大小为171MB,比electron-quick-start的asar包大了170+MB,这么多是差在哪块了???
使用asar extract app.asar ./app 命令解压asar文件,解压之后的目录结构如下图:
image.png
asar包中包含:web应用打包文件build、electron主进程文件、node_modules、package.json。
build包和main.js一共占用空间3MB+。node_modules大小166MB!!看来asar包体积大的原因找到了。
node_modules里的目录结构如下图:
image.png
太长了截不全,来看一下package.json吧:
image.png
这些dependencies依赖包其实在使用webpack对web应用进行打包的时候已经打到build包里了,并进行了压缩和混淆。看来electron-builder打包的时候把web应用的dependencies又打包了一遍,而且没做任何的处理。

electron-builder打包输出信息

image.png
从图中可以看出loaded configuration时是读取package.json中的配置。如果能将web应用和electron的package.json分开,就可以避免出现这个问题。electron-builder刚好支持双package.json结构。

优化之路

参考electron-builder官方文档Two package.json Structure(中文版本:双package.json结构),修改basic-umi-electron-app工程的结构及相关配置。

新建app文件夹

在工程根目录新建app文件夹。
image.png

public/main.js——>app/main.js

将之前放在public目录下的main.js文件移动到app文件夹下。

app/package.json

在app文件夹中新建package.json文件。

  • 参考electron-builder官方文档configuration在package.json文件中添加一些描述信息
  • 安装electron、electron-builder作为开发依赖
  • 配置electron app主入口文件、主页、脚本命令
  • 对electron-builder做简单配置。

具体配置如下图所示:
image.png

app/package.json中添加electron-builder配置

image.png
和之前相比添加了一处配置:

  • main.js:之前的main.js是放到了public文件夹下,webpack打包时会将public文件夹下的所有文件复制到build包中,其实这样做也是可以的。但是为了将electron和web应用的结构分的更清楚,所以将main.js挪到app文件夹下,并配置files,electron-builder打包时会将files中配置的文件复制到asar文件中。

    webpack打包配置修改

    image.png

  • outputPath:将electron-builder的配置挪到了app文件夹下的package.json中,所以同样需要将web应用的打包输出路径改成app文件夹下,不然electron-builder打包的时候找不到build文件夹会报错

    app/main.js内容修改

    image.png
    对main.js的修改除了文件位置的移动之外,还有内容的修改。之前的main.js是在webpack打包的时候复制到build文件夹下的,main.js和index.html在同一文件夹下。现在改为使用electron-builder将main.js和build包同时打包到asar文件中,main.js和index.html不在同一文件夹下,所以loadFile的filePath需要修改成${__dirname}/build/index.html

    ./package.json

    项目根目录下的package.json修改。

    electron-builder相关

  • 移除electron-builder开发依赖包

  • 移除electron-builder打包命令、配置信息

image.png

electron启动命令

  • 考虑到开发过程中需要同时启动web应用和electron两个进程,所以electron启动脚本没有移除,但是修改了electron启动文件路径,由public/main.js改为app/main.js,见下图:

image.png

打包流程

  • 使用webpack打包web应用。在./package.json中执行yarn build命令。
  • 使用electron-builder打包桌面应用。在./app/package.json中执行dist-win32命令。

    打包文件的目录结构

    image.png
    image.png
    image.png

    .exe文件

    basic-electron-umi-app.exe文件大小为112MB。比优化之前(125MB)减少了13MB。

    asar文件

    asar文件大小为3.73MB。比优化之前(171MB)减少了167.27MB。
    asar文件解压之后的目录结构如下图:
    image.png

    dist包整体大小变化

    image.png
    对比优化之前的404MB,dist包整体减小了186MB。

仓库地址