☰
使用 @farmfe/js-plugin-electron 构建 Electron 应用:Farm 桌面开发全指南
2026/10/13 1:45:19 网站建设 项目流程
  • 前端构建
  • 构建工具
  • 开发工具

【免费下载链接】farm

Extremely fast Vite-compatible web build tool written in Rust

项目地址:https://gitcode.com/gh_mirrors/fa/farm
点击查看免费下载

导读

本指南围绕 Farm 官方 JavaScript 插件@farmfe/js-plugin-electron展开,讲解如何用 Farm 这一基于 Rust 的 Vite 兼容构建工具开发 Electron 桌面应用。阅读本文后,你将掌握:插件安装与最小配置、main与preload双入口的构建模型、开发模式下的进程热重启与 preload 热更新机制,以及生产构建与打包(Electron Forge)的完整闭环方案。文章内容以插件源码(src/index.ts)与仓库自带示例工程(examples/electron)为事实依据,所有配置均可直接复制运行。

插件是什么:一条 Farm 与 Electron 之间的"双构建"桥梁

Electron 应用由三部分组成:主进程(main)、预加载脚本(preload)与渲染进程(renderer)。渲染进程可以用 Farm 当作普通的 Web 应用来开发(HTML / CSS / TS / 框架均可),但主进程与 preload 脚本是 Node.js 环境下的独立构建产物,需要单独的入口和输出。

@farmfe/js-plugin-electron的价值就在于:在 Farm 的一次编译会话中,把主进程与 preload 脚本当作"嵌套构建"一并处理。从 src/index.ts 的实现可以看到,该插件会:

  • 通过config钩子修改全局配置(如默认把publicPath设为'./',保证加载相对资源);
  • 在开发服务器启动后(configureServer),自动编译 main / preload 并启动 Electron 进程;
  • 在整次构建结束(finish钩子)时,以生产模式重新编译 main / preload,产出可直接打包的产物。

因此你只需要运行farm(开发)或farm build(生产)一条命令,Electron 侧的编译与启动全部由插件托管,无需额外脚本。

安装与最小配置

安装插件

在 Farm 项目中以开发依赖安装插件,官方文档(README-zh-CN.md)提供了三种包管理器方式:

# npm npm install @farmfe/js-plugin-electron --save-dev # yarn yarn add -D @farmfe/js-plugin-electron # pnpm pnpm add -D @farmfe/js-plugin-electron

注意:插件本身将electron作为devDependencies使用(见 package.json),你的项目同样需要安装electron与@farmfe/core、@farmfe/cli,示例工程 examples/electron/package.json 中即包含完整依赖清单。

在 farm.config.ts 中启用插件

官方文档给出的最小配置(README-zh-CN.md):

import { defineConfig } from '@farmfe/core' import electron from '@farmfe/js-plugin-electron' export default defineConfig({ plugins: [ electron({ main: { input: 'electron/main.ts', }, preload: { input: 'electron/preload.ts', }, }), ], })

代码中同时出现了两条import(import electron from '@farmfe/js-plugin-electron'与import electron from './farm-plugin-electron'),这是文档行文上的冗余,实际使用时二选一即可——发布场景使用包名导入,本地联调插件源码时使用相对路径导入。

仓库示例工程 examples/electron/farm.config.ts 与文档配置几乎一致,仅额外关闭了持久化缓存:

import { defineConfig } from '@farmfe/core'; import electron from '@farmfe/js-plugin-electron'; export default defineConfig({ compilation: { persistentCache: false, }, plugins: [ electron({ main: { input: 'electron/main.ts', }, preload: { input: 'electron/preload.ts', }, }), ], });

关闭persistentCache是因为插件内部在 resolveFarmConfig 中也会强制persistentCache = false——Electron 主进程产物依赖process.cwd()等运行期环境,不适合使用跨进程缓存。

插件选项详解

官方文档给出的完整类型定义(README-zh-CN.md):

import type { UserConfig } from '@farmfe/core' export interface BuildOptions { /** * `compilation.input` 的别名 */ input: string | Record<string, string> farm?: UserConfig } export interface ElectronPluginOptions { main: BuildOptions preload?: BuildOptions }

各字段的语义与取值说明如下(以 src/index.ts 的源码注释与实现为准):

字段类型必填说明
mainBuildOptions✅主进程构建配置,对应最终产出dist-electron/main.js
preloadBuildOptions❌preload 脚本构建配置,对应最终产出dist-electron/preload.js(或.mjs,见下文格式推断)
BuildOptions.inputstring \| Record<string, string>✅compilation.input的快捷方式;传字符串时自动以文件名作为入口名
BuildOptions.farmUserConfig❌透传给该次嵌套构建的完整 Farm 配置,可覆盖输出路径、格式、压缩等任意编译选项

