ByteNoteByteNote

字节笔记本

2026年2月21日

electron-vite - Electron 的下一代构建工具

API中转
¥120

electron-vite 是基于 Vite 的 Electron 构建工具,继承了 Vite 的所有优势,使用方式与 Vite 相同。它专为 Electron 应用开发设计,提供快速、简单且强大的构建体验。

Vite 驱动

继承 Vite 的所有优势,使用方式与 Vite 完全相同。享受 Vite 生态系统的所有特性,包括极速的冷启动、即时模块热更新(HMR)和优化的构建流程。

预配置

针对 Electron 进行了合理的默认配置优化,开箱即用。无需繁琐的配置即可开始 Electron 应用开发。

快速 HMR 与热重载

  • 渲染进程支持 HMR(模块热替换)
  • 主进程和预加载脚本支持热重载

大幅提升开发效率,修改代码后即时生效。

资源优化

针对 Electron 主进程优化资源处理,确保应用性能最佳。

隔离构建

专为多入口应用设计,降低开发复杂性,提升程序性能和安全性。

简化多线程开发

通过简单的导入后缀支持 Worker Threads、Child Process 和 Utility Process。

源码保护

将代码编译为 V8 字节码以保护源代码,防止源码泄露。

易于调试

轻松在 VS Code 和 WebStorm 等 IDE 中进行调试。

开箱即用

原生支持 TypeScript、Vue、React、Svelte、SolidJS 等框架。

快速开始

安装

bash
# 使用 npm
npm create @quick-start/electron@latest

# 使用 yarn
yarn create @quick-start/electron

# 使用 pnpm
pnpm create @quick-start/electron

创建项目

运行上述命令后,按照提示选择:

  • 项目名称
  • 前端框架(Vue/React/Vanilla/Svelte/Solid)
  • 是否使用 TypeScript

项目结构

text
my-electron-app/
├── electron/                 # Electron 相关代码
│   ├── main/                # 主进程
│   │   └── index.ts         # 主进程入口
│   ├── preload/             # 预加载脚本
│   │   └── index.ts         # 预加载脚本入口
│   └── resources/           # 静态资源
│       └── icon.png         # 应用图标
├── src/                     # 渲染进程代码
│   ├── main.ts              # 渲染进程入口
│   ├── App.vue              # 主组件(Vue示例)
│   └── assets/              # 资源文件
├── build/                   # 构建输出目录
├── electron.vite.config.ts  # electron-vite 配置
├── package.json
└── tsconfig.json

开发命令

bash
# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 构建应用
npm run build

# 构建并打包(使用 electron-builder)
npm run build:win    # Windows
npm run build:mac    # macOS
npm run build:linux  # Linux

配置详解

electron.vite.config.ts

typescript
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  main: {
    plugins: [externalizeDepsPlugin()],
    build: {
      outDir: 'dist/main',
      lib: {
        entry: 'electron/main/index.ts',
        formats: ['cjs']
      }
    }
  },
  preload: {
    plugins: [externalizeDepsPlugin()],
    build: {
      outDir: 'dist/preload',
      lib: {
        entry: 'electron/preload/index.ts',
        formats: ['cjs']
      }
    }
  },
  renderer: {
    root: '.',
    build: {
      outDir: 'dist/renderer',
      rollupOptions: {
        input: 'index.html'
      }
    },
    plugins: [vue()]
  }
})

主进程示例

typescript
// electron/main/index.ts
import { app, BrowserWindow, ipcMain } from 'electron'
import path from 'path'

let mainWindow: BrowserWindow | null

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, '../preload/index.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  })

  // 开发环境加载 Vite 服务器
  if (process.env.VITE_DEV_SERVER_URL) {
    mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL)
    mainWindow.webContents.openDevTools()
  } else {
    // 生产环境加载打包后的文件
    mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
  }
}

// IPC 通信示例
ipcMain.handle('get-app-version', () => {
  return app.getVersion()
})

