electron 问题收集

杀毒软件的误报

(Windows平台上)杀毒软件的报毒也是很多独立开发者不愿意发行Windows版本应用的原因。

这是一个非常恶心的事情,如果你应用的目标用户是小白,那么很可能会因为杀软的误报而不考虑安装你的应用,这里有一个叫做 virustotal 的网站能够帮你检测你打包后的应用会被哪些杀毒软件处理。

当然,报毒并不仅仅是你使用了 protocol 这么简单,早期的 Electron 组件中包含了大量的容易被误报的内容,但现在这一问题少了很多,对此我们作为 Electron 的用户基本上没有别的办法,只能等待 Electron 的影响力继续扩大,使杀毒软件将其彻底列入白名单。

相关 issue: https://github.com/atom/atom/issues/3927

压缩应用体积的方法

Electron 应用体积动辄一百多兆的体积从他发布的第一天起到现在一直被人诟病,而其体积之所以如此之大的原因在于 Electron 为其跨平台的支持,在内部打包了整个 V8 引擎,相当于一个功能完整的浏览器。

曾经 Slack 作为仰仗 Electron 『大厂』, macOS 版本曾神奇的只有 20M 左右。但事实上那个时候的 Slack macOS 版本并不依赖 Electron,而是 MacGap(所以你可以看到现在的 Slack 全面转向 Electron 后也毫无疑问的成为了百兆应用的大户)。如果你打算使用 MapGap 来优化 Mac 版本的体积,请打住。简单阅读一下 MacGap 的文档就会发现,MacGap 的发展速度甚至赶不上 Electron,很多需求在 MacGap 上甚至无法实现,例如 preload 这样的功能就不具备。

所以无论你的 Electron 应用多么简单,都至少拥有超过 120M 的体积。这是相当不友好的。对于这个问题,笔者实践中找到了三种相对妥协,却能很好的解决问题的方案:

1. 使用 yarn clean

我们知道 node 程序其实是将依赖库整个下载到了 node_modules 中,这也就包括一些 example 和 docs 和 test,而在 electron 应用被打包的过程中,这些依赖其实也是被耿直的打包进了应用之中。这也就无形之中增加了 Electron 应用的体积。

而使用 yarn clean 可以清除这些内容,从而一定程度上减少应用的体积。

2. 将应用程序打包后再分发

Electron 应用本身的 bundle 确实高达 120M,但其压缩后的体积能够变得很小,尤其是 Windows 平台上的安装程序甚至能够被压缩到 33M 左右,而 macOS 和 Linux 的打包体积也将被压缩为 40M 左右。这其实是一个相当可观的体积了,如果配合下面提到的第三点方法,那么几乎向用户隐瞒了应用本身体积巨大的事实。正如笔者在前面提到的,推荐使用 electron-builder。

3. 定制应用的更新功能

关于这一点内容,我们要从 Electron 打包应用的结构谈起。以 macOS 为例,Electron 应用最终被打包成了如下的结构:

ElectronApp.app
└── Contents
    ├── Frameworks
    │   ├── Changkun\ Blog\ Helper\ EH.app
    │   ├── Changkun\ Blog\ Helper\ NP.app
    │   ├── Changkun\ Blog\ Helper.app
    │   ├── Electron\ Framework.framework
    │   ├── Mantle.framework
    │   ├── ReactiveCocoa.framework
    │   └── Squirrel.framework
    ├── Info.plist
    ├── MacOS
    │   └── Changkun\ Blog
    ├── PkgInfo
    ├── Resources
    │   ├── Changkun\ Blog.icns
    │   ├── app-update.yml
    │   ├── app.asar
    │   ├── electron.asar
    │   ├── en.lproj
    │   ├── zh_CN.lproj
    │   └── zh_TW.lproj
    └── _CodeSignature
        └── CodeResources

在这个结构中,我们自己的核心代码,其实是被完整的打包进了 Contents/Frameworks/Resources/app.asar 中,其他内容则都是 electron 自身的依赖。换句话说,我们只要更新了 app.asar 这个文件,也就相当于更新了整个应用。我们再来看看这个文件的大小:

-rw-r--r--   1 changkun  admin   2.9M Mar 16 17:07 app.asar

这将是一个非常可观的下载量,配合第二点,用户第一次下载了一个不超过 50M 的应用安装程序,每次更新应用时,下载的内容也非常之少。当然,实现这一功能也并不复杂,我们只需要和自己的服务器进行通信,然后下载这个文件退出应用进行替换即可。

相关 issue: https://github.com/electron/electron/issues/2003

案例:一个 bug 的生与死

electron-builder 出现过一个 bug : 在 productName 字段中,如果其包含了一些 UTF-8 字符,那么最终打包后的 dmg 包的应用 icon 的位置将出现错误。之所以以此为例,是因为恰好这个问题笔者前几日找时间跟踪修复的。

这个问题出现的根源可以追溯到 electron-builder 早期对 node-appdmg 的依赖。在 macOS 10.12 更新之前,用于打包 macOS 平台的 dmg 依赖 node-appdmg 不存在任何问题,而且其本身的实现逻辑也是根据苹果自身的文档描述正确无误完成的。但是莫名其妙的是在 macOS Sierra 上就是无法显示背景图。后来才发现是苹果系统自身的 bug,这个问题也在 10.12.3 之后的系统版本上被修复了。那么从 10.12.0 到 10.12.3 这么长的周期间隙中,electron-builder 的维护者也不能闲着,为了摆脱对 node-appdmg 的依赖,electron-builder 的作者使用 perl 黑魔法解决了这个问题,从那以后 electron-builder 不再依赖 node-appdmg

然而这也就埋下了隐患。在去年十二月份的一次 bug 维护中,electron-builder 为了修复使其能够构建时自定义路径而更新了这个 perl 脚本,并将其中关键的 UTF-8 解码交给了 node 进行处理,在 packages/electron-builder/src/targets/dmg.ts 这个文件中非常『暴力』的让 node 读取 perl 脚本本身,然后将 $ENTRIES 进行替换,在运行时中执行整个 perl 脚本。但却忽略了 perl 脚本本身与 python 2 一样,如果不指定 utf-8 编码,那么执行将出错。

因此修复这个 bug 的方法也非常简单,只需要在 perl 脚本中增加一行代码:

use utf8;

相关 issue:

  1. https://github.com/electron-userland/electron-builder/issues/697
  2. https://github.com/LinusU/node-appdmg/issues/121
  3. https://github.com/electron-userland/electron-builder/issues/1369

你可能感兴趣的:(electron 问题收集)