Electron是一个基于Chromium和 Node.js,可以使用 HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容 Mac、Windows 和 Linux。虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求。受限于浏览器的沙盒限制,网页应用无法满足某些场景下的使用需求,而桌面应用可以读写本地文件、调用更多系统资源,再加上Web开发的低成本、高效率的优势,这种方式越来越受到开发者的喜爱。
本文一步一步教你如何使用Electron7和vue-cli4,在完全保留vue开发web应用的习惯下,搭建桌面应用。
本文不涉及Electron和vue的开发教程,仅以实现两者结合为目的,如深入学习Electron和vue,请访问各自官方。
1.1 加速npm下载
将npm仓库镜像改为淘宝镜像
npm config set registry http://registry.npm.taobao.org/
也可以使用cnpm加速安装,需要先安装cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
1.2 为什么不使用SimulatedGREG/electron-vue
SimulatedGREG/electron-vue已经很久没有更新了,而且其生成的工程结构并不是vue-cli3。所以放弃使用。
1.3 安装/升级vue-cli4
先执行以下命令,确认下本地安装的vue-cli版本:
vue -V
在写本文时,我使用的是4.1.1版本。
如果不是最新版,可以执行以下命令安装/升级:
npm install @vue/cli -g
1.4 创建vue项目
找个喜欢的目录,执行以下命令,创建vue项目:
(这里把项目名称定为electron7-vue-demo)
vue create electron7-vue-demo
会出现以下选项(如果熟悉此步骤可跳过本节内容):
选择“Manually select features” (自定义安装)。
这里选择了常用的模块,请根据实际需求进行选择。
如果选择了router,这里会询问是否使用history模式。
vue-router 默认使用hash模式(即通过url#hash来跳转页面),使用URL的hash来模拟一个完整的 URL,当URL改变时,页面不会重新加载。
如果使用history,URL的子路径就会使用斜杠,例如 yoursite.com/user/id ,比较好看。但是需要服务器进行配置来支持。
这里我们选择“n”。
选择CSS预处理模块,我习惯使用Stylus,这里选了“Stylus”。
选择ESLint代码格式检查工具的配置,选择“ESLint + Standard config”,标准配置。
Line on save表示在保存代码的时候,进行格式检查。
Lint and fix on commit表示在git commit的时候自动纠正格式。
这里只选择“Lint on save”。
这里问把 babel, postcss, eslint 这些配置文件放哪?
In dedicated config files 表示独立文件
In package.json 表示放在package.json里
这里选择“In package.json”。
是否为以后的项目保留这些设置?选择“N”。
然后耐心等待项目安装完成。
1.5 安装electron
※注:此过程可能需要科学上网,由于直接从国外镜像下载较慢,可能需要等待很漫长的时间。如果你对自己的网速没有超强自信,请跳过本节,前往1.6小节手动安装。
官方指导:https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/
进入到项目根目录,执行:
vue add electron-builder
在安装过程中,很可能会卡在这一步不动了(未科学上网):
没关系,我们先强制结束掉。再执行一次vue add electron-builder,然后就可以顺利通过了。
接下来出现配置选项:
没有7.0.0?没关系,先选择6.0.0。
然后耐心等待安装完成。如果中间出现错误中断了,请重复此步骤。
安装过程中会出现两个warning:
安装完成后,会自动编译并运行项目,但由于Vue Devtools的问题,导致运行失败。
原因是installVueDevtools未被使用。
结合刚才的WARNING,我们在/src/background.js发现以下注释:
大致意思是:
Devtools扩展工具在Electron6.0.0.以上不好使了。 详见:https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378
在Win10黑暗主题模式下,装了Devtools后,Electron就无法启动。 如果你没有使用Win10黑暗主题,可以去掉下面的注释。 另外,如果上面链接的问题已经关闭,你可以更新Electron并去掉下面的注释。
在写作本文时(2019年12月17日),这个issue还是open状态。我用的是macOS,所以我去掉了注释。
现在升级electron到7.0,修改/package.json
执行以下命令,完成升级安装:
npm install
1.6 手动安装electron
※注:如果已经通过1.5章节的操作,请直接跳过本小节。
如果使用自动安装,安装完成后会自动在src目录下生成background.js并修改package.json。但由于不能科学上网或网速很慢的话,只能手动进行配置并安装了。这种方式简单粗暴,一步到位(electron7.0)。
修改package.json,添加以下7行:
在src目录下新建background.js,复制以下代码:
以上代码是1.5小节使用自动化方式安装后生成的。为什么要注释掉installVueDevtools(Chrome Vue DevTools插件),请回顾1.5小节最后的说明。
执行以下命令,完成升级安装:
npm install
如果未科学上网,可能会卡在这一步:
这时候就需要终止,并删除node_modules/electron目录。
然后使用cnpm进行安装:
cnpm install
1.7 编译并启动APP
执行以下命令,开始编译APP,并启动开发环境APP:
npm run electron:serve
首次启动可能会等待很久,出现以下信息:
这是因为在请求安装vuejs devtools插件。需要科学上网才能安装成功。如果不能科学上网也没关系,耐心等待5次请求失败后会自动跳过。
编译成功后,就会出现开发环境的APP了。
2.1 主进程和渲染进程简介
在开始下面的步骤之前,很有必要简单了解下Electron的应用架构。
【主进程】
Electron 运行 package.json 的 main 脚本(background.js)的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
【渲染进程】
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中。
在普通的浏览器中,web页面通常在一个沙盒环境中运行,不被允许去接触原生的资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
【主进程与渲染进程的关系】
主进程使用 BrowserWindow 实例创建页面。 每个 BrowserWindow 实例都在自己的渲染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。
主进程管理所有的web页面和它们对应的渲染进程。 每个渲染进程都是独立的,它只关心它所运行的 web 页面。
具体可参阅官方文档:https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
2.2 APP窗口大小
修改src/background.js:
2.3 取消跨域限制
修改src/background.js:
2.4 取消菜单栏
在我们生成的桌面APP中,我们可以看到默认的菜单栏。
在windows中,菜单栏在APP窗口内的顶部;在macOS中,菜单栏位于电脑屏幕顶部。
为了方便项目将来也能直接生成纯web应用,尽量把APP的全部功能都做到渲染进程里,这里我们取消菜单栏。
由于macOS的特殊性,顶部菜单栏无法删除,所以我们针对macOS特殊处理,把菜单栏只保留“关于”和“退出”。
修改src/background.js:
macOS菜单栏名称label的“App Demo”会在build版本生效,dev版本会显示“Electron”
更多关于菜单栏设置,请参阅:https://electronjs.org/docs/api/menu
2.5 设置APP窗口图标
准备windows和macOS两版图标。
windows: app.ico 最小尺寸:256x256
macOS: app.png或app.icns 最小尺寸:512x512 (后续3.1章节用到)
把图标文件放到public/目录下,项目结构如下:
可以顺便把favicon.ico也修改一下,但是在桌面版APP上是用不到的。如果以后生成纯web项目才会用到。
修改background.js,让APP窗口应用图标:
这里的${__static}对应的是public目录
现在,Windows系统上可以看到开发环境的APP窗口图标已经生效了。
macOS图标请参照4.1章节,并且需要在build后才能生效。
2.6 设置APP窗口标题栏名称
修改public/index.html:
我们把electron-vue-demo改为App Demo。
这里我们已经集成了electron-builder工具,官方文档可以参阅:www.electron.build/
3.1 设置APP及安装包图标
在2.5章节,我们的图标生效于运行APP的窗口。本小节将生效于最终生成的可执行文件和安装包图标。需要准备的图标文件请回看2.5章节。
修改vue.config.js
运行build后的mac版本,可以看到图标都已生效了。
安装包和可执行文件的截图就不再放出了。
更多详细介绍,可参阅: www.electron.build/icons.html
3.2 设置APP名称
APP名称包括安装包中APP的名称、可执行文件的文件名。
修改vue.config.js:
3.3 打包APP
执行以下命令,可以build工程:
npm run electron:build
复制代码
最终在dist_electron目录下生成build后的产品。
【windows版本】
目录如下:
这里其实就win-unpacked和AppDemo Setup 0.1.0.exe有用。
※注:在32位环境下打包生成的是32位APP,在64位环境下打包生成的是64位APP。
3.4 可能出现的错误
我曾经在Win10 64bit 1809版本上build失败,保存信息中提示:
Error output:Can't open output fileError - aborting creation process
与此同时,在win7和win10 1803版本build正常。经研究,无果。后来把windows升级到1903版本,问题解决了。应该是vue-cli-plugin-electron-builder插件与系统之间的问题导致。
在完成以上章节后,后面基本可以完全按照web方式开发了。这里简单分享下一些小经验。
4.1 src目录结构参考
下面对部分重要目录简要说明:
4.2 换肤功能的实现
很多项目都有实时换肤的需求,在实际开发中,虽然我们使用了Sass、Less、Stylus等高端样式工具,但最终经过编译还是要回归到最原始的CSS。换肤的本质还是实时替换皮肤样式文件。
以Stylus为例,抽象出皮肤文件skin.styl:
$color-bg = #fff$color-text = #333
在业务样式中引用:
@import 'skin.styl'body background: $color-bg color: $color-text
当经过编译后,生成的css为:
body {background: #fff; color: #333;}
样式已经写死了,无法换肤。
那么应该怎么做呢?
【成功案例】
项目根目录下的public目录是静态目录,也就是说在build最终产品的时候,它里面的文件将原封不动保留。所以,可以将皮肤文件放在这里。
由于Electron的是基于chromium内核,所以不用担心代码的浏览器兼容问题。接下来就是发挥CSS3变量var(--*)的时候了。
public/skin/skin01/skin.css:
:root { --color-bg: #fff; --color-text: #333;}
public/skin/skin02/skin.css:
:root { --color-bg: #263238; --color-text: #b2ccd6;}
修改src/App.vue:
在public/index.html引入皮肤样式,注意加上id="app-skin":
篇幅有限,这里就不写通过js修改皮肤的代码了。通过调试工具手动修改skin的css路径,可看到换肤效果:
4.3 注册快捷键打开devTools
在Electron中打开devTools是通过主线程中调用win.webContents.openDevTools()实现的。以上教程仅在开发环境初始启动的时候打开devTools,但是一旦关闭就不能再打开了。下面讲一下怎么通过快捷键打开devTools。
修改src/background.js:
在windows下,按Ctrl+Shift+i即可打开devTools
在macOS下,按Commond+Shift+i即可打开devTools
为什么没用F12?因为windows系统中,F12是系统保留快捷键,无法使用。官方原话是这么解释的:
The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident.
但是可以使用Ctrl+F12,只要不单独使用F12就可以。
以上代码在开发环境和生产环境中均有效,为保证生产环境的安全,建议不要在生产环境中使用。放到上面的if语句中即可。
文中涉及的代码可到作者微信公众号中复制,公众号名称:卧梅又闻花。