buildadmin + electron 桌面应用开发
步骤 1:安装必要依赖
在 /web 目录内,执行如下命令:
language
npm install electron vite-plugin-electron electron-builder -D
# 或
yarn add electron vite-plugin-electron electron-builder -D
# 或
pnpm install electron vite-plugin-electron electron-builder -D
步骤 2:创建 Electron 主进程文件
新建 electron/main.ts 文件:
language
// 导入 Electron 的 app 和 BrowserWindow 模块
import { app, BrowserWindow, session } from 'electron'
// 创建浏览器窗口的函数
const createWindow = () => {
// 创建一个新的浏览器窗口
const win = new BrowserWindow({
width: 1200, // 窗口宽度
height: 800, // 窗口高度
webPreferences: {
// 网页功能设置
nodeIntegration: true, // 启用Node.js集成(允许在渲染进程中使用Node.js API)
contextIsolation: false, // 关闭上下文隔离(与nodeIntegration配合使用)
webSecurity: false, // 禁用web安全策略(允许跨域请求)
preload: 'preload.js', // 预加载脚本(在网页内容加载前运行)
},
})
// 删除窗口的菜单栏
win.removeMenu()
// 判断当前环境是开发还是生产
if (process.env.VITE_DEV_SERVER_URL) {
// 开发模式:加载Vite开发服务器提供的URL
win.loadURL(process.env.VITE_DEV_SERVER_URL)
// 打开开发者工具(调试窗口)
win.webContents.openDevTools()
} else {
// 生产模式:加载本地打包的HTML文件
win.loadFile('index.html')
}
}
// 当Electron完成初始化后执行
app.whenReady().then(() => {
// 获取应用程序的主会话对象
const mainSession = session.defaultSession
// 注册一个网络请求拦截器,在请求发出前进行处理
mainSession.webRequest.onBeforeRequest(
// 配置选项:拦截所有URL(空数组表示匹配所有URL)
{ urls: [] },
(details, callback) => {
// 检查请求URL是否以'file://'开头但不是'file:///'(即非标准本地文件路径)
if (details.url.startsWith('file://') && !details.url.startsWith('file:///')) {
// 从环境变量获取基础URL(通常由Vite注入)
const fullUrl = import.meta.env.VITE_AXIOS_BASE_URL
// 将基础URL解析为URL对象以便获取协议部分
const urlObj = new URL(fullUrl)
// 替换原URL中的'file:'协议为环境变量中的协议(如http:或https:)
const newUrl = details.url.replace('file:', urlObj.protocol)
// 执行回调进行重定向
return callback({ redirectURL: newUrl })
}
// 对于不符合条件的请求,正常放行
return callback({})
}
)
// 创建主窗口
createWindow()
// macOS特有行为:当应用被激活但没有窗口时创建新窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
// 监听所有窗口关闭事件(仅限macOS不退出应用)
app.on('window-all-closed', () => {
// 非macOS平台(如Windows/Linux)直接退出应用
if (process.platform !== 'darwin') {
app.quit()
}
})
步骤 3:创建预加载脚本(可选)
新建 electron/preload.ts 文件:
language
步骤 4:创建 vite 插件
新建 plugins/vite.electron.build.ts 文件:
language
import type { Plugin } from 'vite'
import path from 'path'
import fs from 'fs'
/**
* Vite 插件:为 Electron 构建优化
* 在构建完成后执行以下操作:
* 1. 修改 package.json 的入口文件为 'main.js'
* 2. 将修改后的 package.json 写入到 dist 目录
* 3. 在 dist 目录创建 node_modules 空目录(Electron 应用需要)
*/
export const viteElectronBuild = (): Plugin => {
return {
// 插件名称
name: 'vite-electron-build',
/**
* Vite 构建完成时的钩子函数
* 在打包结束后自动执行
*/
closeBundle: () => {
// 读取项目根目录的 package.json
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'))
// 构建精简版 package.json
const distPkg: Record<string, string> = {
name: packageJson.name,
version: packageJson.version,
main: 'main.js', // Electron 入口文件
}
if (packageJson.description) {
distPkg.description = packageJson.description
}
if (packageJson.author) {
distPkg.author = packageJson.author
}
if (packageJson.homepage) {
distPkg.homepage = packageJson.homepage
}
// 将修改后的 package.json 写入到 dist 目录
const distPackagePath = 'dist/package.json'
fs.writeSync(
fs.openSync(distPackagePath, 'w'), // 同步打开/创建文件
JSON.stringify(distPkg, null, 2) // 带缩进的格式化输出
)
// 在 dist 目录创建 node_modules 文件夹
// (某些 Electron 应用依赖此目录结构)
const nodeModulesPath = path.join(process.cwd(), 'dist/node_modules')
fs.mkdirSync(nodeModulesPath)
},
}
}
步骤 5:创建 Electron 打包配置文件
新建 electron-builder.json 文件:
language
{
"appId": "com.buildadmin.app",
"productName": "BuildAdmin",
"directories": {
"output": "release",
"app": "dist"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
"electronDownload": {
"mirror": "https://npmmirror.com/mirrors/electron/"
},
"asar": true,
"win": {
"target": "nsis",
"icon": "public/favicon.ico"
},
"mac": {
"target": "dmg",
"icon": "public/favicon.png"
},
"linux": {
"target": "AppImage",
"icon": "public/favicon.png"
}
}
步骤 6:配置 Vite 插件
在 vite.config.ts 中添加 Electron 插件:
language
import electron from 'vite-plugin-electron'
import { viteElectronBuild } from './plugins/vite.electron.build'
plugins: [
vue(),
// 在此处新增 electron viteElectronBuild
electron([
{
entry: 'electron/main.ts',
vite: { build: { outDir: 'dist' } },
},
{
entry: 'electron/preload.ts',
vite: { build: { outDir: 'dist' } },
},
]),
viteElectronBuild(),
svgBuilder('./src/assets/icons/'),
customHotUpdate(),
],
步骤 7:修改 package.json
添加 Electron 构建配置:
language
{
"main": "dist/main.js",
"scripts": {
"build": "vite build && esno ./src/utils/build.ts && electron-builder",
}
}
步骤 8:修改 .env.production
将原来的 '/' 改为 './'
language
# base路径
VITE_BASE_PATH = './'
步骤 9:运行与构建
开发模式:
language
npm run dev
生产构建:
language
npm run build
最终项目结构
language
web/
├── electron/
│ ├── main.ts # Electron 主进程
│ └── preload.ts # 预加载脚本
├── plugins/
│ └── vite.electron.build.ts # Vite 插件
├── release/ # Electron 编译目录
├── src/ # BuildAdmin 源码
├── .env.production # 生产环境变量定义
├── electron-builder.json # Electron 打包配置
├── package.json
└── vite.config.ts # Vite 配置
需要解决两个关键点:
1. 生产模式下,由于使用
win.loadFile('index.html')
可能导致以 "//" 开头的协议(即相对协议)被解析为file://
,从而引起头像等资源加载失败(因为头像是http/https资源)可以改用
win.loadURL(import.meta.env.VITE_AXIOS_BASE_URL)
或者在 BuildAdmin 框架需要修改的页面中使用fullUrl()
补全协议
2. public 目录下的 favicon.ico 尺寸要求:必须为 256x256 像素
当执行 npm install 或类似命令安装 Electron 时,常见以下错误提示:
language
Electron failed to install correctly, please delete node_modules/electron and try installing again
或卡在 node install.js 步骤长时间不动。这通常是由于 node_modules/electron 目录中的文件丢失或损坏导致程序无法正常执行。
解决方案:使用 electron-fix 工具
language
# 1. 首先正常安装项目依赖
npm install
# 2. 全局安装 electron-fix 工具
npm install -g electron-fix
# 3. 在项目根目录执行修复
electron-fix start
# 4. 重新运行项目
npm run dev
感谢分享~
- 1
前往