Electron-Vue 环境搭建 + 基本入门 + 软件打包 + 软件更新

electron是一个使用JS,CSS,HTML构建跨平台的桌面应用程序的框架,微软的VScode就是使用该技术开发

环境搭建

  1. 安装node环境

  2. 由于使用的是electron-vue脚手架工具,首先要安装vuecli

1
2
3
npm install -g @vue/cli
# OR
yarn global add @vue/cli
  1. 起步

vue init阶段会出现一些项目基本选项,按照自己需求选择就好,打包工具选择elelctron-builder之后会用到它打包和更新

img

1
2
3
4
5
6
7
8
9
10
11
vue init simulatedgreg/electron-vue my-project

cd my-project

npm install
# OR
yarn

npm run dev
# OR
yarn dev
  1. 出现以下界面及成功

img

注意事项

  • npm install时候可能会由于网络原因导致包安装失败,使用cnpm或者nrm切换软件源
  • npm install时候可能会遇到electron下载失败情况,有两种解决方法
    1. 在项目根目录下新建.npmrc或者.yarnrc文件,里面写入
      1
      electron_mirror=http://npm.taobao.org/mirrors/electron/
    2. 淘宝镜像下载对应系统和版本的electron包到electron缓存目录
      1
      mac/win/liunx: 当前用户名/.electron/ 
  • windows用户在npm install时候会遇到node-gyp错误,这是由于你的系统没有安装正确到构建工具,可以使用windows-build-tools一键安装所有到所需工具包
1
2
3
npm install --global windows-build-tools
# OR
yarn global add windows-build-tools
  • npm run dev时候可能会遇到process is not defined错误,这是由于node10.X版本导致的,有两种解决方法
    1. 升级node版本到12.X
    2. 打开项目/src/index.ejs,修改!process.browser!require('process').browser

基础入门

插件使用

插件使用和vue一样,npm/yarn直接装包就可以,脚手架自带electron-vuex可以实现主进程与渲染线程共享数据,推荐使用

css预处理器

假设我们使用less作为我们到css预先处理,需要安装less并且修改webpack配置

  1. 安装
1
2
3
npm install -D less less-loader
# OR
yarn add -D less less-loader
  1. 打开.electron-vue/webpack.renderer.config.js,在less rule里面加入less-loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
test: /\.less$/,
use: [
{
loader: "vue-style-loader"
},
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
{
loader: "postcss-loader",
},
{
loader: "less-loader",
options: {
javascriptEnabled: true,
modifyVars: {
'text-primary-color': '#293A4D', // 主要'
'text-minor-color': 'rgba(41, 58, 77, 0.45)', // 次要'
'text-highlight-color': '#1890FF' // 高亮
}
}
}
]
}

静态资源使用

在项目根目录下的static目录,可以存放主进程和渲染进程都可以访问到的静态资源,electron-vue提供一个__static全局变量来快速访问此目录,而且开发环境和生产都可以使用。

  1. vue模版使用
1
2
3
4
5
6
7
8
9
10
11
12
<template>
<img v-bind:src="imageUrl">
</template>

<script>
export default {
data () {
// 注意 路径的起始是 `static/`
return { imageUrl: 'static/imgs/unsplash.png' }
}
}
</script>
  1. js文件使用
1
2
3
4
5
6
import fs from 'fs'
import path from 'path'

let fileContents = fs.readFileSync(path.join(__static, '/someFile.txt'), 'utf8')

console.log(fileContents)

读写本地文件

使用 electron 的一大好处是可以访问用户的文件系统。这使你可以读取和写入本地系统上的文件。electron提供了app.getPath(name)来快速访问本地文件目录,比如桌面、用户目录等等

1
2
3
4
5
6
7
8
9
10
// 用户的home文件夹
app.getPath('home')

// 用户桌面
app.getPath('desktop')

// 用户下载文件夹
app.getPath('downloads')

// 更多访问 https://www.electronjs.org/docs/api/app#appgetpathname

