Vue + Electron 跨平台打包完整指南

1. 配置文件说明

1.1 package.json 配置详解

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
{
// Electron 主进程入口文件
"main": "dist-electron/main.js",

// 构建命令配置
"scripts": {
// 开发相关命令
"dev": "ELECTRON_DISABLE=true vite dev", // 纯前端开发模式
"electron:dev": "vite dev & electron .", // Electron 开发模式

// 构建相关命令
"build": "vue-tsc && vite build", // 基础构建
"build:mac": "npm run build && electron-builder --mac --config.mac.identity=null", // 仅构建 Mac
"build:win": "npm run build && electron-builder --win --config.win.artifactName=${productName}-win.${ext}", // 仅构建 Windows
"build:all": "npm run build && electron-builder -mw" // 构建所有平台
},

// Electron Builder 配置
"build": {
"appId": "com.yourapp.id", // 应用唯一标识
"productName": "Your App Name", // 应用名称
"directories": {
"output": "release", // 输出目录
"buildResources": "resources" // 构建资源目录
},
"files": [ // 需要打包的文件
"dist/**/*", // 前端构建输出
"dist-electron/**/*" // Electron 构建输出
],
"extraResources": [ // 额外资源文件配置
{
"from": "dist", // 源目录
"to": "app/dist" // 目标目录
}
],

// macOS 特定配置
"mac": {
"target": ["dmg"], // 输出格式
"category": "public.app-category.productivity", // App Store 分类
"identity": null, // 签名配置,null 表示不签名
"hardenedRuntime": false, // 是否启用强化运行时
"icon": "public/logo.ico" // 应用图标
},

// Windows 特定配置
"win": {
"target": [ // 构建目标
{
"target": "nsis", // 使用 NSIS 安装程序
"arch": ["x64"] // 64位架构
}
],
"icon": "public/logo.ico", // 应用图标
"requestedExecutionLevel": "asInvoker" // 程序权限级别
},

// NSIS 安装程序配置
"nsis": {
"oneClick": false, // 是否一键安装
"allowToChangeInstallationDirectory": true, // 允许更改安装目录
"createDesktopShortcut": true, // 创建桌面快捷方式
"createStartMenuShortcut": true, // 创建开始菜单快捷方式
"shortcutName": "Your App Name" // 快捷方式名称
},

"asar": true, // 是否将源代码打包成 asar 文件
"electronVersion": "^29.1.0" // Electron 版本
}
}

1.2 electron/main.ts 配置详解

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
import { app, BrowserWindow, globalShortcut } from 'electron'
import path from 'path'

function createWindow() {
// Enable remote module
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true'
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webSecurity: false,
devTools: true
}
})

// In development, load from Vite dev server
// In production, load from dist directory
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:5173')
} else {
win.loadFile(path.join(app.getAppPath(), 'dist/index.html'))
}

// Always enable DevTools in both dev and prod
win.webContents.openDevTools()

// Register DevTools toggle shortcut for both dev and prod
globalShortcut.register('CommandOrControl+Shift+I', () => {
win.webContents.toggleDevTools()
})

// Register reload shortcut
globalShortcut.register('CommandOrControl+R', () => {
win.reload()
})

return win
}

app.whenReady().then(() => {
const mainWindow = createWindow()

// Enable keyboard shortcuts
globalShortcut.register('CommandOrControl+R', () => {
mainWindow.reload()
})

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

1.3 vite.config.ts 配置详解

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
76
77
78
79
80
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import electron from 'vite-plugin-electron'
import renderer from 'vite-plugin-electron-renderer'
import path from 'path'
import tailwindcss from 'tailwindcss'
import autoprefixer from 'autoprefixer'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
// 下面的命令是防止npm run dev时一并把electron:win启动了
...(!process.env.ELECTRON_DISABLE ? [
electron({
entry: 'electron/main.ts',
}),
renderer(),
] : []),
],
base: './',
build: {
outDir: 'dist',
emptyOutDir: true,
rollupOptions: {
output: {
format: 'cjs',
chunkFileNames: '[name].[hash].js',
assetFileNames: '[name].[hash].[ext]',
entryFileNames: '[name].js',
inlineDynamicImports: true
}
},
target: 'esnext',
minify: true,
sourcemap: true
},
server: {
host: '0.0.0.0',
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
'/ask_fake_news': {
target: 'http://localhost:8000/ask_fake_news',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/ask_fake_news/, ""),
}
}
},
css: {
postcss: {
plugins: [
tailwindcss,
autoprefixer,
],
},
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
optimizeDeps: {
exclude: ['electron']
}
})

2. 打包命令使用

2.1 开发模式

1
2
# 启动开发服务器
npm run electron:dev

2.2 生产构建

1
2
3
4
5
6
7
8
# Mac 构建
npm run build:mac

# Windows 构建
npm run build:win

# 所有平台构建
npm run build:all

2.3 代理设置(如需要)

1
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

3. 常见问题解决

3.1 白屏问题

  1. 检查路径配置:

    • vite.config.ts 中 base: './'
    • main.ts 中路径使用 path.join()
  2. 配置网页安全性:

    1
    2
    3
    4
    5
    webPreferences: {
    nodeIntegration: true,
    contextIsolation: false,
    webSecurity: false
    }

3.2 开发工具问题

注意之前由于loadFile错误导致无法启动开发工具,并不是本身代码的问题

  1. 确保配置:

    1
    2
    3
    webPreferences: {
    devTools: true
    }
  2. 注册快捷键:

    1
    2
    3
    globalShortcut.register('CommandOrControl+Shift+I', () => {
    win.webContents.toggleDevTools()
    })

3.3 跨平台构建注意事项

  1. macOS:

    • 签名配置:"identity": null
    • DMG 格式:"target": ["dmg"]
  2. Windows:

    • NSIS 配置:"oneClick": false

    • 权限级别:"requestedExecutionLevel": "asInvoker"

    • 下载 NSIS 资源时遇到了网络问题,可以使用下面的命令,再执行build命令,当然可能只是当时网络波动了

      1
      sudo rm -rf node_modules/.cache/electron-builder &&sudo  rm -rf release 
  3. 通用:

    • 使用相对路径
    • 处理资源文件
    • 错误处理机制

3.4 模块加载错误解决

具体报错:Uncaught ReferenceError: exports is not defined at index-BF1qxaNs.js:1:36,然后页面依旧是白屏

  1. package.json 中移除 “type”: “module”
  2. 使用 CommonJS 格式构建
  3. 确保所有路径使用相对路径

4. 最佳实践

  1. 文件组织
    1
    2
    3
    4
    5
    project/
    ├── electron/ # Electron 主进程代码
    ├── src/ # 渲染进程代码(Vue)
    ├── dist/ # 构建输出
    └── release/ # 打包输出