English | 简体中文
An Electron CLI integrated with Vite
- ⚡️Use the same way as Vite
- 🔨Main process, renderer process and preload script source code are built using Vite
- 📃Main process, renderer process and preload script Vite configuration combined into one file
- 📦Preset optimal build configuration
- 🚀HMR for renderer processes
npm i electron-vite -D
In a project where electron-vite
is installed, you can use electron-vite
binary directly with npx electron-vite
or add the npm scripts to your package.json
file like this:
{
"scripts": {
"start": "electron-vite preview", // start electron app to preview production build
"dev": "electron-vite dev", // start dev server and electron app
"prebuild": "electron-vite build" // build for production
}
}
In order to use the renderer process HMR, you need to use the environment variables
to determine whether the window browser loads a local html file or a remote URL.
function createWindow() {
// Create the browser window
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, '../preload/index.js')
}
})
// Load the remote URL for development or the local html file for production
if (!app.isPackaged && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
}
}
Note: For development, the renderer process index.html
file needs to reference your script code via <script type="module">
.
├──src
│ ├──main
│ │ ├──index.js
│ │ └──...
│ ├──preload
│ │ ├──index.js
│ │ └──...
│ └──renderer
│ ├──src
│ ├──index.html
│ └──...
├──electron.vite.config.js
└──package.json
Clone the electron-vite-boilerplate or use the create-electron tool to scaffold your project.
npm init @quick-start/electron
When running electron-vite
from the command line, electron-vite will automatically try to resolve a config file named electron.vite.config.js
inside project root. The most basic config file looks like this:
// electron.vite.config.js
export default {
main: {
// vite config options
},
preload: {
// vite config options
},
renderer: {
// vite config options
}
}
You can also explicitly specify a config file to use with the --config
CLI option (resolved relative to cwd
):
electron-vite --config my-config.js
Tips: electron-vite
also supports ts
or mjs
config file.
Since electron-vite
ships with TypeScript typings, you can leverage your IDE's intellisense with jsdoc type hints:
/**
* @type {import('electron-vite').UserConfig}
*/
const config = {
// ...
}
export default config
Alternatively, you can use the defineConfig
and defineViteConfig
helper which should provide intellisense without the need for jsdoc annotations:
import { defineConfig, defineViteConfig } from 'electron-vite'
export default defineConfig({
main: {
// ...
},
preload: {
// ...
},
renderer: defineViteConfig(({ command, mode }) => {
// conditional config use defineViteConfig
// ...
})
})
Tips: The defineViteConfig
exports from Vite
.
See vitejs.dev
- outDir:
out\main
(relative to project root) - target:
node*
, automatically match node target ofElectron
. For example, the node target of Electron 17 isnode16.13
- lib.entry:
src\main\{index|main}.{js|ts|mjs|cjs}
(relative to project root), empty string if not found - lib.formats:
cjs
- rollupOptions.external:
electron
and all builtin modules
- outDir:
out\preload
(relative to project root) - target: the same as
main
- lib.entry:
src\preload\{index|preload}.{js|ts|mjs|cjs}
(relative to project root), empty string if not found - lib.formats:
cjs
- rollupOptions.external: the same as
main
- root:
src\renderer
(relative to project root) - outDir:
out\renderer
(relative to project root) - target:
chrome*
, automatically match chrome target ofElectron
. For example, the chrome target of Electron 17 ischrome98
- lib.entry:
src\renderer\index.html
(relative to project root), empty string if not found - polyfillModulePreload:
false
, there is no need to polyfillModule Preload
for the Electron renderer - rollupOptions.external: the same as
main
In web development, Vite will transform 'process.env.'
to '({}).'
. This is reasonable and correct. But in nodejs development, we sometimes need to use process.env
, so electron-vite
will automatically add config define field to redefine global variable replacements like this:
export default {
main: {
define: {
'process.env': 'process.env'
}
}
}
Note: If you want to use these configurations in an existing project, please see the Vite plugin vite-plugin-electron-config
When your electron app has multiple windows, it means there are multiple html files or preload files. You can modify your config file like this:
export default {
main: {},
preload: {
build: {
rollupOptions: {
input: {
browser: resolve(__dirname, 'src/preload/browser.ts'),
webview: resolve(__dirname, 'src/preload/webview.ts')
}
}
}
},
renderer: {
build: {
rollupOptions: {
input: {
browser: resolve(__dirname, 'src/renderer/browser.html'),
webview: resolve(__dirname, 'src/renderer/webview.html')
}
}
}
}
}
For the full list of CLI options, you can run npx electron-vite -h
in your project. The flags listed below are only available via the command line interface:
--ignoreConfigWarning
: boolean, allow you ignore warning when config missing--outDir
: string, output directory (default: out)
Type Signature:
async function build(inlineConfig: InlineConfig = {}): Promise<void>
Example Usage:
const path = require('path')
const { build } = require('electron-vite')
;(async () => {
await build({
build: {
outDir: 'out'
rollupOptions: {
// ...
}
}
})
})()
Type Signature:
async function createServer(inlineConfig: InlineConfig = {}): Promise<void>
Example Usage:
const { createServer } = require('electron-vite')
;(async () => {
await createServer({
server: {
port: 1337
}
})
})()
Type Signature:
async function preview(inlineConfig: InlineConfig = {}): Promise<void>
Example Usage:
const { preview } = require('electron-vite')
;(async () => {
await preview({})
})()
The InlineConfig interface extends Vite UserConfig with additional properties:
ignoreConfigWarning
: set tofalse
to ignore warning when config missing
And omit base
property because it is not necessary to set the base public path in Electron.
Type Signature:
async function resolveConfig(
inlineConfig: InlineConfig,
command: 'build' | 'serve',
defaultMode = 'development'
): Promise<ResolvedConfig>
MIT © alex.wei