Electron 在线热升级方案

一个项目正式交付客户使用了,对于版本的升级和代码更新是个一直困扰的问题,由于之前一直都是内部人员使用,可以让他们每次都下载完整压缩包(压缩后大概 40-50MB),但对于正式的终端用户,这个体验是不可接受。
参考过 Electron 官方文档,里面提及的方案兼容性并不好(Linux 不支持),需要准备的东西不少,而且交互上也不满意;以及参考了这篇 《我是如何实现electron的在线升级热更新功能的?》,最终按照里面的思路为该项目做了一个在线热升级的方案,本文介绍方案的细节及中间遇到的一些坑。

流程图

processon

关键步骤

  1. 通过 app.getVersion() 获取到 App 的本地版本号,这个版本号来源于 package.json
  2. 获取线上的 App 版本信息,此处我们设计了两个版本信息(如图例子);
    2.1. “1.3.0” 为核心版本号,该版本号用于判断是否需要重新下载完整包(图中所示的对应不同平台有不同的下载地址,为 zip 扩展名的压缩包,至于为什么用 zip,下文会提及),比如当 Electron 核心版本升级,或者增加了 node_modules 依赖等情况;
    2.2. “1.3.3” 为热更新版本号,这种情况只需要更新特定的文件列表(图中所示的 upgrade_1.3.3.tar.gz),通常包含 package.jsonsrc/* 等;
    2.3. description 分别表示核心版本和热更新版本的描述;
  3. 对比本地版本号 (appVersion) 和线上的版本号 (onlineVersion),下面是版本号比较的代码:

    3.1. 对比本地版本号和线上核心版本号 (onlineVersion.version),如果小于线上版本号,则激活浏览器并进入下载,同时退出 App;
    3.2. 否则进行对比本地版本号和热更新版本号 (onlineVersion.upgrade.version),如果小于线上版本号,则下载热更新包;
  4. 根据 (upgrade.url) 下载热更新包、升级、重启 App,全部代码:

  1. Windows 下可以直接把更新文件保存到 App 目录(没有权限问题),而在 Mac OSX 下,App 目录是无权写入的,而临时文件路径必须通过 app.getPath() 来获取,常用 temp 或者 userData 目录来保存解压文件;
  2. 压缩包我使用了 zip 一个原因是 Windows 下默认就能支持 zip 包解压,另一个主要原因是文件名编码问题,最初用 tar 来压缩文件,对于英文文件名是正常的,对于中文文件名,在 Mac OSX 下打包后在 Windows 是无法被正确解开的。而貌似 7z 生成的 zip 包会保存文件名字符集并能被 Windows 正确解开,所以在 gulp 中使用了 7z 来产生 zip 压缩包:

    而对于热更新包,由于源代码都是使用英文名,所以用 tar 来压缩没毛病:

webpack 怎样生成 inline (内联) 的 style 或 script

背景

最近一个项目用到 React,默认配置下,样式和脚本都通过混淆压缩合并后生成一个 css 或 js 文件(通过 ExtractTextPlugin ),并插入到 index.html 中,详细的配置可查看 eject 后的 webpack 配置文件。

而由于输出的 css 和 js 文件都有数十 KB,在第一次加载页面时,会出现一个白屏的情况,所以我在 index.html 中加了一个 Loading 效果,但是由于 Loading 的样式也是在 css 文件内的,并没有达到预期的效果,所以想是不是可以把一些基础样式单独抽出来放到 index.html 中内联。

ExtractTextPlugin

这个插件可以把符合条件的内容输出到一个独立的文件当中,详细配置查看 https://doc.webpack-china.org/plugins/extract-text-webpack-plugin/,在 webpack.config.prod.js 配置中已经包含了该 plugin,仅用于输出外部引入的 css 文件,我们可以修改下。

此处定义了两个实例,把 extractCss 用于处理原有的 css 文件输出,extractInlineCss 用于处理需要 inline 的 css,下面是常见的 webpack 配置内容,我们在 css 处理器前加上 inline css 的处理

完成这个步骤后,build 过程会对 inline.css 结尾的文件合并并输出到 main.inline.css

HtmlWebpackInlineSourcePlugin

这个插件可以把符合条件的 css 或 js 内联到 index.html 中,详细配置查看 https://github.com/DustinJackson/html-webpack-inline-source-plugin,这里我们需要把 inline.css 结尾的文件内联进来。

最后,build 完的结果是把这些 inline.css 的内容都内潜入 index.html 中,以致在未加载完独立 css 和 js 时也可以把 Loading 显示正确。

MySQL 根据出生年月日计算年龄

项目中需要做一个年龄统计,其中字段 birthdayDATE 类型。

关键是 RIGHT(CURDATE(),5) < RIGHT(birthday,5) 用于判断 MM-DD 是否小于当前日期的值(就是过了生日没),如果小于则减一岁。

PHP 获取 zval 类型转换结果的函数

在扩展中我们常常会对 zval 进行类型转换,常用的方法可以 convert_to_*,但是这套函数需要声明临时 zval 来保存结果,对于仅仅需要获取标量转换结果的话有点麻烦了,在 zend_operators.h 中可以找到一些简单的获取转换结果的方法。

下一页 →