vite-plugin-electron

Electron ๐Ÿ”— Vite

English | ็ฎ€ไฝ“ไธญๆ–‡


In short, `vite-plugin-electron` makes developing Electron apps as easy as normal Vite projects. ## Features - [๐Ÿ”ฅ Hot Restart (Main process)](https://electron-vite.github.io/guide/features.html#hot-restart) - [๐Ÿ”„ Hot Reload (Preload scripts)](https://electron-vite.github.io/guide/features.html#hot-reload) - [โšก๏ธ HMR (Renderer process)](https://electron-vite.github.io/guide/features.html#hmr) - [๐Ÿš€ Not Bundle, It's fast (Like Vite's Not Bundle)](https://github.com/electron-vite/vite-plugin-electron#not-bundle) - ๐ŸŒฑ Fully compatible with Vite and Vite's ecosystem (Based on Vite) - ๐Ÿฃ Few APIs, easy to use ## Quick Setup 1. Add the following dependency to your project ```sh npm i -D vite-plugin-electron ``` 2. Add `vite-plugin-electron` to the `plugins` section of `vite.config.ts` ```js import electron from 'vite-plugin-electron' export default { plugins: [ electron({ entry: 'electron/main.ts', }), ], } ``` 3. Create the `electron/main.ts` file and type the following code ```js 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'); } }) ``` 4. Add the `main` entry to `package.json` ```diff { + "main": "dist-electron/main.js" } ``` That's it! You can now use Electron in your Vite app โœจ ## Simple API Many times, for a developer who is new to Vite and Electron, the oversimplified and open API design is confusing to them. Maybe Simple API makes them easier to understand. :) ```js // Just like v0.9.x 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.rollupOptions.input` input: 'electron/preload.ts', }, // Optional: Use Node.js API in the Renderer process renderer: {}, }), ], } ``` ## API (Define) `electron(options: ElectronOptions | ElectronOptions[])` ```ts 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 Electroo App via `startup` function. */ onstart?: (args: { /** * Electron App startup function. * It will mount the Electron App child-process to `process.electronApp`. * @param argv default value `['.', '--no-sandbox']` */ startup: (argv?: string[]) => Promise /** Reload Electron-Renderer */ reload: () => void }) => void | Promise } ``` ## Recommend Structure Let's use the official [template-vanilla-ts](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-vanilla-ts) created based on `create vite` as an example ```diff + โ”œโ”€โ”ฌ electron + โ”‚ โ””โ”€โ”€ main.ts โ”œโ”€โ”ฌ src โ”‚ โ”œโ”€โ”€ main.ts โ”‚ โ”œโ”€โ”€ style.css โ”‚ โ””โ”€โ”€ vite-env.d.ts โ”œโ”€โ”€ .gitignore โ”œโ”€โ”€ favicon.svg โ”œโ”€โ”€ index.html โ”œโ”€โ”€ package.json โ”œโ”€โ”€ tsconfig.json + โ””โ”€โ”€ vite.config.ts ``` ## Examples There are many cases here ๐Ÿ‘‰ [electron-vite-samples](https://github.com/caoxiemeihao/electron-vite-samples) ## JavaScript API `vite-plugin-electron`'s JavaScript APIs are fully typed, and it's recommended to use TypeScript or enable JS type checking in VS Code to leverage the intellisense and validation. - `ElectronOptions` - type - `resolveViteConfig` - function, Resolve the default Vite's `InlineConfig` for build Electron-Main - `withExternalBuiltins` - function - `build` - function - `startup` - function **Example** ```js 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() } }, }], }, }) ``` ## How to work It just executes the `electron .` command in the Vite build completion hook and then starts or restarts the Electron App. ## Be aware - ๐Ÿšจ By default, the files in `electron` folder will be built into the `dist-electron` - ๐Ÿšจ Currently, `"type": "module"` is not supported in Electron ## C/C++ Native We have two ways to use C/C++ native modules **First way** In general, Vite may not correctly build Node.js packages, especially C/C++ native modules, but Vite can load them as external packages So, put your Node.js package in `dependencies`. Unless you know how to properly build them with Vite ```js export default { plugins: [ electron({ entry: 'electron/main.ts', vite: { build: { rollupOptions: { // Here are some C/C++ modules them can't be built properly external: [ 'serialport', 'sqlite3', ], }, }, }, }), ], } ``` **Second way** Use ๐Ÿ‘‰ [vite-plugin-native](https://github.com/vite-plugin/vite-plugin-native) ```js import native from 'vite-plugin-native' export default { plugins: [ electron({ entry: 'electron/main.ts', vite: { plugins: [ native(/* options */), ], }, }), ], } ``` --- ## Not Bundle > Added in: v0.13.0 During the development phase, we can exclude the `cjs` format of npm-pkg from bundle. Like Vite's [๐Ÿ‘‰ Not Bundle](https://vitejs.dev/guide/why.html#why-not-bundle-with-esbuild). **It's fast**! ```js import electron from 'vite-plugin-electron' import { notBundle } from 'vite-plugin-electron/plugin' export default defineConfig(({ command }) => ({ plugins: [ electron({ entry: 'electron/main.ts', vite: { plugins: [ command === 'serve' && notBundle(/* NotBundleOptions */), ], }, }), ], })) ``` **API** `notBundle(/* NotBundleOptions */)` ```ts export interface NotBundleOptions { filter?: (id: string) => void | false } ``` **How to work** Let's use the `electron-log` as an examples. ```js โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“ โ”‚ import log from 'electron-log' โ”‚ โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”› โ†“ Modules in `node_modules` are not bundled during development, it's fast! โ†“ โ”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”“ โ”‚ const log = require('electron-log') โ”‚ โ”—โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ”› ``` ## FAQ - `electron` does not exit correctly | ไฝฟ็”จctrl + c ๅœๆญขไปฃ็ ๏ผŒelectronๅŽๅฐไธๅ…ณ้—ญ | [#122](https://github.com/electron-vite/vite-plugin-electron/pull/122), [#168](https://github.com/electron-vite/vite-plugin-electron/issues/168) * Add `tree-kill` into you dependencies, `npm i -D tree-kill`.