input 的两种写法

从源码 resolveFarmConfig 可以看到字符串写法会被自动展开为{ [path.parse(input).name]: input },即:

  • input: 'electron/main.ts'等价于input: { main: 'electron/main.ts' };
  • 若需要多入口主进程(例如多窗口场景),可直接传入Record形式:input: { main: 'electron/main.ts', tray: 'electron/tray.ts' }。

farm 字段的覆盖能力

farm字段会原样合并进该次嵌套构建的配置(resolveFarmConfig返回{ ...opts.farm, configFile: false })。这意味着你可以在其中设置任何 Farm 编译选项,例如:

electron({ main: { input: 'electron/main.ts', farm: { compilation: { output: { path: 'dist-electron', format: 'cjs', }, minify: true, sourcemap: true, }, }, }, })

插件自动注入的默认编译行为

即使你只填写了input,插件也会在 resolveFarmConfig 中为每次嵌套构建注入一组面向 Electron 的默认值。理解这些默认值有助于排查产物异常:

配置项默认值作用与来源
compilation.output.pathdist-electron主进程与 preload 的统一输出目录
compilation.output.targetEnvlibrary以库形式产出,避免被当作 Web 应用打包
compilation.output.formatmain:包类型为module时esm,否则cjs;preload:默认cjs自动适配工程类型(见下文"格式推断")
compilation.output.entryFilenamepreload 且工程为 ESM 时[entryName].mjs,否则[entryName].js匹配 Electron ESM preload 必须以.mjs结尾的约束
compilation.external追加^electron$把electron模块标记为外部依赖,避免被打包进产物
compilation.minify开发模式false,生产构建true与当前 Farm 运行模式联动
compilation.watch开发模式true开发时监听 main / preload 源文件变化
compilation.persistentCachefalse关闭持久化缓存,保证 Electron 产物一致
partialBundling.enforceResourcespreload 构建追加[{ test: ['.+'], name: 'preload' }]强制 preload 的全部模块合并为单个preload文件,确保脚本可被require/加载

格式推断的完整逻辑

源码中的格式推断逻辑(src/index.ts):

if (!opts.farm.compilation.output.format) { opts.farm.compilation.output.format = name === 'preload' ? // In most cases, preload scripts use `cjs` format 'cjs' : isEsm ? 'esm' : 'cjs'; }

其中isEsm来自对项目根目录package.json中"type": "module"的解析(resolvePackageJson)。归纳如下:

  • main 进程:跟随工程类型——package.json声明"type": "module"时产出 ESM(main.js),否则产出 CJS。示例工程 examples/electron/package.json 即"type": "module",因此其 main 产物为 ESM;
  • preload 脚本:绝大多数场景使用cjs;只有当工程为 ESM 时,输出文件扩展名改为.mjs(Electron 官方要求 ESM preload 脚本必须为.mjs扩展名),同时仍以 CJS 格式构建(见 entryFilename 逻辑)。

这也是示例中 preload 的引用写法为preload.mjs的原因(见 electron/main.ts)。

开发模式:一键启动与进程热更新

插件开发模式的完整工作流(来自 configureServer):

  1. Farm 开发服务器启动后,插件把isDev置为true,并在 HTTP 服务listening事件中继续;
  2. 将服务器地址解析为http://localhost:<port>并写入环境变量FARM_DEV_SERVER_URL(resolveServerUrl);
  3. 对main与preload分别执行一次farmBuild(嵌套构建),同时为每次构建注册一个名为:startup的finish钩子插件;
  4. 构建完成后:若为preload,向渲染进程发送full-reload触发整页刷新(preload 脚本热更新);若为main,则通过Starter.start()重启 Electron 主进程(index.ts)。

Starter 类:Electron 进程的启停管理

主进程重启由 Starter 类完成:

  • 通过spawn(electronPath, ['.', '--no-sandbox'], { stdio: 'inherit' })以当前目录启动 Electron(--no-sandbox便于在容器/CI 环境运行);
  • 启动前先exit()杀掉旧进程并移除监听器,避免端口与窗口残留;
  • Electron 退出时同步结束 Farm 命令进程(this.electronApp.once('exit', process.exit));
  • 在进程退出钩子中清理 Electron 子进程,防止僵尸进程。

主进程如何加载开发页面

在 examples/electron/electron/main.ts 中可以看到开发与生产的页面加载分支:

if (process.env.FARM_DEV_SERVER_URL) { win.loadURL(process.env.FARM_DEV_SERVER_URL) win.webContents.openDevTools() } else { win.loadFile(path.join(process.env.DIST, 'index.html')) }

开发模式下直接加载FARM_DEV_SERVER_URL(Farm 开发服务器地址),从而获得 HMR、模块热替换等完整开发体验;生产模式加载打包后的dist/index.html。

渲染进程的环境变量声明

示例工程在 electron/electron-env.d.ts 中为 TypeScript 声明了这三个插件相关环境变量,可照搬到自己的项目中:

declare namespace NodeJS { interface ProcessEnv { DIST: string // 打包目录 dist FARM_PUBLIC: string // /dist/ 或 /public/ FARM_DEV_SERVER_URL?: string // Farm dev server run address } }

生产构建:从编译到打包

生产模式下(farm build),插件走finish钩子(index.ts):跳过开发流程(if (isDev) return),对main与preload依次执行生产构建(自动启用minify: true,见默认值表),产出位于dist-electron目录。

与 Electron Forge 集成打包

示例工程使用 Electron Forge 完成安装包制作(forge.config.cjs),其构建脚本为:

"build": "farm build && electron-forge package"

Forge 配置中的关键点是packagerConfig.ignore: /.*/忽略全部文件,再通过beforeCopy仅复制运行所需的三样内容:

const items = [ 'dist', // 渲染进程产物 'dist-electron', // main + preload 产物 'package.json', // 应用元信息与入口声明 ] for (const item of items) { fs.copySync(path.join(__dirname, item), path.join(buildPath, item)) }

这一设计很干净:只拷贝构建产物与包描述文件,不携带源码与 node_modules,因此最终安装包体积小、结构清晰。同时记得在package.json中把应用入口指向dist-electron/main.js(示例见 examples/electron/package.json)。

正确性验证:仓库 e2e 测试

仓库为 Electron 示例提供了端到端测试 examples/electron/e2e.spec.mjs,它验证了插件的完整链路:

  1. 清理dist与dist-electron后执行farm build完成生产构建;
  2. 通过playwright-chromium的_electron.launch启动 Electron 应用(参数同样带--no-sandbox);
  3. 断言渲染页面标题为Electron + Farm + TypeScript(与 src/main.ts 中的 H1 一致),并对窗口截图保存到 screenshots/app-window.png。

测试同时给出了一个环境提示:Linux 的 CI 环境偶发无法启动 Electron 窗口时,测试会放行通过,避免环境因素误报。

版本与演进

插件当前的发布版本为2.0.0-beta.0(package.json)。从 CHANGELOG.md 可以看到其演进脉络:

  • 1.0.0:新增插件,支持 Farm 开发 Electron 应用;
  • 1.0.1:支持 Electron 产物中的相对路径;
  • 1.0.2:新的import.meta.url运行时,并合并 preload 输出文件(与enforceResources单文件产出对应);
  • 1.0.3:修复依赖被意外标记为外部的问题;
  • 2.0.0-beta.0:随 Farm v2.0.0 发布。

小结

@farmfe/js-plugin-electron用"一次 Farm 命令、两层嵌套构建"的设计,把 Electron 主进程、preload 与渲染进程的开发体验统一到 Farm 的生态里:开发时自动编译、自动拉起/重启 Electron、preload 改动即刷;生产时产出dist-electron供 Forge 等工具直接打包。上手路径建议:参考 examples/electron 完整示例,对照本文的选项表与默认值表理解插件行为,再按需用BuildOptions.farm覆盖默认编译设置。

相关文件索引

  • 插件文档:js-plugins/electron/README-zh-CN.md | 英文版 js-plugins/electron/README.md
  • 插件源码:js-plugins/electron/src/index.ts
  • 完整示例:examples/electron/farm.config.ts、examples/electron/electron/main.ts、examples/electron/electron/preload.ts
  • 打包配置:examples/electron/forge.config.cjs
  • 端到端验证:examples/electron/e2e.spec.mjs
  • 前端构建
  • 构建工具
  • 开发工具

【免费下载链接】farm

Extremely fast Vite-compatible web build tool written in Rust

项目地址:https://gitcode.com/gh_mirrors/fa/farm
点击查看免费下载

相关推荐

上一篇:godropbox 缓存系统深度解析:从本地缓存到分布式存储的完整指南
下一篇:独角数卡支付系统:构建企业级高可用自动售货解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询