基于Umi搭建Electron App

990 阅读9分钟

环境准备

在开发之前需要准备Node环境,可以去Node官网下载安装包,安装Node环境以及Npm工具。 我本地使用nvm管理三个版本的Node,搭建Umi+Antd+Electron框架时使用的Node版本及Npm版本如下图所示。

image.png

Tips: 如果觉得npm下载依赖包的速度过慢可以考虑使用淘宝镜像或者换成yarn,但是不建议使用cnpm,因为cnpm下载的依赖包都是扁平化的,会导致打包的过程非常慢且Node内存溢出的问题。

使用Umi创建React项目

因为想要使用Ant Design作为UI库,所以可以参考Ant Design Pro的搭建步骤。(如果参考UmiJS的搭建步骤,还需要自己再去集成Ant Design,所以还不如直接参考Ant Design Pro的搭建步骤) 如果你的电脑和我的一样是Windows系统,那么按照Ant Design Pro提供的步骤搭建框架会出现下图的问题: image.png 根据上图中的提示,找到D:\front_end_environment\node\node_global\bin\create-umi这个文件打开看一下: image.png 在Windows系统下,盘符前不需要‘%~dp0’符号。将上图红框圈出的部分删掉后保存该文件并执行create-umi命令(注:不要再执行yarn create umi命令,否则这会重新安装create-umi,这样会把之前改过的文件覆盖掉。) 如果执行create-umi命令报错“不是内部或外部命令”,那么需要将“D:\front_end_environment\node\node_global\bin”路径添加至系统变量path中。

create-umi配置步骤

执行create-umi命令之后需要根据提示选择配置:

  1. 选择模板类型:

image.png 这里回车选择第一个ant-design-pro。

  1. 选择ant-design-pro版本:

image.png 这里回车选择V4版本。

  1. 选择语言

image.png 虽然TS很火,但我还是喜欢JS(TS还不咋会呢~~~)

  1. 选择安装Ant Design Pro的所有模块还是安装简单的脚手架

image.png 对Ant Design比较熟悉的话,选择complete。

  1. 创建成功

image.png 最终成功搭建好的React项目目录结构如下: image.png

  1. 打开WS,运行npm install、npm run start,界面如下:

image.png

  1. 为了直观地区分对 第四步“选择安装Ant Design的所有模块还是安装简单的脚手架” 进行不同选择的区别,我也进行了简单脚手架的安装,界面如下:

image.png

对比两种选择的结果,显然安装Ant Design Pro的所有模块会看到Ant Design官方提供的丰富的页面样例,里面涵盖了大部分的Ant Design组件。而简单的脚手架中就只有简单的两个页面,但是两个工程除了pages文件夹下的内容不一样之外,其他内容几乎没有什么不同。 所以实际应用中根据实际需求做出合适的选择即可。

Web应用——>Electron应用

引入Electron依赖

参考Electron官网文档,执行npm install electron --save-dev命令安装Electron作为开发依赖。

编写Electron主进程文件

参考Electron官网文档,编写Electron主进程文件main.js。暂时先将main.js放在工程根目录。 main.js文件内容如下:

image.png

注:图片中所示代码的17行,mainWindow.loadURL(url); 这里的参数url应该与webpck的devServer配置项的host和port一致。使用Umi创建的项目内置了webpack devServer配置,默认配置见devServer或直接看下图:

image.png

如果你本地的8000端口被占用了,可以在package.json中指定PORT,就像这样:

image.png

或者,你也可以在工程根目录下新建.env文件,在.env文件中配置PORT,就像这样:

image.png

Umi中内置的环境变量配置项还有很多,详见:env-variables

运行Electron App

main.js配置好之后,开始尝试把Electron App run 起来~~~ 在package.json中配置程序主入口main.js,并且添加运行Electron的脚本命令,如下图:

image.png

然后。。。看到electron脚本命令前面的绿色小三角了吗?点它点它!或者直接在Terminal输入npm run electron,就能把electorn应用run起来了,如下图:

image.png

现在看到的Electron App的界面是一片空白,是因为主进程脚本第17行代码:mainWindow.loadURL('http://localhost:8000/');需要加载的'http://localhost:8000/'资源找不到,所以界面会一片空白。 在这个基于Umi创建的Electron App中,渲染进程这一角色由React来充当。所以需要先执行Umi的启动脚本:

image.png

然后再重新运行Electron的启动脚本,此时可以看到Elctron App中出现平时在Web端看到的界面咯~~:

image.png

启动Electorn App需要先后执行两个脚本命令,这样会比较麻烦,主进程和渲染进程如果可以使用一个脚本命令就可以全部启动的话,会节省一部分开发调试时间。 使用concurrently库同步运行多命令,同时运行electron和react。使用wait-on库等待8000端口启动完成之后运行electron。具体的脚本命令如下图:

image.png

看一下执行过程:

image.png

Electron App打包

安装electron-builder