主线程与渲染进程通信

  1. ipcMainipcRenderer
1
2
3
4
5
6
7
8
9
10
11
// 在主进程中.
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.reply('asynchronous-reply', 'pong')
})

ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.returnValue = 'pong'
})
1
2
3
4
5
6
7
8
//在渲染器进程 (网页) 中。
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')
  1. remote模块

在渲染进程中,可以通过const {remote} = require('electron')来获取到remote对象. 通过这个对象可以允许渲染进程访问主进程的模块.

1
2
3
4
5
6
7
8
// 把自定义方法挂载到app下
const { app } = require('electron');

app.utils = {
test () {
return 'hello world'
}
}
1
2
3
4
// 在渲染进程中通过remote模块访问此方法
const {remote} = require('electron')
remote.app.utils.test()

软件打包

electron-packagerelectron-builder都可以把代码打包成各个平台安装包。正经过调研和实际使用electron-builder功能丰富,可配置性强,故下面都使用electron-builder进行打包

  1. vue init阶段应该选择electron-builder作为打包工具
  2. 为了方便首先自定义打包命令

为各个平台添加打包命令。在package.json文件scripts里加入以下命令

1
2
3
4
5
"scripts": {
"build:dmg": "node .electron-vue/build.js && electron-builder --mac",
"build:deb": "node .electron-vue/build.js && electron-builder --linux",
"build:exe": "node .electron-vue/build.js && electron-builder --win"
}
  1. 自定义打包配置

与打包相关的配置在package.json文件的build下面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"build": {
"productName": "hello-electron-vue",
"appId": "com.example.yourapp",
"directories": {
"output": "build"
},
"files": [
"dist/electron/**/*"
],
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": {
"icon": "build/icons/icon.icns"
},
"win": {
"icon": "build/icons/icon.ico"
},
"linux": {
"icon": "build/icons"
}
}

上面是默认配置,下面是我的自定义配置并会进行相关说明,更多配置请查看electron-builder官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"build": {
// productName 是软件安装后的名字,只适用于像dmg、exe、deb这种安装包
"productName": "这里是软件安装后的名字",
"appId": "com.example.yourapp",
"copyright": "这里是软件版权信息",
"directories": {
"output": "build"
},
"files": [
"dist/electron/**/*"
],
// electron下载镜像地址,推荐设置,不然下载electron会失败
"electronDownload": {
"mirror": "https://npm.taobao.org/mirrors/electron/"
},
// 打包dmg安装包自定义配置,对应macos平台
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
],
// 如果没有苹果开发者账号请禁止dmg签名
"sign": false,
"icon": "build/icons/icon.ico"
},
// 打包成appImage自定义配置,对应linux平台
"appImage": {
"desktop": {
"Name[zh_CN]": "这里是软件安装后的名字",
"Name": "这里是软件安装后的名字",
"Icon": "build/Icons/Icon256x256.png"
}
},
// windows平台打包工具配置
"nsis": {
// 是否一键安装,false后安装时候会出现安装引导界面,比如自定义安装位置
"oneClick": false,
"perMachine": false,
// 是否允许用户自定义安装目录
"allowToChangeInstallationDirectory": true,
// 安装/卸载时候图标
"installerIcon": "build/icons/icon.ico",
"uninstallerIcon": "build/icons/icon.ico",
"installerHeaderIcon": "build/icons/icon.ico",
// 安装完成后i是否创建快捷方式
"createDesktopShortcut": true
},
// 打包成deb安装包自定义配置,对应linux平台
"deb": {
"icon": "build/icons"
},
"mac": {
"icon": "build/icons/icon.icns",
// macos平台如果没有苹果开发者账号请禁止代码签名,不然会打包错误
"identity": null
},
"win": {
// win平台下图标为ico格式,mac平台为icns,linux平台为png
"icon": "build/icons/icon.ico"
},
"linux": {
"icon": "build/icons",
// linux平台打包类型
"target": ["AppImage", "deb"]
}
}
  1. 根据第二步打包命令执行即可

建议在当前平台只打包当前平台,如果打包其他平台可能会出现无法预知错误,可以利用虚拟机在一个电脑上打包多平台。在yarn build时候你可能会遇到打包组件(electron fpm nsis)下载失败情况,请到这里下载对应版本到组件,然后放到系统缓存目录

1
2
3
macOS ~/Library/Caches/electron-builder
linux ~/.cache/electron-builder
windows %LOCALAPPDATA%\electron-builder\cache
  1. 打包成功后在build目录里面会找到对应安装包

注意事项

  • deb安装包在ubuntu安装成功后,会出现打不开软件情况,因为系统缺少libgconf2-4,运行下面命令安装即可
1
sudo apt -y install libgconf2-4

软件更新

electron-builder插件也自带更新功能,也可以把打包好的安装包发布到各个开源平台以及自定义。

注意事项

  • 三个平台只支持特定的安装包格式,其他格式(deb)暂不支持
1
2
3
macOS: DMG
Linux: AppImage
Windows: NSIS
  • macos平台必须开启代码签名才可以进行更新操作

12

  1. 添加发布配置

publish 配置添加到package.json文件的build下面会对所有平台生效,也可以为某个特定平台添加特有发布配置

1
2
3
4
5
6
7
8
9
10
"publish": [
{
// provider 字段是发布对平台,支持Bintray, GitHub, S3, Spaces or Snap Store和自定义发布服务器
// 这里只演示自定义服务器,更多配置及api请查看官方文档https://www.electron.build/configuration/publish
"provider": "generic",
// url为发布服务器地址和路径,搭建一个文件服务器就可以,或者oss。路径下就是安装包存放的位置
"url": "http://127.0.0.1:2333/test/"
}
]

  1. 相关代码

更新是写在主线程中,因为更新只能在打包后测试,为了调试方便建议使用electron-log把每一步日志和错误都打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { autoUpdater } from 'electron-updater'
const log = require('electron-log')

// 检查更新
// sendStatusToWindow函数为把更新消息发送到渲染进程
ipcMain.on('check-update', (event, arg) => {
log.info("check-update")
// 检查更新
autoUpdater.checkForUpdates()
})

autoUpdater.on('error', (err) => {
log.error("update-error")
log.error(err)
sendStatusToWindow(-1, '更新错误', 0)
})

autoUpdater.on('checking-for-update', () => {
log.info("checking-for-update")
sendStatusToWindow(1, '正在检查更新', 0)
})

autoUpdater.on('update-available', () => {
log.info("update-available")
// 发现有可用更新
sendStatusToWindow(1, '有可用更新', 0)
})

autoUpdater.on('update-not-available', () => {
log.info("update-not-available")
sendStatusToWindow(1, '没有可用更新', 0)
})

autoUpdater.on('download-progress', (progress, bytesPerSecond, percent, total, transferred) => {
// 监听下载进度
log.info("download-progress")
log.info(parseInt(progress.percent) + '%')
sendStatusToWindow(1, '下载中', progress.percent)
})

autoUpdater.on('update-downloaded', (UpdateInfo) => {
// 下载安装包完成后会触发,此时发送给渲染进程下载完成消息,渲染进程点击安装,执行autoUpdater.quitAndInstall()方法重启应用安装
log.info('update-downloaded')
log.info(UpdateInfo)
sendStatusToWindow(2, '已下载完成', 100)
ipcMain.on('update-install', (event, arg) => {
log.info('update-install')
autoUpdater.quitAndInstall()
})
})
  1. 上传安装包和yml文件

yarn build完成后,如果你配置了publish会额外生成一个yaml文件,此文件记录当前安装包一些信息,以便检查更新进行对比来判断是否要更新。默认情况下win平台会生成latestyml,macos平台latest-mac.yml,linux平台latest-linux.yml,把安装包和yml文件一起上传到发布服务器相应路径下

23

参考资料