caoxiemeihao / vite-electron-plugin

High-performance, esbuild-based Vite Electron plugin
MIT License
53 stars 7 forks source link
electron esbuild plugin vite

vite-electron-plugin

High-performance, esbuild-based Vite Electron plugin

NPM version NPM Downloads

Quick Setup

  1. Add dependency to project
npm i -D vite-electron-plugin
  1. Add vite-electron-plugin into vite.config.ts
import electron from 'vite-electron-plugin'

export default {
  plugins: [
    electron({
      include: [
        // The Electron source codes directory
        'electron',
      ],
    }),
  ],
}
  1. Create electron/main.ts and type the following code
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  const win = new BrowserWindow()

  if (process.env.VITE_DEV_SERVER_URL) {
    win.loadURL(process.env.VITE_DEV_SERVER_URL)
  } else {
    win.loadFile('dist/index.html')
  }
})
  1. Add entry into package.json
{
+ "main": "dist-electron/main.js"
}

Examples

Recommend Structure

Let's use the official template-vanilla-ts created based on create vite as an example

+ ├─┬ electron
+ │ └── main.ts
  ├─┬ src
  │ ├── main.ts
  │ ├── style.css
  │ └── vite-env.d.ts
  ├── .gitignore
  ├── favicon.svg
  ├── index.html
  ├── package.json
  ├── tsconfig.json
+ └── vite.config.ts

Conventions

Configuration

electron(config: Configuration)
Key Type Description Required Default
include Array directory or filename or glob Array.
Must be a relative path, which will be calculated based on the root.
If it is an absolute path, it can only be a subpath of root.
Otherwise it will cause the output file path to be calculated incorrectly.
✅
root string process.cwd()
outDir string Output Directory. dist-electron
api Record<string, any> Useful if you want to pass some payload to the plugin.
plugins Plugin[] See the Plugin API.
logger { [type: string], (...message: string[]) => void } Custom log. If logger is passed, all logs will be input this option
transformOptions import('esbuild').TransformOptions Options of esbuild.transform()
watch import('chokidar').WatchOptions Options of chokidar.watch()

Plugin API

The design of plugin is similar to Vite's plugin. But simpler, only 4 hooks in total.

configResolved

You can freely modify the config argument in ths hooks or use.

onwatch serve only

Triggered by include file changes. You can emit some files in this hooks. Even restart the Electron App.

transform

Triggered by changes in extensions files in include.

ondone

Triggered when transform() ends or a file in extensions is removed.

Builtin Plugin

import path from 'node:path'
import electron from 'vite-electron-plugin'
import {
  alias,
  copy,
  dest,
  esmodule,
  customStart,
  loadViteEnv,
} from 'vite-electron-plugin/plugin'

export default {
  plugins: [
    electron({
      plugins: [
        alias([
          // `replacement` is recommented to use absolute path, 
          // it will be automatically calculated as relative path.
          { find: '@', replacement: path.join(__dirname, 'src') },
        ]),

        copy([
          // filename, glob
          { from: 'foo/*.ext', to: 'dest' },
        ]),

        // Dynamic change the build dist path.
        dest((_from, to) => to?.replace('dist-electron', 'dist-other')),

        customStart(({ startup }) => {
          // If you want to control the launch of Electron App yourself.
          startup()
        }),

        // Support use ESM npm-package in Electron-Main.  
        esmodule({
          // e.g. `execa`, `node-fetch`, `got`, etc.
          include: ['execa', 'node-fetch', 'got'],
        }),

        // https://vitejs.dev/guide/env-and-mode.html#env-files
        // Support use `import.meta.env.VITE_SOME_KEY` in Electron-Main
        loadViteEnv(),
      ],
    }),
  ],
}

JavaScript API

import {
  type Configuration,
  type ResolvedConfig,
  type Plugin,
  build,
  watch,
  startup,
  defineConfig,
  default as electron,
} from 'vite-electron-plugin'

Example

// dev
watch({
  include: [
    // The Electron source codes directory
    'electron',
  ],
  plugins: [
    {
      name: 'plugin-electron-startup',
      ondone() {
        // Startup Electron App
        startup()
      },
    },
  ],
})

// build
build({
  include: ['electron'],
})