Skip to content

Latest commit

 

History

115 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@tomjs/vite-plugin-electron

npm node-current (scoped) NPM jsDocs.io

English | 中文

A Simple vite plugin for electron, supports esm and cjs.

Many thanks to caoxiemeihao's vite-plugin-electron and Doubleshotjs's doubleshot These two excellent libraries inspired me. I hope to use it to simplify development configuration and focus only on business development.

Features

  • Fast build main and preload with vite
  • Little configuration, focus on business
  • Support main's Hot Restart
  • Support preload's Hot Reload
  • Support esm and cjs, you can use esm in electron v28+
  • Support vue and react and other frameworks supported by vite
  • Optional electron-builder Simple configuration

Install

# 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

If you use builder to package your application, please install electron-builder

# pnpm
pnpm add electron-builder -D

# yarn
yarn add electron-builder -D

# npm
npm i electron-builder --save-dev

Usage

Recommended Agreement

Directory Structure

  • Recommend electron and page src code directory structure
|--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
  • Zero configuration, default dist output directory
|--dist
|  |--main
|  |  |--index.js
|  |  |--index.js.map
|  |--preload
|  |  |--index.js
|  |  |--index.js.map
|  |--renderer
|  |  |--index.html

Default configuration and behavior

See PluginOptions and recommended parameter descriptions in detail

electron

electron/main/index.ts

import { join } from 'node:path';
import { ELECTRON_EXIT } from '@tomjs/vite-plugin-electron/electron';
import { app, BrowserWindow } from 'electron';

// `__dirname` and `__filename` are provided automatically for `esm` output.

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);

process.on('message', (data) => {
  // When restarting the electron, if devTools is turned on, the electron may not be able to shut down normally.
  if (data === ELECTRON_EXIT) {
    if (win) {
      win.webContents.closeDevTools();
    }
  }
});

vue

Take using esm as an example, but it requires Electron>=28

  • package.json

Electron preload process must use the .mjs suffix, otherwise an error will be reported, see official documentation. So the default output of esm of preload uses the .mjs suffix. For consistency, main process also ends with .mjs

{
  "type": "module",
  "main": "dist/main/index.mjs"
}
  • vite.config.ts
// import renderer from 'vite-plugin-electron-renderer'; // Enable nodeIntegration
import electron from '@tomjs/vite-plugin-electron';
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    vue(),
    // If you use the agreed directory structure, no configuration is required
    electron(),
    // If the directory structure is customized, the value must be assigned according to the actual situation
    // electron({
    //   main: {
    //     entry: 'electron/main/index.ts',
    //   },
    //   preload: {
    //     entry: 'electron/preload/index.ts',
    //   },
    // }),
    // renderer(),
  ],
});

react

Take using cjs as an example

  • package.json
{
  // "type": "commonjs",
  "main": "dist/main/index.js"
}
  • vite.config.ts
import electron from '@tomjs/vite-plugin-electron';
import react from '@vitejs/plugin-react-swc';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [react(), electron()],
});

Documentation

Parameters

PluginOptions

Property Type Default Description
recommended boolean true This option is intended to provide recommended default parameters and behavior.
external string[] Don't bundle these modules. Node.js built-ins and electron are always excluded.
main MainOptions Configuration options for the electron main process.
preload PreloadOptions Configuration options for the electron preload process.
debug boolean false Electron debug mode, don't startup electron. You can also use process.env.VITE_ELECTRON_DEBUG. Default is false.
builder boolean | BuilderOptions false If it is a boolean type, whether to enable electron-builder. If it is an object, it is the configuration of electron-builder. You can also turn it on using process.env.VITE_ELECTRON_DEBUG.
inspect boolean false Electron will listen for V8 inspector protocol messages on the specified port, an external debugger will need to connect on this port. You can also use process.env.VITE_ELECTRON_INSPECT. See debugging-main-process for more information.
devtools boolean | number false If true, depending on whether the react plugin exists, inject <script src="http://localhost:8097"></script> code for react-devtools; depending on whether the vue plugin exists, inject <script src="http://localhost:8097"></script> for vue-devtools debugging; if number, it is a custom port.

Notice

The recommended option is used to set the default configuration and behavior, which can be used with almost zero configuration. The default is true. If you want to customize the configuration, set it to false. The following default prerequisites are to use the recommended project structure.

  • Check whether electron/main/index.ts and electron/main/index.ts exist, and if so, assign values to main.entry and preload.entry respectively. If it does not exist, main.entry must be actively assigned, and an error will be reported.
  • The output directory is based on the build.outDir parameter of vite, and outputs electron/main, electron/preload and src to dist/main, dist/preload and dist/renderer respectively.
  • Other behaviors to be implemented

MainOptions

Based on UserConfig of vite, some default values are added for ease of use.

