- 前端构建
- 构建工具
- 开发工具
【免费下载链接】farm
Extremely fast Vite-compatible web build tool written in Rust
导读
本指南围绕 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 的源码注释与实现为准):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
main | BuildOptions | ✅ | 主进程构建配置,对应最终产出dist-electron/main.js |
preload | BuildOptions | ❌ | preload 脚本构建配置,对应最终产出dist-electron/preload.js(或.mjs,见下文格式推断) |
BuildOptions.input | string \| Record<string, string> | ✅ | compilation.input的快捷方式;传字符串时自动以文件名作为入口名 |
BuildOptions.farm | UserConfig | ❌ | 透传给该次嵌套构建的完整 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.path | dist-electron | 主进程与 preload 的统一输出目录 |
compilation.output.targetEnv | library | 以库形式产出,避免被当作 Web 应用打包 |
compilation.output.format | main:包类型为module时esm,否则cjs;preload:默认cjs | 自动适配工程类型(见下文"格式推断") |
compilation.output.entryFilename | preload 且工程为 ESM 时[entryName].mjs,否则[entryName].js | 匹配 Electron ESM preload 必须以.mjs结尾的约束 |
compilation.external | 追加^electron$ | 把electron模块标记为外部依赖,避免被打包进产物 |
compilation.minify | 开发模式false,生产构建true | 与当前 Farm 运行模式联动 |
compilation.watch | 开发模式true | 开发时监听 main / preload 源文件变化 |
compilation.persistentCache | false | 关闭持久化缓存,保证 Electron 产物一致 |
partialBundling.enforceResources | preload 构建追加[{ 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):
- Farm 开发服务器启动后,插件把
isDev置为true,并在 HTTP 服务listening事件中继续; - 将服务器地址解析为
http://localhost:<port>并写入环境变量FARM_DEV_SERVER_URL(resolveServerUrl); - 对
main与preload分别执行一次farmBuild(嵌套构建),同时为每次构建注册一个名为:startup的finish钩子插件; - 构建完成后:若为
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,它验证了插件的完整链路:
- 清理
dist与dist-electron后执行farm build完成生产构建; - 通过
playwright-chromium的_electron.launch启动 Electron 应用(参数同样带--no-sandbox); - 断言渲染页面标题为
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
相关推荐
用 Farm 构建 Electron 应用:@farmfe/js-plugin-electron 插件安装、配置与双进程构建全指南
用 Farm 构建 Electron 应用:@farmfe/js plugin electron 插件安装、配置与双进程构建全指南 Farm 是一个用 Rust
前端构建构建工具开发工具用 uv 重塑 Python 依赖管理:agents24 仓库中的现代 Python 项目工作流实战指南
用 uv 重塑 Python 依赖管理:agents24 仓库中的现代 Python 项目工作流实战指南 导读 本文以 agents24 仓库中 uv pack
前端构建构建工具开发工具command-line-args在微服务架构中的应用:分布式CLI工具开发
command line args在微服务架构中的应用:分布式CLI工具开发 在微服务架构中,分布式CLI工具开发面临着多服务协同、参数统一管理和跨环境配置等挑
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考