Home

Awesome

@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

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

|--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
|--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 { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { app, BrowserWindow } from 'electron';

// when package.json "type": module"
global.__dirname = dirname(fileURLToPath(import.meta.url));

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

vue

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

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"
}
import { defineConfig } from 'vite';
// import renderer from 'vite-plugin-electron-renderer'; // Enable nodeIntegration
import electron from '@tomjs/vite-plugin-electron';
import vue from '@vitejs/plugin-vue';
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

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

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

Documentation

Parameters

PluginOptions

PropertyTypeDefaultDescription
recommendedbooleantrueThis option is intended to provide recommended default parameters and behavior.
externalstring[]Don't bundle these modules, but dependencies and peerDependencies in your package.json are always excluded.See more
mainMainOptionsConfiguration options for the electron main process.
preloadPreloadOptionsConfiguration options for the electron preload process.
debugbooleanfalseElectron debug mode, don't startup electron. You can also use process.env.VITE_ELECTRON_DEBUG. Default is false.
builderboolean | BuilderOptionsfalseIf 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.
inspectbooleanfalseElectron 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.

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.

MainOptions

Based on Options of tsup, some default values are added for ease of use.

PropertyTypeDefaultDescription
entrystring-The main process entry file.
format'cjs' | 'esm'-The bundle format. If not specified, it will use the "type" field from package.json.
outDirstring"dist-electron/main"The output directory for the main process files
onSuccess() => Promise<void | undefined | (() => void | Promise<void>)>undefinedA function that will be executed after the build succeeds.

PreloadOptions

Based on Options of tsup, some default values are added for ease of use.

PropertyTypeDefaultDescription
entrystring-The preload process entry file.
format'cjs' | 'esm'-The bundle format. If not specified, it will use the "type" field from package.json.
outDirstring"dist-electron/preload"The output directory for the preload process files
onSuccess() => Promise<void | undefined | (() => void | Promise<void>)>undefinedA function that will be executed after the build succeeds.

BuilderOptions

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

Not suitable for everyone.

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

PropertyTypeDefaultDescription
appIdstring"com.electron.${name}"The application id. See More
productNamestring"com.electron.${name}"product name.See More
builderConfigConfigurationundefinedelectron-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

ParameterDevelopment Mode DefaultProduction Mode Default
sourcemaptruefalse
minifyfalsetrue

Environment Variables

Vite plugin variables

VariableDescription
VITE_ELECTRON_DEBUGElectron 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_INSPECTElectron 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_BUILDEREnable 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.

VariableDescription
VITE_DEV_SERVER_URLThe 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 => {
      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.