Property Type Default Description
entry string | string[] | Record - The main process entry file. When recommended: true, defaults to electron/main/index.ts if it exists.
format 'cjs' | 'esm' - The bundle format. If not specified, it will use the "type" field from package.json.
outDir string "dist/main" (recommended) / "dist-electron/main" The output directory for the main process files
target string | false 'node18.18' (esm) / 'node16' (cjs) The Node.js build target, passed to Vite's build.target.
sourcemap boolean | 'inline' | 'hidden' true (dev) / false (prod) Whether to generate sourcemaps.
minify boolean | 'oxc' | 'terser' | 'esbuild' false (dev) / true (prod) Minify the output.
clean boolean true Empty the output directory before building.
treeshake boolean true (dev) / false (prod) Enable/disable tree-shaking.
external string[] [] Don't bundle these modules. Node.js built-ins and electron are always excluded.
watchFiles string | string[] undefined Additional files or folders to watch. Note: Vite always watches the module dependency graph, so this is only needed for files outside the graph.
ignoreWatch Arrayable<string | RegExp> '.history', '.temp', '.tmp', '.cache', 'dist' Ignore files or folders being watched
onSuccess string | function undefined A shell command or callback to run after every successful build (dev mode).

Any other top-level Vite UserConfig option (resolve, define, plugins, ...) can also be passed directly.

PreloadOptions

Based on UserConfig of vite, some default values are added for ease of use.

Property Type Default Description
entry string | string[] | Record - The preload process entry file. When recommended: true, defaults to electron/preload/index.ts if it exists.
format 'cjs' | 'esm' - The bundle format. If not specified, it will use the "type" field from package.json.
outDir string "dist/preload" (recommended) / "dist-electron/preload" The output directory for the preload process files
target string | false 'node18.18' (esm) / 'node16' (cjs) The Node.js build target, passed to Vite's build.target.
sourcemap boolean | 'inline' | 'hidden' true (dev) / false (prod) Whether to generate sourcemaps.
minify boolean | 'oxc' | 'terser' | 'esbuild' false (dev) / true (prod) Minify the output.
clean boolean true Empty the output directory before building.
treeshake boolean true (dev) / false (prod) Enable/disable tree-shaking.
external string[] [] Don't bundle these modules. Node.js built-ins and electron are always excluded.
watchFiles string | string[] undefined Additional files or folders to watch. Note: Vite always watches the module dependency graph, so this is only needed for files outside the graph.
ignoreWatch Arrayable<string | RegExp> '.history', '.temp', '.tmp', '.cache', 'dist' Ignore files or folders being watched
onSuccess string | function undefined A shell command or callback to run after every successful build (dev mode).

Any other top-level Vite UserConfig option (resolve, define, plugins, ...) can also be passed directly.

BuilderOptions

When recommended and builder.enable are both true, use electron-builder to package Electron applications.

  • In the build.outDir directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
  • Execute npm install and then package.

Reference vite-plugin-electron-renderer and Two package.json Structure

Not suitable for everyone.

To use this function, you need to install additional electron-builder

Property Type Default Description
appId string "com.electron.${name}" The application id. See More
productName string "com.electron.${name}" product name.See More
builderConfig Configuration undefined electron-builder's Configuration

The default configuration is as follows:

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,
  },
};

Additional Information

  • Default values for main and preload when the relevant parameters are not configured
Parameter Development Mode Default Production Mode Default
sourcemap true false
minify false true

Environment Variables

Vite plugin variables

Variable Description
VITE_ELECTRON_DEBUG Electron main process debug, don't startup electron. When value is true or 1 to enable, false or 0 to disable.Default is undefined.
VITE_ELECTRON_INSPECT Electron will listen for V8 inspector protocol messages on the specified port, an external debugger will need to connect on this port. When value is true, the default port is 5858.
VITE_ELECTRON_BUILDER Enable electron-builder to package. When value is true or 1 to enable, false or 0 to disable. Default is undefined.

Application variables

Electron main process and renderer process use.

Variable Description
VITE_DEV_SERVER_URL The url of the dev server.

Debug

Web debugging

Use @tomjs/electron-devtools-installer to install the Chrome Devtools plugins and use it like web development

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) => {
      // Install the extension before enabling the developer tools; otherwise, the extension may fail to load.
      // win.webContents.openDevTools();

      console.log(
        'Added Extension: ',
        exts.map(s => s.name),
      );
    })
    .catch((err) => {
      console.log('Failed to install extensions');
      console.error(err);
    });
});

Main Process Debug

Run Debug Main Process through vscode to debug the main thread. For debugging tools, refer to Official Documentation

launch.json is configured as follows:

{
  "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 is configured as follows:

{
  "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*$"
        }
      }
    }
  ]
}

Preload process Debug

Use DevTools to debug the preload process.

Examples

First execute the following command to install dependencies and generate library files:

pnpm install
pnpm build

Open the examples directory, there are vue and react examples.

Important Notes

v3.0.0

Breaking Updates:

  • Requires Vite ^8.0.0 (the main/preload processes are now compiled with Vite itself using Rolldown, instead of tsdown).
  • MainOptions / PreloadOptions are now based on Vite's UserConfig instead of tsdown's options. Any top-level Vite option (resolve, define, plugins, ...) can be passed directly.
  • The module dependency graph of main/preload is always watched in dev mode; watchFiles is only needed for files outside the graph.
  • __dirname / __filename are now injected automatically for esm output (like the previous shims behavior), so you can keep using __dirname in the main process without any manual setup.

v2.0.0

Breaking Updates:

  • Using tsdown instead of tsup, the main/preload configuration is changed to inherit tsdown.
  • If recommended:true is not used, watchFiles needs to be configured. See MainOptions and PreloadOptions for details.

About

A simple vite plugin for electron, supports esm/cjs

Topics

Resources

Stars

12 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages