创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程
环境: node v20.18.0 npm 11.1.0
用到的所有依赖:
"dependencies": {
"core-js": "^3.8.3",
"vue": "^3.2.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"cross-env": "^7.0.3",
"dotenv-webpack": "^8.1.0",
"electron": "^35.0.0",
"electron-builder": "^25.1.8",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
安装@vue/cli
// 已经安装可以忽略
npm install -g @vue/cli
创建一个新的 Vue 项目
vue create my-electron-vue-app
cd my-electron-vue-app
// 加上这个,build后,发布的页面不会出现白板
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/'
};
添加Electron镜像地址
添加.npmrc文件,里面加上。不配置这个会有很多electron相关的文件下载不了。
electron_mirror=https://npmmirror.com/mirrors/electron/
安装 Electron
npm install electron --save-dev
mkdir electron
touch electron/main.js
// electron/main.js
// app 模块,它控制应用程序的事件生命周期。
// BrowserWindow 模块,它创建和管理应用程序 窗口。
const { app, BrowserWindow, ipcMain } = require('electron')
// 部引入 Node.js 中的 path 模块
const path = require('path')
const process = require('process')
// 添加一个createWindow()方法来将index.html加载进一个新的BrowserWindow实例
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
//预加载
// __dirname 字符串指向当前正在执行脚本的路径 (本项目,指向项目的根文件夹)。
// path.join API 将多个路径段联结在一起,创建一个跨平台的组合路径字符串。
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:8080');
// Open the DevTools.
// mainWindow.webContents.openDevTools()
} else {
mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
}
}
// 在 Electron 中,只有在 app 模块的 ready 事件被激发后才能创建浏览器窗口。
// 您可以通过使用 app.whenReady() API来监听此事件。
// 在whenReady()成功后调用createWindow()。
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// 在macOS上,当单击dock图标并且没有其他窗口打开时,通常会在应用程序中重新创建一个窗口
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// 在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。
// 为了实现这一点,监听 app 模块的 'window-all-closed' 事件,
// 并在用户不是在 macOS (darwin) 上运行时调用 [app.quit()][app-quit]
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
touch electron/preload.js
// electron/preload.js
/**
* 预加载
* 预加载脚本在渲染器进程加载之前加载,并有权访问两个 渲染器全局 (例如 window 和 document) 和 Node.js 环境(例如 process)
*/
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
// package.json
{
...
// 加入"main": "electron/main.js"
"main": "electron/main.js",
"scripts": {
...
// 本地启动命令electron:serve
"electron:serve": "set NODE_ENV=development&& electron ."
},
...
}
安装Electron打包程序electron-builder
npm install electron-builder --save-dev
// package.json
{
...
"scripts": {
...
"electron:build": "set NODE_ENV=production&& electron-builder"
},
// electron打包配置
"build": {
"appId": "com.example.yourapp",
"productName": "YourApp",
"directories": {
"output": "dist_electron"
},
"files": [
"dist/**/*",
"electron/*"
],
"win": {
"target": "nsis",
"icon": "build/icon.ico"
},
"mac": {
"target": "dmg",
"icon": "build/icon.icns"
},
"linux": {
"target": "AppImage",
"icon": "build/icon.png"
}
},
...
}
appId: com.example.yourapp
productName: YourApp
copyright: Copyright © 2025 MyApp
directories:
output: dist_electron
files:
- "dist/**/*"
- "electron/*"
asar: true
win:
target: nsis
icon: build/icon.ico
mac:
target: dmg
icon: build/icon.icns
linux:
target: AppImage
icon: build/icon.png
nsis:
oneClick: false # 是否一键安装
#allowElevation: true # 允许请求提升权限
allowToChangeInstallationDirectory: true # 允许修改安装目录
createDesktopShortcut: true # 创建桌面快捷方式
createStartMenuShortcut: true # 创建开始菜单快捷方式
安装配置env环境变量
npm install dotenv-webpack --save-dev
const Dotenv = require('dotenv-webpack');
module.exports = {
configureWebpack: {
plugins: [
new Dotenv({
path: `./.env.${process.env.NODE_ENV}`,
})
]
}
};
npm install cross-env --save-dev
{
...
"scripts": {
// "serve": "vue-cli-service serve",
"serve": "cross-env NODE_ENV=development vue-cli-service serve",
// "build": "vue-cli-service build",
"build": "cross-env NODE_ENV=production vue-cli-service build",
...
},
}
touch .env.development
touch .env.production
// .env.development
API_URL=https://dev.api.example.com
// .env.production
API_URL=https://pro.api.example.com
安装vue-router配置
npm install vue-router
// src/router/index.js
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
import HelloWorld from '../components/HelloWorld.vue';
const routes = [
{ path: '/', component: HelloWorld }
];
const router = createRouter({
// 打包用createWebHashHistory,如果用createWebHistory,页面会出现白板。
history: process.env.NODE_ENV === 'production'
? createWebHashHistory(process.env.BASE_URL)
: createWebHistory(process.env.BASE_URL),
routes,
});
执行命令
npm run electron:serve
// 先执行vue的打包
npm run build
// 再执行electron的打包
npm run electron:build