作为一名长期奋战在前端一线的开发者,我深知现代前端技术的边界正在不断扩展。Electron的出现彻底打破了Web与桌面应用的次元壁,让我们熟悉的HTML、CSS和JavaScript技术栈能够直接用于构建跨平台的桌面应用程序。你可能已经注意到,VS Code、Slack、Figma等知名应用都是基于Electron构建的——这充分证明了它的生产级可靠性。
传统桌面开发需要掌握C++/C#等系统级语言,学习曲线陡峭。而Electron将Chromium渲染引擎和Node.js运行时完美结合,让我们能够:
vite-electron-builder这个开源模板完美整合了现代前端开发的最佳实践:
这种组合解决了传统Electron开发中的几个痛点:
bash复制# 使用degit快速克隆模板(比git clone更轻量)
npx degit cawa-93/vite-electron-builder my-electron-app
# 进入项目目录
cd my-electron-app
# 安装依赖
npm install
注意:如果遇到依赖安装问题,可以尝试删除node_modules和package-lock.json后重新安装。国内用户建议配置淘宝镜像源。
code复制my-electron-app/
├── src/
│ ├── main/ # Electron主进程代码
│ ├── renderer/ # 前端渲染进程代码
│ └── preload/ # 安全通信桥接脚本
├── build/ # 构建配置
├── dist/ # 打包输出目录
└── vite.config.ts # Vite配置
bash复制npm start
这个命令实际上同时启动了:
开发时你会看到两个窗口:
在src/main/main.ts中扩展Electron API:
typescript复制import { ipcMain } from 'electron'
// 暴露文件系统操作
ipcMain.handle('read-file', async (_, path) => {
return await fs.promises.readFile(path, 'utf-8')
})
在预加载脚本中安全暴露API:
typescript复制// src/preload/index.ts
contextBridge.exposeInMainWorld('electronAPI', {
readFile: (path: string) => ipcRenderer.invoke('read-file', path)
})
在前端组件中使用:
typescript复制const content = await window.electronAPI.readFile('/path/to/file.txt')
模板默认支持Vue,但可以轻松添加React:
bash复制npm install @vitejs/plugin-react
然后修改vite.config.ts:
typescript复制import react from '@vitejs/plugin-react'
export default {
plugins: [
react(),
// 其他插件...
]
}
bash复制npm run compile
这个命令会:
在package.json中配置electron-builder:
json复制"build": {
"appId": "com.example.myapp",
"productName": "My Electron App",
"copyright": "Copyright © 2023",
"mac": {
"category": "public.app-category.developer-tools"
},
"win": {
"target": ["nsis", "portable"]
},
"linux": {
"target": ["AppImage", "deb"]
}
}
typescript复制const HeavyComponent = defineAsyncComponent(() =>
import('./components/HeavyComponent.vue')
)
typescript复制optimizeDeps: {
exclude: ['sqlite3'] // 排除需要原生编译的模块
}
问题1:require is not defined
问题2:打包后资源加载失败
process.resourcesPath获取正确路径问题3:跨平台样式差异
css复制/* 在渲染进程中 */
:root {
--platform-font: system-ui;
}
body {
font-family: var(--platform-font);
}
json复制{
"type": "node",
"request": "launch",
"name": "Electron Main",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"args": ["."]
}
bash复制npm install electron-updater
typescript复制import { autoUpdater } from 'electron-updater'
autoUpdater.checkForUpdatesAndNotify()
typescript复制autoUpdater.on('update-downloaded', () => {
dialog.showMessageBox({
type: 'info',
buttons: ['重启安装', '稍后'],
message: '新版本已下载',
detail: '重启应用以完成更新'
}).then(({ response }) => {
if (response === 0) autoUpdater.quitAndInstall()
})
})
以SQLite为例:
bash复制npm install sqlite3
typescript复制contextBridge.exposeInMainWorld('database', {
query: (sql: string) => ipcRenderer.invoke('database-query', sql)
})
typescript复制import sqlite3 from 'sqlite3'
ipcMain.handle('database-query', async (_, sql) => {
const db = new sqlite3.Database('app.db')
return new Promise((resolve, reject) => {
db.all(sql, (err, rows) => {
if (err) reject(err)
else resolve(rows)
db.close()
})
})
})
创建新窗口的推荐方式:
typescript复制function createSettingsWindow() {
const win = new BrowserWindow({
width: 600,
height: 400,
webPreferences: {
preload: path.join(__dirname, '../preload/index.js')
}
})
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:3000/settings')
win.webContents.openDevTools()
} else {
win.loadFile(path.join(__dirname, '../renderer/settings.html'))
}
return win
}
在实际项目中,我发现这套技术栈特别适合需要快速迭代的中小型桌面应用开发。相比传统Electron开发,Vite带来的开发体验提升是革命性的——修改代码后几乎能立即看到变化,这大大提高了开发效率。electron-builder的打包配置虽然一开始看起来复杂,但一旦掌握就能轻松应对各种分发需求。