最近得知QQ将使用Electron
来重构其项目,加上前段时间开发了一个在浏览器上使用threejs
运行3D模型的项目,用户喜欢使用IE来运行我们的项目或其网速达到了惊人的100k的速度,使用户无法打开页面或打开页面时间过长的现状,就萌生了大胆的想法,使用electron来使我们开发过的项目打包成桌面应用,这样用户就不纠结为什么只能使用谷歌或火狐打开项目了,且前端的图片、模型等资源均在本地,不需要占用宝贵的流量,真是一举多得的好处,于是就尝试着使用vue+electron来创建一个桌面应用。当然在创建过程中也是各种各样的坑,好在通过百度搜索、潜伏到技术群偷技术、及自己不断的debug查找问题,最终算百成功搭建了一个可以运行的框架,遂写出来方便有和我一样的需要的同事们相互借鉴。当然,如果看到有不适的配置,请帮忙指出,谢谢。
开始前准备
本项目使用了 VUE3
和 electron
需要提前安装好的工具有:NodeJs,vue-cli,和可能用到的nvm。
如果你以前开发过vue项目,且正在开发或维护着vue2的项目,则最好需要安装nvm工具来管理多个node版本,因为vue2的最高版本和electron运行所需的node的最高版本可能存在着版本冲突。通过nvm可以很方便的切换node版本。
1. 安装node
前往nodejs官网下载合适版本的nodejs,下载msi
文件后,最好安装在指定版本的node目录中,这样可以实现多个版本共存。electron最新版本至少运行在node 18.17.1
以上。
如果使用nvm来管理node版本,请忽略此步骤。
electron版本 | node版本最低 | chrome版本 |
---|---|---|
v11 | 14.16.0 | v87 |
v12 | 14.16.0 | v89 |
v13 | 14.16.0 | v91 |
v14 | 14.16.0 | v93 |
v15 | 16.5.0 | v94 |
v16 | 16.9.1 | v96 |
v17 | 16.13.0 | v98 |
v18 | 16.13.2 | v100 |
… | … | … |
v26 | 18.16.1 | v116 |
2. 安装vue-cli
在已经安装过node之后,打开终端,运行下面命令
# 安装vue-cli
npm i -g vue-cli
# 检测vue版本
vue --version
3. 安装nvm
前往nvm官网下载地址下载最新版本的nvm,下载zip
或exe
均可,然后按提示安装即可。在安装前,请先卸载已经安装好的node版本,否则会可能出现node版本对了,npm的版本不对。如果没有设置自定义安装路径和nodejs安装路径时,nvm的安装位置应该是在C:\Users\Administrator\AppData\Roaming\nvm
,实际安装位置在安装时请留心一下即可。
使用步骤:
安装完成后,打开终端,输入下面的命令安装和管理node版本。
# 安装node v18.16.1
nvm install 18.16.1
# 查看已经安装过的node列表,如果应用了的版本,其前面会有 * 号
nvm list
# 卸载指定版本的node
nvm uninstall 18.16.1
# 使用指定版本的node作用当前开发环境
nvm use 18.16.1
# 其他命令 输入nvm 即可查看说明
初始化 vite + Vue项目
vue项目的初始化有两种方式 ,下面使用哪种都行,我更喜欢使用后者,因为我们可以自动选择好vue-router、vuex/pinia等其他工具
- 使用vite来初始化一个vue项目
# 初始化一个vite项目,选择使用的框架,生成的项目名,也可以选择语言模板
npm create vite@latest vue-app-name
# 如果使用ts语言
npm create vite@latest vue-app-name -- --template vue-ts
# 进入到项目目录
cd vue-app-name
# 安装依赖
npm i
# 运行项目,在浏览器中打开项目,证明上面的步骤没有问题
npm run dev
- 或者使用下面的命令自定义安装
# 初始化vue项目
npm init vue@latest
# 根据自己的实际需要选择vue项目的技术栈,如选择vue版本,选择vuex或pinia,是否使用vue-router等
cd app_name_dir
npm install
npm run dev
安装Electron相关包
# 安装electon
npm i electron -D
# 安装electron-builder,它主要用于打包项目
npm i electron-builder -D
# 安装electron-devtools-installer,它主要用于我们开发和调试electron
npm i electron-devtools-installer -D
# 安装vite-plugin-electron, 该 包已经集成了vite和electron,它可以方便我们在渲染过程中使用nodeAPI或Electron API
# 注意:这里固定了vite-plugin-electron的版本,如果不固定,运行时他出错,打包不能进行。
npm i vite-plugin-electron@0.8.3 -D
# 安装rimraf,它辅助我们快速删除文件和文件夹
npm i rimraf -D
相关工具的官网:
electron-devtools-installer
vite-plugin-electron
创建主进程
electron项目的启动,需要一个入口程序main.js
,所以,我们需要手动为electron也创建一个入口文件,为了方便管理,我们在项目的根目录上创建electron目录,并创建main.js文件,写上electron启动的相关代码:
const { app, BrowserWindow, IpcMain } = require('electron');
const path = require('path');
// 创建窗口函数
function createWindow() {
// 判断当前是在开发环境还是在生产环境
const baseURL = process.env.NODE_ENV === 'development' ? `http://${process.env.VITE_DEV_SERVER_HOST}:${process.env.VITE_DEV_SERVER_PORT}` : `file://${path.join(__dirname, '../')}/dist/index.html`
let win = new BrowserWindow({
width: 500, // 窗口宽度
height: 600, // 窗口高度
webPreferences: {
contextIsolation: false, // 是否开启隔离上下文, 根据需要,如果设置为false,则无法使用ipc进程间的通信
nodeIntegration: true, // 渲染进程使用nodejs
preload: path.join(__dirname, 'electron', 'preload.js') // 预加载脚本,注意,后面会面electron目录下创建preload.js文件
}
});
// 如果需要打开指定的路由页面,可以在baseURL后拼接上路由地址,如:baseURL + '#/index'
win.load(baseURL);
}
// 注意whenReady返回的是一个promise对象
app.whenReady().then(() => {
createWindow();
// 对于macOS而言,关闭了全部的窗口并不会使app退出,所以,再打开app,则不会再次触发whenReady方法,需要在activate中监听,如果没有已打开的窗口,则创建新窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
})
})
// 当窗口全部关闭了,如果不是macOS,需要将app退出。
app.on('window-all-closed', () => {
if (process.platform !== 'darkwin') {
app.quit();
}
});
创建预加载脚本
在electron目录下创建预加载脚本preload.js
,当然,这个目录是自定义的,需要与上 面的preload选项匹配即可
请不要试图使用import xxx from xxx的方式引入指定的工具或插件,否则会报错。
const os = require('os');
console.log(os);
修改tsconfig.json
如果我们选择了ts语言,需要配置tsconfig.json
,因为生成的文件中只包含了src
目录下的文件,而不会处理electron目录下的文件,在include选项中添加这些选项。如果选择的语言为js,则无需此处修改。
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*/tsx",
"src/**/*/vue",
"electron/**/*.ts"
]
修改vite.config.js
通过上面的操作,我们已经安装和配置好了electron环境和vue环境,但此时的electron和vue是相互独立的,尚无法运行一个命令直接打开窗口并运行vue项目,需要修改一下vite.config.js
,使它们之间有所关联。使用我们的vs code或其他IDE,打开vite.config.js,在defineCofig
的插件(plugins)添加electron等选项。
import electron from 'vite-plugin-electron'
export default defineConfig({
plugins: [
vue(),
electron({
main: {
// electron程序入口
entry: 'electron/main.js'
},
preload: {
input: '/electron/preload.js'
},
}),
],
build: {
emptyOutDir: false // 默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录
}
})
注意:这里除了安装vite-plugin-electron
,还需要安装vite-plugin-electron-renderer
插件
修改package.json
在package.json
中需要配置一下项目的打包,运行等信息,需要注意的点有:
- 一定要删除
type: module
选项,否则会报错,无法以module的形式加载electron - 添加或修改入口文件为electron的main文件
- 重新配置打包命令和打包信息配置
下面就是package.json的配置修改的内容,只显示修改或添加的,至于没有修改或需要删除的部分不作展示了
{
"main": "electron/main.js",
"scripts": {
"build": "rimraf dist && rimraf release && vite build && electron-builder"
}
}
生产环境配置
因为我们使用的打包工具是electron-builder
。所以在要目录下,创建electron-builder.json
文件,并添加下面的内容
{
"build": {
"appId": "com.xxx.xxx", // 包名
"productName": "name", // 项目名称(软件的名称)
"asar": true, // 是否以asar的形式打包资源,设置为true后,dist包内将
"copyright": "Copyright © 2023 xxx",
"directories": {
"output": "release/${version}" // 打包后的输出路径
},
"file": "dist", // 打包的资源目录(vue打包后的项目目录)
"mac": {
"artifactName": "${productName}_${version}.${ext}",
"target": [
"dmg"
]
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
],
"artifactName": "${productName}_${version}.${ext}"
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"deleteAppDataOnUninstall": false
},
"publish": [
{
"provider": "generic",
"url": "http://127.0.0.1:8080"
}
],
"releaseInfo": {
"releaseNotes": "版本更新的具体内容"
}
}
}
至此,我们的electron-vue的项目搭建完成了,最后运行下面的命令,可以打包或运行项目
# 本地运行
npm run dev
# 打包
npm run build