Electron是一个跨平台的桌面应用程序开发框架,它允许开发人员使用Web技术(如HTML、CSS和JavaScript)构建桌面应用程序,这些应用程序可以在Windows、macOS和Linux等操作系统上运行。
Electron的核心是Chromium浏览器内核和Node.js运行时环境。Chromium内核提供了现代浏览器的功能,例如HTML5和CSS3支持,JavaScript引擎等,而Node.js运行时环境则提供了服务器端JavaScript的能力和模块系统,这使得开发人员可以使用Node.js的模块和工具来构建桌面应用程序。
许多知名应用都是使用Electron构建的,例如Visual Studio Code、Atom和Postman。
要开始一个Electron项目,我们可以结合Vue和Vite。首先,创建Vue项目并安装相关依赖:
npm init vue
npm install
npm install electron electron-builder -D
如果安装过程中出现超时问题,可以配置镜像源来加速下载。
为了在开发时能够同时启动Vite开发服务器和Electron应用,而不是分别启动两次,我们可以创建自定义的Vite插件。在项目根目录创建一个plugins文件夹,并编写以下文件:
plugins/vite.electron.dev.ts:用于开发模式启动Electron。plugins/vite.electron.build.ts:用于打包Electron项目。
首先,需要创建Electron的主进程文件src/background.ts:
import { app, BrowserWindow } from 'electron'
app.whenReady().then(async () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webSecurity: false,
}
})
if (process.argv[2]) {
win.loadURL(process.argv[2])
} else {
win.loadFile('index.html')
}
})
这段代码创建了一个基本的Electron窗口,并根据命令行参数加载URL或本地文件。在开发模式下,通过传递URL参数可以连接到Vite开发服务器,实现热更新。
接下来,在vite.electron.dev.ts中编写开发插件:
import type { Plugin } from 'vite'
import type { AddressInfo } from 'net'
import { spawn } from 'child_process'
import fs from 'fs'
export const viteElectronDev = (): Plugin => {
return {
name: 'vite-electron-dev',
configureServer(server) {
const initElectron = () => {
require('esbuild').buildSync({
entryPoints: ['src/background.ts'],
bundle: true,
outfile: 'dist/background.js',
platform: 'node',
target: 'node12',
external: ['electron']
})
}
initElectron()
server?.httpServer?.once('listening', () => {
const addressInfo = server?.httpServer?.address() as AddressInfo
const IP = `http://localhost:${addressInfo.port}`
let electronProcess = spawn(require('electron'), ['dist/background.js', IP])
fs.watchFile('src/background.ts', () => {
electronProcess.kill()
initElectron()
electronProcess = spawn(require('electron'), ['dist/background.js', IP])
})
electronProcess.stdout?.on('data', (data) => {
console.log(`日志: ${data}`)
})
})
}
}
}
这个插件在Vite开发服务器启动时,使用esbuild编译TypeScript主进程代码,然后启动Electron进程。它还监听background.ts文件的变化,实现热重载。
对于生产打包,创建vite.electron.build.ts插件:
import type { Plugin } from 'vite'
import * as electronBuilder from 'electron-builder'
import path from 'path'
import fs from 'fs'
export const viteElectronBuild = (): Plugin => {
return {
name: 'vite-electron-build',
closeBundle() {
const initElectron = () => {
require('esbuild').buildSync({
entryPoints: ['src/background.ts'],
bundle: true,
outfile: 'dist/background.js',
platform: 'node',
target: 'node12',
external: ['electron'],
})
}
initElectron()
const json = JSON.parse(fs.readFileSync('package.json', 'utf-8'))
json.main = 'background.js'
fs.writeSync(fs.openSync('dist/package.json', 'w'), JSON.stringify(json, null, 2))
fs.mkdirSync(path.join(process.cwd(), "dist/node_modules"))
electronBuilder.build({
config: {
appId: 'com.example.app',
productName: 'vite-electron',
directories: {
output: path.join(process.cwd(), "release"),
app: path.join(process.cwd(), "dist"),
},
asar: true,
nsis: {
oneClick: false,
}
}
})
}
}
}
这个插件在Vite构建完成后触发,先编译主进程代码,然后修改package.json的main字段,并创建必要的目录,最后使用electron-builder进行打包。
最后,在vite.config.ts中配置这些插件:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteElectronDev } from './plugins/vite.electron.dev'
import { viteElectronBuild } from './plugins/vite.electron.build'
export default defineConfig({
plugins: [
vue(),
viteElectronDev(),
viteElectronBuild()
],
base: './',
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
通过以上配置,我们实现了一个集成Vite和Electron的完整开发环境,支持开发时的热更新和生产打包。