Electron 支持

Nasti 原生支持构建 Electron 桌面应用,最低要求 Electron 41 (对应 Node.js 22.x / Chromium 138,完整 ESM 主进程能力)。主进程、Preload、 渲染进程由同一个 Nasti 流水线统一打包。

兼容性: 支持 Electron 41 以及更新版本(42、43、…)。 开发时会检测已安装版本,低于 minVersion 将提示警告。

安装

npm install -D @nasti-toolchain/nasti electron@^41

项目结构

my-electron-app/
├── index.html                 # 渲染进程入口
├── src/
│   ├── main.tsx               # 渲染进程 JS
│   ├── App.tsx
│   └── electron/
│       ├── main.ts            # 主进程入口
│       └── preload.ts         # Preload 脚本
└── nasti.config.ts

配置

// nasti.config.ts
import { defineConfig } from '@nasti-toolchain/nasti'

export default defineConfig({
  target: 'electron',
  framework: 'react',

  electron: {
    main: 'src/electron/main.ts',
    preload: 'src/electron/preload.ts',
    mainFormat: 'cjs',       // 'cjs' | 'esm'(Electron 41+ 支持 ESM)
    preloadFormat: 'cjs',
    nodeTarget: 'node22',
    autoRestart: true,
    minVersion: 41,
    external: ['electron'],
  },
})

主进程示例

// src/electron/main.ts
import { app, BrowserWindow } from 'electron'
import path from 'node:path'

async function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      preload: path.resolve(__dirname, 'preload.cjs'),
      contextIsolation: true,
      sandbox: true,
    },
  })

  // Nasti 在 dev 模式下会将渲染进程 URL 注入 NASTI_DEV_SERVER_URL
  if (process.env.NASTI_DEV_SERVER_URL) {
    await win.loadURL(process.env.NASTI_DEV_SERVER_URL)
  } else {
    await win.loadFile(path.resolve(__dirname, 'renderer/index.html'))
  }
}

app.whenReady().then(createWindow)

Preload 示例

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

contextBridge.exposeInMainWorld('nasti', {
  ping: () => ipcRenderer.invoke('ping'),
})

开发

# 启动渲染进程 dev server 并 spawn Electron
npx nasti electron

# 仅编译主/preload,不启动 Electron(CI 场景)
npx nasti electron --no-spawn

# 禁用主/preload 变更自动重启
npx nasti electron --no-restart

Nasti 会:

  1. 启动 HTTP dev server 承载渲染进程(带 HMR)
  2. 将主进程 / preload 编译至 .nasti/ 临时目录
  3. 通过 node_modules/electron 查找 Electron 可执行文件并 spawn
  4. 监听主 / preload 文件变更,重编译后自动重启 Electron 进程

生产构建

npx nasti electron-build
# 等价于:
npx nasti build --target electron

产物布局:

dist/
├── renderer/            # Web 渲染层(同 nasti build)
│   ├── index.html
│   └── assets/
├── main.cjs             # 主进程(mainFormat=esm 时为 main.mjs)
└── preload.cjs          # Preload(preloadFormat=esm 时为 preload.mjs)

ESM 主进程(Electron 41+)

Electron 41 开始完整支持 ESM 主进程,可通过 mainFormat: 'esm' 启用:

export default defineConfig({
  target: 'electron',
  electron: {
    mainFormat: 'esm',
    preloadFormat: 'cjs', // preload 建议保持 cjs 以兼容 contextIsolation
  },
})
注意: 低于 Electron 41 时若使用 mainFormat: 'esm', Electron 会拒绝加载 .mjs 主进程。Nasti 在检测到过低版本时会输出警告。

配置参考

选项类型默认值说明
mainstring'src/electron/main.ts'主进程入口
preloadstring | string[]'src/electron/preload.ts'Preload 脚本,可多入口
rendererstring'index.html'渲染进程入口 HTML
mainFormat'cjs' | 'esm''cjs'主进程输出格式
preloadFormat'cjs' | 'esm''cjs'Preload 输出格式
nodeTargetstring'node22'主/preload 的 Node 目标版本
autoRestartbooleantruedev 模式下主/preload 变更自动重启
minVersionnumber41允许的最低 Electron 大版本
electronPathstring''自定义 Electron 可执行文件路径
electronArgsstring[][]传递给 Electron 的 CLI 参数
externalstring[]['electron']主/preload 外部化依赖

编程式 API

import { buildElectron, startElectronDev } from '@nasti-toolchain/nasti'

// 生产构建
await buildElectron({ root: '.' })

// 开发模式
await startElectronDev({ root: '.' })

与 Electron Builder 配合

Nasti 只负责编译代码产物;打包分发(.dmg / .exe / AppImage) 建议搭配 electron-builder

// package.json
{
  "scripts": {
    "build": "nasti electron-build && electron-builder"
  },
  "build": {
    "files": ["dist/**"],
    "directories": { "buildResources": "build" }
  }
}