Electron App的打包方式有三种,具体可参考[Electron应用打包、发布、更新](www.yuque.com/docs/share/… 《Electron应用打包、发布、更新》)这篇文章。 我选择的打包方式是electron-builder。 参考electron-builder官网,执行yarn add electron-builder --dev命令安装electron-builder作为开发依赖。

配置electron-builder

我的电脑是Windows系统(如果操作系统不一样,请自行查询electron-builder官方文档配置),具体配置如下图:

image.png

我只简单的配置了appId(实际生产的时候需要申请,这里先随便写一个),productName(为最终生成的可执行文件指定名字,实际生产的时候根据实际情况修改),打包文件输出目录output,打包时使用的文件files。其他配置项请参考electron-builder官方配置文档

webpack打包配置

如果Electron App没有集成React作为渲染进程,那么只需要配置electron-builder即可。


但是这个工程是基于Umi创建的,所以相当于渲染进程和主进程是分开打包的: 1. 对渲染进程(React)使用webpack打包; 2. 主进程(Electron)使用electron-builder打包,把渲染进程打出的包再打进Electron包里(看上图中第126行的files配置)。

-- 2021年6月1日 --

总感觉上面划掉的部分描述有些不准确。。。。重新写一下:

基于Umi搭建Electron App,其实可以理解成通过Electron将使用Umi搭建的Web应用包装成桌面应用。

image.png

所以对于基于Umi搭建的Electron App,需要对Web应用和Elecrton分别打包。

  1. web应用打包:使用webpack打包
  2. 桌面应用程序打包:使用electron-builder打包
  3. 将Web应用打包后的文件(build文件夹中的所有文件)复制到桌面应用程序中(通过electron-builder中的files配置,就像这样:"files": [ "build/**/*"]。有关files的详细内容请查看electron-builder Application Contentselectron-builder File Patterns

Umi中内置了webpack,所以一些配置已经写好了,但是需要结合Electron打包的需要修改一下默认配置:

history

默认路由模式是“browser”,打包后会出现首页或其他页面找不到继而加载不出来的情况,所以需要改成hash模式。

publicPath

默认值是'/',需要改成"./" 摘录自Umi publicPath

配置 webpack 的 publicPath。当打包的时候,webpack 会在静态文件路径前面添加 publicPath 的值,当你需要修改静态文件地址时,比如使用 CDN 部署,把 publicPath 的值设为 CDN 的值就可以。如果使用一些特殊的文件系统,比如混合开发或者 cordova 等技术,可以尝试将 publicPath 设置成 ./ 相对路径。

outputPath

默认值是'dist',但是因为Electron的打包输出目录是dist,所以webpack打包输出目录改成'build'。 具体配置如下图:

image.png

Electron主进程文件修改

内容修改

在开始打包之前,需要对主进程main.js文件做一些修改,如下图:

image.png

图中增加的几行代码大多是有关环境变量的,在生产环境下是无法通过loadURL这种方式加载渲染进程的,生产环境下只能通过加载某个文件来加载渲染进程,也就是上图中的loadFile的方式。 在生产环境和开发环境下加载渲染进程的方式不同,所以需要判断当前的环境然后进行分别处理。 环境变量的配置可以看一下cross-env这个库,在使用Umi创建工程时,cross-env是默认安装的。

位置变动

之前在编写Electron主进程文件的时候,暂时将main.js放在了工程根目录。但这样放置的话,由于main.js与其他模块之间没有任何引用关系,所以webpcak打包时无法把main.js打进去。那么生产环境下main.js中加载index.html就找不到这个文件,执行打包后生成的electron.exe文件时会出现白屏的情况。 鉴于这种情况,有以下的解决办法:

  1. 把main.js放到public文件夹下,因为webpack打包时public文件夹下的文件都会原封不动地复制到build文件夹中。
  2. 将package.json中配置项"main"的值由"main.js"改为"build/main.js"。

脚本命令配置

生产环境和开发环境下electron启动命令

通过在package.json中配置脚本命令的方式来设置当前的环境,如下图:

image.png

图中第36行是生产环境下electron启动命令,通过cross-env NODE_ENV=production来设置环境变量为“production”表明是生产环境,生产环境下electron主进程是直接执行的打包生成的build文件夹下的main.js文件。 图中第37行是开发环境下electron启动命令,设置环境变量的方式与生产环境类似,但是开发环境下electron主进程是执行的public文件下的main.js。

针对不同平台的electron打包命令

image.png

在package.json里我只配置了windows和mac两种平台的打包命令(它们的共同点是都要先执行yarn build对react进行打包),因为我的电脑是windows,所以只尝试了windows下的打包,打包出的文件如下图:

image.png

打包体积

Electron App打出的包体积有些大,如果网络不好的话,下载安装包会有些慢。总的来说,打包体积有待优化。

image.png

basic-electron-umi-app

这是我搭建的基于Umi的electron app框架,放到gitee上了:basic-electron-umi-app