English | 中文
非常感谢 caoxiemeihao 的 vite-plugin-electron 和 Doubleshotjs 的 doubleshot 这两个优秀库给了我启发。我希望使用它能简化开发配置,只关注业务开发。
- 使用 tsup 快速构建
main
和preload
- 配置简单,专注业务
- 支持
main
的热重启
- 支持
preload
的热重载
- 支持
esm
和cjs
,你可以在 electron v28+ 中使用esm
- 支持
vue
和react
等其他vite
支持的框架 - 可选 electron-builder 简单配置打包
# pnpm
pnpm add @tomjs/vite-plugin-electron -D
# yarn
yarn add @tomjs/vite-plugin-electron -D
# npm
npm i @tomjs/vite-plugin-electron --save-dev
如果使用 builder
打包应用,请安装 electron-builder
# pnpm
pnpm add electron-builder -D
# yarn
yarn add electron-builder -D
# npm
npm i electron-builder --save-dev
- 推荐
electron
和 页面src
代码目录结构
|--electron
| |--main // main process code
| | |--index.ts
| |--preload // preload process code
| | |--index.ts
| |--build // electron-builder resources for electron package
| | |--icons
|--src // front-end code
| |--App.vue
| |--main.ts
- 零配置,默认 dist 输出目录
|--dist
| |--main
| | |--index.js
| | |--index.js.map
| |--preload
| | |--index.js
| | |--index.js.map
| |--renderer
| | |--index.html
详细查看 PluginOptions 和 recommended
参数说明
electron/main/index.ts
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { app, BrowserWindow } from 'electron';
// when package.json "type": module"
global.__dirname = dirname(fileURLToPath(import.meta.url));
const preload = join(__dirname, '../preload/index.mjs');
const url = process.env.VITE_DEV_SERVER_URL;
async function createWindow() {
win = new BrowserWindow({
title: 'Main window',
width: 800,
height: 700,
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false,
},
});
if (isDev) {
win.loadURL(url);
} else {
win.loadFile(indexHtml);
}
}
app.whenReady().then(createWindow);
以使用 esm
为例,不过要求 Electron>=28
package.json
Electron preload process
必须使用 .mjs
后缀,否则报错,查看官方文档。所以 preload
的 esm
默认输出使用 mjs
后缀。为了保持一致性,main process
也以 .mjs
结尾。
{
"type": "module",
"main": "dist/main/index.mjs"
}
vite.config.ts
import { defineConfig } from 'vite';
// import renderer from 'vite-plugin-electron-renderer'; // 启用 nodeIntegration
import electron from '@tomjs/vite-plugin-electron';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
vue(),
// 如使用约定的目录结构,则不需要配置
electron(),
// 如果自定义了目录结构,则必须根据实际情况赋值
// electron({
// main: {
// entry: 'electron/main/index.ts',
// },
// preload: {
// entry: 'electron/preload/index.ts',
// },
// }),
// renderer(),
],
});
以使用 cjs
为例
package.json
{
// "type": "commonjs",
"main": "dist/main/index.js"
}
vite.config.ts
import { defineConfig } from 'vite';
import electron from '@tomjs/vite-plugin-electron';
import react from '@vitejs/plugin-react-swc';
export default defineConfig({
plugins: [react(), electron()],
});
- unpkg.com 提供的 index.d.ts.
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
recommended | boolean |
true |
这个选项是为了提供推荐的默认参数和行为 |
external | string[] |
不打包这些模块,但是 dependencies and peerDependencies 默认排除,详见 |
|
main | MainOptions | electron main 进程选项 | |
preload | PreloadOptions | electron preload 进程选项 | |
debug | boolean |
false |
Electron调试模式,不启动Electron。 您还可以使用 process.env.VITE_ELECTRON_DEBUG |
builder | boolean |
false |
如果是boolean 类型,是否启用electron-builder。如果是Object ,则是electron-builder的配置。 您还可以使用 process.env.VITE_ELECTRON_DEBUG 开启它。 |
inspect | boolean |
false |
Electron 将监听指定 port 上的 V8 调试协议消息, 外部调试器需要连接到此端口上。您还可以使用 process.env.VITE_ELECTRON_INSPECT 。 有关更多信息,请参阅debugging-main-process。 |
recommended
选项用于设置默认配置和行为,几乎可以达到零配置使用,默认为 true
。如果你要自定义配置,请设置它为false
。以下默认的前提条件是使用推荐的 项目结构。
- 检查是否存在
electron/main/index.ts
和electron/main/index.ts
,如果有则分别给main.entry
和preload.entry
赋值。如果不存在,main.entry
必须主动赋值,负责会报错 - 输出目录根据
vite
的build.outDir
参数, 将electron/main
、electron/preload
、src
分别输出到dist/main
、dist/preload
、dist/renderer
- 其他待实现的行为
继承自 tsup 的 Options,添加了一些默认值,方便使用。
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
entry | string |
- |
main 入口文件 |
format | 'cjs' | 'esm' |
- |
打包格式。如果未指定,将使用 package.json 中的 "type" 字段 |
outDir | string |
"dist-electron/main" |
main 输出文件夹 |
onSuccess | () => Promise<void | undefined | (() => void | Promise<void>)> |
undefined |
构建成功后运行的回调函数 |
继承自 tsup 的 Options,添加了一些默认值,方便使用。
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
entry | string |
- |
preload 入口文件 |
format | 'cjs' | 'esm' |
- |
打包格式。如果未指定,将使用 package.json 中的 "type" 字段 |
outDir | string |
"dist-electron/preload" |
preload 输出文件夹 |
onSuccess | () => Promise<void | undefined | (() => void | Promise<void>)> |
undefined |
构建成功后运行的回调函数 |
当 recommended
和 builder.enable
都为 true
时,使用 electron-builder 打包 Electron 应用程序。
- 在vite中配置的
build.outDir
目录中,根据配置和package.json生成新的package.json,排除非依赖项。 - 执行
npm install
然后打包。
不适合所有人使用。
使用该功能,需要额外安装 electron-builder
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
appId | string |
"com.electron.${name}" |
应用程序 ID。详细 |
productName | string |
`` | 应用程序名称。详细 |
builderConfig | Configuration | undefined |
electron-builder 的 Configuration |
默认配置如下
const config = {
directories: {
buildResources: 'electron/build',
app: path.dirname(resolvedConfig.build.outDir),
output: 'release/${version}',
},
files: ['main', 'preload', 'renderer'],
artifactName: '${productName}-${version}-${os}-${arch}.${ext}',
electronDownload: {
// when npm registry mirror is 'registry.npmmirror.com'
mirror: 'https://npmmirror.com/mirrors/electron',
},
electronLanguages: ['zh-CN', 'en-US'],
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
},
],
},
mac: {
target: ['dmg'],
},
linux: {
target: ['zip'],
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
deleteAppDataOnUninstall: false,
},
};
main
和preload
未配置相关参数时的默认值
参数 | 开发模式默认值 | 生产模式默认值 |
---|---|---|
sourcemap | true |
false |
minify | false |
true |
变量 | 描述 |
---|---|
VITE_ELECTRON_DEBUG |
Electron主进程调试,不要启动Electron。 当值为 true 或 1 时启用,为 false 或 0 时禁用。默认值未定义。 |
VITE_ELECTRON_INSPECT |
Electron 将在指定端口上侦听 V8 检查器协议消息,外部调试器需要连接到该端口。 当值为 true 时,默认端口为 5858。 |
VITE_ELECTRON_BUILDER |
启用 Electron-builder 进行打包。 当值为 true 或 1 时启用,为 false 或 0 时禁用。 默认值未定义。 |
Electron main process
和 renderer process
使用。
变量 | 描述 |
---|---|
VITE_DEV_SERVER_URL |
Vite 开发服务器的 URL |
使用 @tomjs/electron-devtools-installer 安装 Chrome Devtools
插件后像 Web 开发一样使用
import { app } from 'electron';
app.whenReady().then(() => {
const { installExtension, REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } = await import(
'@tomjs/electron-devtools-installer'
);
installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS])
.then(exts => {
console.log(
'Added Extension: ',
exts.map(s => s.name),
);
})
.catch(err => {
console.log('Failed to install extensions');
console.error(err);
});
});
通过 vscode
运行 Debug Main Process
调试主线程,调试工具参考 官方文档
launch.json
配置如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Main Process",
"preLaunchTask": "npm:debug",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": ["."],
"outFiles": [
"${workspaceFolder}/**/*.js",
"${workspaceFolder}/**/*.cjs",
"${workspaceFolder}/**/*.mjs",
"!**/node_modules/**"
],
"envFile": "${workspaceFolder}/node_modules/@tomjs/vite-plugin-electron/debug/.env"
}
]
}
tasks.json
配置如下:
{
"version": "2.0.0",
"tasks": [
{
"label": "npm:debug",
"type": "npm",
"script": "debug",
"detail": "cross-env VITE_ELECTRON_DEBUG=1 vite",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"fileLocation": "relative",
"pattern": {
"regexp": "^([a-zA-Z]\\:/?([\\w\\-]/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
"file": 1,
"line": 3,
"column": 4,
"code": 5,
"message": 6
},
"background": {
"activeOnStart": true,
"beginsPattern": "^.*VITE v.* ready in \\d* ms.*$",
"endsPattern": "^.*\\[tomjs:electron\\] startup electron*$"
}
}
}
]
}
使用 DevTools
调试 preload process
.
先执行以下命令安装依赖,并生成库文件:
pnpm install
pnpm build
打开 examples 目录,有 vue
和 react
示例。