vite-plugin-electron
v1.0.4
Published
Electron ð Vite
Readme
vite-plugin-electron
English | ç®äœäžæ
ç®èèšä¹ïŒvite-plugin-electron 让åŒå Electron åºçšåæ®é Vite 项ç®äžæ ·ç®åã
[!important] æ¬æä»¶åæ¶æ¯æ Vite 7 å Vite 8ã æå»ºé 眮äŒèªåšéé ïŒVite 8+ 䜿çš
rolldownOptionsïŒVite < 8 䜿çšrollupOptionsã
ä» 0.x è¿ç§»ïŒè¯Šç»è¿ç§»æå请åè§ Migrate to v1ã
ç¹æ§
- ð± äž Vite åå ¶çæå®å šå Œå®¹ (åºäº Vite)
- ð® 宿Žç JavaScript APIïŒåŸéåå倿项ç®éæã
- ð£ API å°ïŒäžæç®å
å¿«éåŒå§
- åšé¡¹ç®äžæ·»å äžé¢çäŸèµ
npm i -D vite-plugin-electron- æ
vite-plugin-electronå å°vite.config.tsçpluginsé 眮é
import electron from 'vite-plugin-electron/simple'
export default {
plugins: [
electron({
main: {
// Shortcut of `build.lib.entry`
entry: 'electron/main.ts',
},
preload: {
// Shortcut of `build.rolldownOptions.input` (`build.rollupOptions.input` on Vite < 8)
input: 'electron/preload.ts',
},
// Optional: Use Node.js API in the Renderer process
renderer: {},
}),
],
}- å建
electron/main.tsæä»¶ïŒå¹¶åå ¥äžé¢ç代ç
import { app, BrowserWindow } from 'electron'
app.whenReady().then(() => {
const win = new BrowserWindow({
title: 'Main window',
})
// You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
if (process.env.VITE_DEV_SERVER_URL) {
win.loadURL(process.env.VITE_DEV_SERVER_URL)
} else {
// Load your file
win.loadFile('dist/index.html')
}
})- åš
package.jsonäžæ·»åmainå ¥å£
{
+ "main": "dist-electron/main.js"
}å°±æ¯è¿æ ·ïŒç°åšäœ å¯ä»¥åš Vite åºçšéäœ¿çš Electron äº âš
å·¥äœåç
æä»¶äŒåš Vite ç closeBundle() é©åéæ§è¡ electron . åœä»€ïŒç¶åå¯åšæéå¯ Electron Appã
- ðš é»è®€æ
åµäžïŒ
electronæä»¶å€¹äžçæä»¶äŒè¢«æå»ºå°dist-electronç®åœ
Flat API
倧倿°æ
åµäžïŒæšèäœ¿çš vite-plugin-electron/simple APIãåŠæäœ åŸäºè§£è¿äžªæä»¶çå·¥äœæ¹åŒïŒæè
æ³æ vite-plugin-electron API äœäžºåºå± API çäºæ¬¡å°è£
ïŒé£ä¹ Flat API äŒæŽéåäœ ãå®åæ ·ç®åïŒäœæŽçµæŽ»ã:)
å simple API çžæ¯ïŒå®äžäŒèªåšè¯å«åªäžªå
¥å£ä»£è¡š preloadïŒä¹äžäŒèªåšéé
preloadã
import electron from 'vite-plugin-electron'
export default {
plugins: [
electron({
entry: 'electron/main.ts',
}),
],
}Flat API vs Simple API
- Simple API åºäº Flat API
- Simple API å å«äžäº preload èæ¬çé¢è®Ÿé 眮ã
- Flat API æäŸäºæŽéçšçäžäº APIïŒäœ å¯ä»¥çšå®åäºæ¬¡å°è£ ïŒæ¯åŠ nuxt-electronã
ç±»åå®ä¹
electron(options: ElectronOptions | ElectronOptions[])
export interface ElectronOptions {
/**
* Shortcut of `build.lib.entry`
*/
entry?: import('vite').LibraryOptions['entry']
vite?: import('vite').InlineConfig
/**
* Triggered when Vite is built every time -- `vite serve` command only.
*
* If this `onstart` is passed, Electron App will not start automatically.
* However, you can start Electron App via `startup` function.
*/
onstart?: (args: {
/**
* Electron App startup function.
* It will mount the Electron App child-process to `process.electronApp`.
*
* You can also set environment variables to control the Electron CLI flags.
* Supported env vars:
* - `REMOTE_DEBUGGING_PORT`
* - `ELECTRON_IGNORE_CERTIFICATE_ERRORS`
* - `ELECTRON_DISABLE_WEB_SECURITY`
* - `ELECTRON_INSPECT`
* - `ELECTRON_INSPECT_BRK`
*
* `1` or `true` turns a flag on, `0` or `false` turns it off, and any other non-empty
* value is appended as `=<value>`.
*
* @param argv default value `['.', '--no-sandbox']`
* @param options options for `child_process.spawn`
* @param customElectronPkg custom electron package name (default: 'electron')
* @returns `true` if the Electron app is started, or `false` if the startup is prevented by `startup.prevent` or `ELECTRON_STARTUP_PREVENT` env var.
*/
startup: (
argv?: string[],
options?: import('node:child_process').SpawnOptions,
customElectronPkg?: string,
) => Promise<boolean>
/** Reload Electron-Renderer */
reload: () => void
}) => void | Promise<void>
}Environment API
[!important]
vite-plugin-electron/multi-envä» åšvite-plugin-electron@>=1.0.0æäŸã0.xçæ¬æ²¡ææ€åèœã
äœ¿çš Vite ç Environment API æå»º Electron ç®æ ïŒèäžæ¯æåšè°çš build()ãè¿æ¯æªæ¥äž»æšçå€ç®æ æå»ºæ¹åŒïŒé
眮æŽç®æŽãæç»Žæ€ïŒVite 8+ çš rolldownOptions.inputïŒVite < 8 çš rollupOptions.inputïŒäžºæ¯äžªç®æ æå®å
¥å£åå¯èŠççç¯å¢é
眮ã
Flat APIïŒ
import electron from 'vite-plugin-electron/multi-env'
export default {
plugins: [
electron([
{
input: 'electron/main.ts',
},
{
input: 'electron/preload.ts',
},
]),
],
}Simple API:
import { electronSimple } from 'vite-plugin-electron/multi-env'
export default {
plugins: [
electronSimple({
main: {
input: 'electron/main.ts',
// åŒåæ¶å€éšå npm äŸèµïŒå Vite 对æµè§åšçè¡äžºäžæ ·ïŒ
// ç产æå»ºæ¶è¯¥é项äŒè¢«å¿œç¥ïŒææäŸèµéœäŒè¢«æå
notBundle: true,
options: {
define: {
__ELECTRON_TARGET__: JSON.stringify('main'),
},
},
},
preload: {
input: 'electron/preload.ts',
options: {
define: {
__ELECTRON_TARGET__: JSON.stringify('preload'),
},
},
},
// äœ ä¹å¯ä»¥æ·»å èªå®ä¹ç®æ ãå®ä»¬äŒåäž»è¿çšäžæ ·æå»ºïŒäœå¯ä»¥äœ¿çšäžåçç¯å¢åéã
custom: {
input: 'electron/custom.ts',
options: {
define: {
__ELECTRON_TARGET__: JSON.stringify('custom'),
},
},
},
}),
],
}electronSimple() æ¥åäžäžªä»¥ç¯å¢ååç»ç对象ãmain å preload äŒå€çš simple API çé»è®€é¢è®ŸïŒå
¶ä»èªå®ä¹ key äŒåäž»è¿çšäžæ ·æå»ºïŒå¹¶äœ¿çšåèªçç¯å¢é
眮ã
Factory çšæ³
åŠæäœ éèŠåšæè§£æ Electron ç®æ ïŒå¯ä»¥äœ¿çš electronPluginFactory()ãè¿äžªå·¥ååœæ°äŒæ¥æ¶è§£æåç root å packageJsonïŒå¹¶äžå¯ä»¥è¿åå䞪é项ãé项æ°ç»ïŒæè
è§£æäžºè¿äž€ç§åœ¢æä¹äžç Promiseã
import { electronPluginFactory } from 'vite-plugin-electron/multi-env'
export default {
plugins: [
electronPluginFactory(async ({ root, packageJson }) => {
const isESM = packageJson?.type === 'module'
return [
{
name: 'main',
input: 'electron/main.ts',
options: {
define: {
__APP_ROOT__: JSON.stringify(root),
},
},
},
{
name: 'preload',
input: 'electron/preload.ts',
options: {
build: {
minify: !isESM,
},
},
},
]
}),
],
}ç±»åå®ä¹
export interface MultiEnvElectronOptions {
/**
* Optional name for the Electron environment `electron_${name}`.
*
* By default, the plugin will generate environment names like `electron_0`,
* `electron_1`, etc. based on the order of the options provided.
*/
name?: string
/**
* Shortcut of `options.build.rolldownOptions.input` (`options.build.rollupOptions.input` on Vite < 8)
*/
input?: import('vite').BuildEnvironmentOptions['rolldownOptions']['input']
/**
* Shortcut of `options.build.rolldownOptions.plugins` (`options.build.rollupOptions.plugins` on Vite < 8)
*/
plugins?: import('vite').BuildEnvironmentOptions['rolldownOptions']['plugins']
/**
* Per-environment Vite options.
*/
options?: import('vite').EnvironmentOptions
/**
* 讟䞺 `true` æ¶ïŒåŒåé¶æ®µäŒå€éšå npm äŸèµïŒäžæå
å®ä»¬ïŒè¡äžºå Vite 对æµè§åšäžæ ·ã
*
* ä¹å¯ä»¥äŒ å
¥èªå®ä¹ç `external` åŒæ¥èŠçé»è®€ä» package.json çæçå€éšåéåã
*
* ç产æå»ºæ¶è¯¥é项äŒè¢«å¿œç¥ïŒææäŸèµéœäŒè¢«æå
ã
*
* @default false
*/
notBundle?: boolean | import('vite').BuildEnvironmentOptions['rolldownOptions']['external']
onstart?: ElectronOptions['onstart']
}
export interface ElectronFactoryContext {
root: string
packageJson?: PackageJson | null
}
export type MultiEnvElectronOptionsFactory = (
context: ElectronFactoryContext,
) =>
| MultiEnvElectronOptions
| MultiEnvElectronOptions[]
| Promise<MultiEnvElectronOptions | MultiEnvElectronOptions[]>çé蜜é¢å èœœèæ¬
ä» v0.29.0 åŒå§ïŒåœ preload èæ¬éæ°æå»ºæ¶ïŒå®ä»¬äŒåäž»è¿çšåéäžäžª electron-vite&type=hot-reload äºä»¶ã
åŠæäœ çåºçšäžéèŠæž²æè¿çšïŒè¿å°±å¯ä»¥å®ç° çé蜜ã
// electron/main.ts
process.on('message', (msg) => {
if (msg === 'electron-vite&type=hot-reload') {
for (const win of BrowserWindow.getAllWindows()) {
// çé蜜 preload èæ¬
win.webContents.reload()
}
}
})æšèç®åœç»æ
äžé¢ä»¥åºäº create vite ç宿¹ template-vanilla-ts æš¡æ¿äžºäŸã
+ ââ⬠electron
+ â âââ main.ts
ââ⬠src
â âââ main.ts
â âââ style.css
â âââ vite-env.d.ts
âââ .gitignore
âââ favicon.svg
âââ index.html
âââ package.json
âââ tsconfig.json
+ âââ vite.config.tsæå»ºæ ŒåŒ
è¿åªæ¯é»è®€è¡äžºïŒäœ å¯ä»¥éæ¶éè¿ vite.config.js éçèªå®ä¹é
眮æ¥ä¿®æ¹ã
{ "type": "module" }
ââââââââââââââââââââââ³âââââââââââ³ââââââââââââ
â built â format â suffix â
â ââââââââââââââââââââââââââââââââââââââââââââš
â main process â esm â .js â
â ââââââââââââââââââââââââââââââââââââââââââââš
â preload scripts â cjs â .mjs â diff
â ââââââââââââââââââââââââââââââââââââââââââââš
â renderer process â - â .js â
ââââââââââââââââââââââžâââââââââââžââââââââââââ
{ "type": "commonjs" } - default
ââââââââââââââââââââââ³âââââââââââ³ââââââââââââ
â built â format â suffix â
â ââââââââââââââââââââââââââââââââââââââââââââš
â main process â cjs â .js â
â ââââââââââââââââââââââââââââââââââââââââââââš
â preload scripts â cjs â .js â diff
â ââââââââââââââââââââââââââââââââââââââââââââš
â renderer process â - â .js â
ââââââââââââââââââââââžâââââââââââžââââââââââââ瀺äŸ
è¿éæåŸå€ç€ºäŸ ð electron-vite-samples
Playground
æ¬å°æŒç€ºå¥ä»¶äœäº playground/ïŒå å« flatãsimpleãmulti-env å worker æš¡åŒïŒå®ä»¬äŒçŽæ¥ä»è¿äžªä»åºå¯Œå ¥æä»¶æºç ã
JavaScript API
vite-plugin-electron ç JavaScript API éœæå®æŽç±»åä¿¡æ¯ïŒå»ºè®®äœ¿çš TypeScriptïŒæè
åš VS Code äžåŒå¯ JS ç±»åæ£æ¥ïŒä»¥äŸ¿äœ¿çšæºèœæç€ºåæ ¡éªã
ElectronOptions- ç±»åresolveViteConfig- åœæ°ïŒçšäºè§£ææå»º Electron Main çé»è®€ ViteInlineConfigwithExternalBuiltins- åœæ°build- åœæ°startup- åœæ°
瀺äŸ
import { build, startup } from 'vite-plugin-electron'
const isDev = process.env.NODE_ENV === 'development'
const isProd = process.env.NODE_ENV === 'production'
build({
entry: 'electron/main.ts',
vite: {
mode: process.env.NODE_ENV,
build: {
minify: isProd,
watch: isDev ? {} : null,
},
plugins: [
{
name: 'plugin-start-electron',
closeBundle() {
if (isDev) {
// Startup Electron App
startup()
}
},
},
],
},
})èªå®ä¹ Electron å è§£æ
startup(argv, options, customElectronPkg) æ¯æèªå®ä¹ Electron forkãæä»¶äŒäŒå
åšåºçšæ ¹ç®åœäžäžæäžè§£æè¯¥å
ïŒprocess.cwd()ãoptions.cwdãINIT_CWDïŒïŒç¶åååéå°æ åæš¡åè§£æã
åŠæä»ç¶æ æ³è§£æïŒstartup() äŒæåºé误ïŒå¹¶æç€ºå®è£
æ¹åŒææŸåŒäŒ å
¥å
åã
å¯åšç¯å¢åé
[!important] ç¯å¢åé ä» åš
vite-plugin-electron@>=1.0.0æäŸã0.xçæ¬æ²¡ææ€åèœã
startup() äŒè¯»åè¿äºç¯å¢åéã1 æ true 衚瀺åŒå¯ïŒ0 æ false 衚瀺å
³éïŒå
¶å®é空åŒäŒè¿œå 䞺 =<value>ã
REMOTE_DEBUGGING_PORT远å--remote-debugging-port=<value>ELECTRON_IGNORE_CERTIFICATE_ERRORS远å--ignore-certificate-errorsELECTRON_DISABLE_WEB_SECURITY远å--disable-web-securityELECTRON_INSPECT远å--inspectæ--inspect=<value>ELECTRON_INSPECT_BRK远å--inspect-brkæ--inspect-brk=<value>
å¯åšæ§å¶
[!important] å¯åšæ§å¶ ä» åš
vite-plugin-electron@>=1.0.0æäŸã0.xçæ¬æ²¡ææ€åèœã
å¯ä»¥äœ¿çš startup.prevent = true, ELECTRON_STARTUP_PREVENT=1, æ ELECTRON_STARTUP_PREVENT=true åšåŒåæéŽçŠçšèªåšå¯åšãè¿æ ·äœ å¯ä»¥æèªå·±çæ¶æºæåšè°çš startup.prevent = false; startup()ïŒäŸåŠå
çåŸ
æäžªæ¬å°æå¡å°±ç»ªïŒã
Await startup() çè¿ååŒå¯ä»¥ç¥éæ¯åŠè§Šåäºå¯åšïŒæè
被æ§å¶é项黿¢äºã
å 眮æä»¶
notBundle æä»¶
äœ¿çš notBundle() 䞺 Electron å
¥å£å€éšåäŸèµé¡¹ã
è¿éè¿åšè¿è¡ vite serve æ¶è·³è¿äŸèµæå
ïŒå¯ä»¥è®©å¯åšé床æŽå¿«ãç产æå»ºäžïŒå®ä»ç¶äŒå€éšåäŸèµïŒäœé»è®€éåæŽçªã
[!tip] æ£åšäœ¿çš
vite-plugin-electron/multi-envïŒ å¯ä»¥çŽæ¥åšMultiEnvElectronOptionsäžäœ¿çšå 眮çnotBundle: trueéé¡¹ïŒæ éåç¬å¯Œå ¥æä»¶ïŒimport { electronSimple } from 'vite-plugin-electron/multi-env' electronSimple({ main: { input: 'electron/main.ts', notBundle: true, // â å çœ®å¿«æ·æ¹åŒ }, })讟䞺
trueæ¶ïŒåŒåé¶æ®µäŒæ ¹æ®package.jsonå€éšå npm äŸèµã ä¹å¯ä»¥äŒ å ¥èªå®ä¹externalåŒïŒåŠnotBundle: ['lodash']ïŒæ¥èŠçé»è®€éåã
[!important]
v1.0.0è¡äžºåæŽïŒ
notBundle()ç°åšäŒåš config é¶æ®µæ ¹æ®package.jsonäžæ¬¡æ§é 眮build.rolldownOptions.externalïŒVite < 8 䞺build.rollupOptions.externalïŒïŒäžååšæ¯æ¬¡resolveIdæ¶æ ¡éªæ¯äžª import æ¯åŠå¯è¢«require()å 蜜ãdependencies/devDependencies/peerDependencies/optionalDependenciesäžååºçå éœäŒè¢«æ æ¡ä»¶å€éšåãåŠææäžªå åšè¿è¡æ¶çŒºå€±ïŒé误äŒåšè¿è¡æ¶æåºïŒèäžäŒè¢«é»é»æå è¿æ¥ãå¯ä»¥äœ¿çšfilteré项æ¶çªæèŠçå€éšåèåŽã- é»è®€ external éååšåŒåé¶æ®µæŽå®œïŒ
dependenciesãdevDependenciesãpeerDependenciesåoptionalDependencieséœäŒè¢«å€éšåïŒçäº§é¶æ®µåªå€éšådependenciesãå¯ä»¥äœ¿çšfilteræŸåŒèŠçéåã
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron'
import { notBundle } from 'vite-plugin-electron/plugin'
export default defineConfig({
plugins: [
electron({
entry: 'electron/main.ts',
vite: {
plugins: [notBundle()],
},
}),
],
})åç诎æ
åš Vite 8+ äœ¿çš build.rolldownOptions.externalïŒVite < 8 äœ¿çš build.rollupOptions.externalïŒèªåšå€éšå package.json éçäŸèµã
API
notBundle(options?: NotBundleOptions)
export interface NotBundleOptions {
/**
* èŠç `build.rolldownOptions.external`ïŒVite < 8 䞺 `build.rollupOptions.external`ïŒã
*
* åŠææªæäŸïŒåŒåé¶æ®µäŒ externalize package.json äžç dependenciesãdevDependenciesãpeerDependenciesãoptionalDependenciesã
* çäº§é¶æ®µåª externalize dependenciesã
*
* åŠææäŸè¯¥é项ïŒå®äŒæ¿æ¢æ ¹æ® package.json èªåšçæçé»è®€ external éåã
*
* äœ¿çš `import { getIsViteDev } from 'vite-plugin-electron/plugin'` æ£æµæ¯åŠäžºåŒåé¶æ®µã
*/
filter?: RolldownOrRollupOptions['external']
}API: extractExternalDeps
é»è®€çå€éšåäŸèµé»èŸã
- åŒåé¶æ®µ externalize ææ dependenciesãdevDependenciesãpeerDependenciesãoptionalDependenciesã
- çäº§é¶æ®µåª externalize dependenciesã
/**
* @param pkg package.json çå
容
*/
export function extractExternalDeps(pkg: Record<string, any>): RolldownOrRollupOptions['external']esmShim æä»¶
[!important]
esmShimæä»¶ä» åšvite-plugin-electron@>=1.0.0æäŸã0.xçæ¬æ²¡ææ€åèœã
äœ¿çš esmShim() 䞺äŸèµè¿äº CJS å
šå±åéç ESM Electron å
¥å£æ³šå
¥ __dirname å __filename ç shimã
åªæå®é
åŒçšäº __dirname æ __filename çæä»¶æäŒè¢«èœ¬æ¢ïŒå æ€å¯¹äžéèŠå®çæä»¶æ²¡æé¢å€åŒéã
import { defineConfig } from 'vite'
import electron from 'vite-plugin-electron'
import { esmShim, notBundle } from 'vite-plugin-electron/plugin'
export default defineConfig({
plugins: [
electron({
entry: 'electron/main.ts',
vite: {
plugins: [notBundle(), esmShim()],
},
}),
],
})åç诎æ
å¯¹äºæ¯äžªå®é
åŒçš __dirname æ __filename çæä»¶ïŒäŒåšå€Žéšæå
¥åŠäž shimïŒ
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)API
esmShim() ââ æ éé
眮ïŒçŽæ¥å å
¥ plugins å³å¯ã
dependencies vs devDependencies
electron-builder äŒæ dependencies æå
å°æç»åºçšäžïŒVite/Rolldown ä¹å¯èœæ dependencies æå
å°æž²æè¿çšäº§ç©éã䞺äºé¿å
åäžä»œä»£ç 被é倿å
ïŒåçæš¡åé»è®€åºè¯¥æŸåš dependencies äžïŒå 䞺 electron-builder éèŠæ¶éå®ä»¬çäºè¿å¶æä»¶ãå
¶ä»å¯æå»ºæš¡ååºè¯¥æŸåš devDependencies äžïŒåŠåå®ä»¬å¯èœå
被 Vite æå
ïŒå被 electron-builder æå
äžæ¬¡ã
åŠæäœ æåšå€çåçæš¡åçäºè¿å¶æä»¶åè¿è¡æ¶äŸèµåžå±ïŒä¹å¯ä»¥æè¿äºåçæš¡åç§»å° devDependencies äžïŒä»¥è¿äžæ¥åå°æå
åçåºçšäœç§¯ã