app.whenReady().then(createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

预加载脚本示例

typescript
// electron/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron'

// 暴露安全的 API 给渲染进程
contextBridge.exposeInMainWorld('electronAPI', {
  getAppVersion: () => ipcRenderer.invoke('get-app-version'),

  // 平台信息
  platform: process.platform,

  // 其他自定义 API
  sendMessage: (channel: string, data: any) => {
    const validChannels = ['to-main']
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data)
    }
  }
})

渲染进程使用示例

typescript
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

// 使用预加载的 API
console.log('Platform:', window.electronAPI?.platform)

// 调用主进程方法
window.electronAPI?.getAppVersion().then(version => {
  console.log('App Version:', version)
})

环境变量

electron-vite 支持在渲染进程中使用环境变量:

env
# .env
VITE_APP_TITLE=My Electron App

# .env.development
VITE_API_URL=http://localhost:3000

# .env.production
VITE_API_URL=https://api.example.com

在代码中使用:

typescript
const apiUrl = import.meta.env.VITE_API_URL
const appTitle = import.meta.env.VITE_APP_TITLE

多线程开发

Worker Threads

typescript
// 创建 worker(使用 .node.worker.ts 后缀)
// src/workers/calculation.node.worker.ts
import { parentPort } from 'worker_threads'

parentPort?.on('message', (data) => {
  // 执行耗时计算
  const result = heavyCalculation(data)
  parentPort?.postMessage(result)
})

// 在主进程中使用
// electron/main/index.ts
import { Worker } from 'worker_threads'
import path from 'path'

const worker = new Worker(
  path.join(__dirname, '../workers/calculation.node.worker.js')
)

worker.postMessage({ numbers: [1, 2, 3, 4, 5] })
worker.on('message', (result) => {
  console.log('Calculation result:', result)
})

Child Process

typescript
// 使用 .node.ts 后缀
// electron/main/child.node.ts
import { spawn } from 'child_process'

const child = spawn('node', ['script.js'])
child.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`)
})

源码保护

使用字节码保护源代码:

bash
# 安装 bytenode
npm install bytenode --save-dev

# 在 electron.vite.config.ts 中配置
import { bytecodePlugin } from 'electron-vite'

export default defineConfig({
  main: {
    plugins: [
      externalizeDepsPlugin(),
      bytecodePlugin()  // 启用字节码保护
    ]
  }
})

VS Code 调试配置

创建 .vscode/launch.json

json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Main Process",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "args": ["."],
      "env": {
        "NODE_ENV": "development"
      }
    },
    {
      "name": "Debug Renderer Process",
      "type": "chrome",
      "request": "attach",
      "port": 9223,
      "webRoot": "${workspaceFolder}",
      "timeout": 30000
    }
  ]
}

打包发布

配置 electron-builder

package.json 中添加:

json
{
  "build": {
    "appId": "com.example.myapp",
    "productName": "My Electron App",
    "directories": {
      "output": "release"
    },
    "files": [
      "dist/**/*",
      "electron/**/*"
    ],
    "mac": {
      "target": [
        {
          "target": "dmg",
          "arch": ["x64", "arm64"]
        }
      ]
    },
    "win": {
      "target": [
        {
          "target": "nsis",
          "arch": ["x64"]
        }
      ]
    },
    "linux": {
      "target": [
        {
          "target": "AppImage",
          "arch": ["x64"]
        }
      ]
    }
  }
}

常见问题

1. 热重载不生效

检查 electron.vite.config.ts 配置是否正确,确保 build.watch 已启用。

2. 路径问题

在打包后的应用中,使用 __dirnamepath.join 来构建路径:

typescript
import path from 'path'

const resourcePath = path.join(__dirname, '../resources/icon.png')

3. 原生模块使用

对于原生 Node.js 模块,需要在 electron.vite.config.ts 中配置 external:

typescript
export default defineConfig({
  main: {
    build: {
      rollupOptions: {
        external: ['native-module-name']
      }
    }
  }
})

相关链接

分享: