☰
Farm 官方插件全景指南:Rust 插件与 JS 插件的选型、配置与源码解析
2026/10/14 8:15:43 网站建设 项目流程
  • 前端构建
  • 构建工具
  • 开发工具

【免费下载链接】farm

Extremely fast Vite-compatible web build tool written in Rust

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

Farm 官方提供了覆盖框架编译、样式处理、资源导入、代码优化与微前端等场景的一整套插件,分为Rust 插件与JS 插件两条产品线,两者共享同一套 Rollup 风格的编译钩子(hooks),在farm.config.ts中用法完全一致。本文以 插件概览 为骨架,逐一梳理 21 个官方 Rust 插件与 13 个官方 JS 插件的功能定位、安装配置方式,并结合仓库源码(rust-plugins 与 js-plugins)深入讲解关键插件的底层实现,帮助你在真实项目中快速选型、正确配置并理解其工作原理。

为什么 Farm 要同时提供 Rust 与 JS 两套插件

Farm 采用完全插件化的架构,插件可以干预编译、解析、转换、依赖分析、资源处理等几乎全部环节。官方同时维护两套编译插件:

  • Rust 插件:用 Rust 编写,直接内联进 Farm 的 Rust 编译管线,不经过 Node.js 桥接,性能最佳,官方明确建议"尽可能使用 Rust 插件";
  • JS 插件:用 JS/TS 编写,主要用于兼容当前庞大的 JS 生态(PostCSS、Less、Babel 等),牺牲部分性能换取生态兼容性。

两者的调用方式完全一致——导入后在plugins字段中以工厂函数形式调用。可参考 使用插件 的说明:

import sass from "@farmfe/plugin-sass"; // Rust 插件 import farmPostcssPlugin from "@farmfe/js-plugin-postcss"; // JS 插件 export default defineConfig({ plugins: [ sass(), // Rust 插件,导入并以函数形式调用 farmPostcssPlugin(), // JS 插件,同样以工厂函数形式配置 ], });

除了这两类编译插件,Farm 还支持vitePlugins配置的 Vite/Rollup/Unplugin 插件、运行时插件(compilation.runtime.plugins)与 SWC 插件(compilation.script.plugins),详见 使用插件。

插件执行顺序与过滤器

两个与所有官方插件都相关的通用机制值得先了解:

  • priority控制执行顺序:数值越大越先执行,Farm 内部插件默认优先级为100。例如@farmfe/plugin-sass在源码中显式声明priority() { 101 },注释写明"此插件应在内部插件之前执行"(rust-plugins/sass/src/lib.rs);而@farmfe/plugin-react优先级为99(rust-plugins/react/src/lib.rs)。如果你需要调整官方插件的执行时机,可在 JS 插件对象上覆写priority。
  • filters过滤器:官方 JS 插件均要求配置过滤器(如resolvedPaths、moduleTypes),不匹配的模块根本不会触发 JS 钩子,从而把性能开销留在 Rust 侧,最大化编译速度。

官方 Rust 插件(21 个)

框架编译:React 与 Vue

@farmfe/plugin-react:支持 Reactjsx编译与react-refresh热更新。安装后即可在配置中启用:

import { UserConfig } from '@farmfe/core'; import react from '@farmfe/plugin-react'; const config: UserConfig = { plugins: [react({ /* options here */ })] }

配置项与 SWC 的jsc.transform.react一致,可参考其文档。从源码(rust-plugins/react/src/lib.rs)可以看到其关键行为:

  • 通过swc_transform_react调用 SWC 完成 JSX/TSX 转换,仅处理Jsx/Tsx模块类型;
  • 开发模式下自动注入 React Refresh:enable_react_refresh由is_dev && refresh.unwrap_or(true)决定,可通过refresh: false关闭;当output.target_env不是浏览器环境时(如 SSR、Node),会强制关闭 refresh(源码 L48-L51);
  • 提供useAbsolutePath选项控制模块文件名是否使用绝对路径(默认false,L59);
  • 在analyze_deps阶段向 HTML 模块头部插入一个全局注入模块(GLOBAL_INJECT_MODULE_ID),确保 React Refresh 运行时最先执行(L180-L193)。

@farmfe/plugin-vue:使用fervidRust 编译器编译 Vue 3 单文件组件(SFC)。对应源码目录为 rust-plugins/vue,配合@farmfe/js-plugin-postcss等样式插件可完整编译 Vue 单文件组件。

样式编译:Sass 与 TailwindCSS

@farmfe/plugin-sass:支持编译sass/scss文件,底层使用grass(Rust 版 Sass 编译器),并提供additionalData选项在每个 Sass 文件头部追加内容,例如@import '@/styles/variables.scss';(详见 sass.mdx)。

其源码实现(rust-plugins/sass/src/lib.rs)值得细读:

  • 在config钩子中自动把sass、scss追加到config.resolve.extensions,无需手动配置扩展名(L271-L281);
  • load钩子将.sass/.scss文件标记为ModuleType::Custom("sass")(L283-L302),transform钩子中调用grass::from_path编译为 CSS(L304-L355);
  • 除additionalData外,还支持charset、quietDeps、style(expanded/compressed)等选项,并依据文件后缀自动选择InputSyntax::Sass或 SCSS 语法(L358-L383);
  • 通过自定义FarmFs实现 Sass@import解析(支持@/别名、_前缀 partial 自动补全),并调用rebase_urls重写 url 相对路径,同时把被引用的依赖文件注册到 Farm 的 watch 图,保证开发模式下依赖变更能正确触发重建(L127-L174)。

@farmfe/plugin-tailwindcss:基于 Rust 的 TailwindCSS 集成。仓库中同时维护了 rust-plugins/tailwindcss(Rust 插件)与 rust-ecosystem/tailwindcss(编译内核)两处实现,另有配套示例 examples/tailwindcss-rust-plugin。

资源与数据文件:SVG、WASM、Worker、URL、Image、DSV、YAML

  • @farmfe/plugin-svgr:将 SVG 文件转换为 React 组件,仓库实现位于 rust-plugins/svgr,示例见 examples/rust-plugin-svgr;
  • @farmfe/plugin-wasm:支持 WebAssembly 与wasm-pack生成的模块,实现位于 rust-plugins/wasm,示例见 examples/rust-plugin-wasm;
  • @farmfe/plugin-worker:支持通过构造函数和?worker查询后缀使用 Web Worker,实现位于 rust-plugins/worker,示例见 examples/rust-plugin-worker;
  • @farmfe/plugin-url:将文件作为 data URI 或产物资源 URL 导入,实现位于 rust-plugins/url,示例见 examples/rust-plugin-url;
  • @farmfe/plugin-image:将图片文件作为 base64 data URI 或 DOMImage导出导入,实现位于 rust-plugins/image,示例见 examples/rust-plugin-image;
  • @farmfe/plugin-dsv:将.csv和.tsv文件转换为 JavaScript 模块,需要 Node LTS(v18.0.0+)与 Farm v1.0.0+。启用后可直接importCSV 文件并得到一个对象数组(详见 dsv.mdx):
// farm.config.js import { defineConfig } from '@farmfe/core'; import dsv from '@farmfe/plugin-dsv'; export default defineConfig({ plugins: [dsv()], });
import fruit from './fruit.csv'; console.log(fruit); // [ { type: 'apples', count: '7' }, { type: 'pears', count: '4' }, { type: 'bananas', count: '5' } ]
  • @farmfe/plugin-yaml:将 YAML 文件转换为 ES6 模块,受@rollup/plugin-yaml启发(详见 yaml.mdx):
import { defineConfig } from '@farmfe/core'; import yaml from '@farmfe/plugin-yaml'; export default defineConfig({ plugins: [ yaml({ documentMode: 'single' | 'multi', // 默认 single include: Regex, // 默认 None exclude: Regex, // 默认 None }), ], });

注意include/exclude使用的是正则表达式而非 glob,例如匹配01.yaml应写".*\\/01.yaml",**/01.yaml这种写法不合法。

代码优化与工程化:Compress、Strip、Replace-Dirname、Modular-Import、Virtual、Auto-Import、Dts、Icons、MDX、React-Components

  • @farmfe/plugin-compress:使用 Brotli、Gzip、Deflate 或 DeflateRaw 压缩生成的资源,实现位于 rust-plugins/compress,示例见 examples/rust-plugin-compress;

  • @farmfe/plugin-strip:从代码中移除debugger语句和assert.equal、console.log这类函数调用(详见 strip.mdx)。其源码(rust-plugins/strip/src/lib.rs)展示了典型的 Rust 插件实现方式:先用正则做第一遍快速过滤(first_pass_filter),命中后再用 SWC 解析 AST,通过VisitMut访问器把命中的函数调用替换为(void 0)表达式、删除Debugger语句和指定标签的 labeled 语句(L181-L263),并按需生成 source map。核心选项如下:

    选项类型默认值说明
    includeString | RegExp | Array['**/*.js']指定处理的文件模式
    excludeString | RegExp | Array[]指定忽略的文件模式(源码中默认排除node_modules/.*)
    debuggerBooleantrue是否移除debugger语句
    functionsArray<String>['console.*', 'assert.*']目标移除的函数调用
    labelsArray<String>[]目标移除的带标签块/语句(:**隐含,无需配置)
    sourceMapBooleantrue移除代码后是否更新 source map
    export default defineConfig({ plugins: [ strip({ functions: ['console.*', 'assert.*'], labels: ['unittest'] }) ], });

    注意:指定链开头的函数(如'a().b().c()')会得到(void 0).b().c(),运行时可能报错,应避免。

  • @farmfe/plugin-replace-dirname:在脚本模块中替换__dirname、__filename和import.meta.url,实现位于 rust-plugins/replace-dirname;

  • @farmfe/plugin-modular-import:将 UI 库的具名导入转换为按组件导入,实现位于 rust-plugins/modular-import,示例见 examples/rust-plugin-modular-import;

  • @farmfe/plugin-virtual:方便在 Farm 中使用虚拟模块(详见 virtual.mdx):

// farm.config.ts import { defineConfig } from '@farmfe/core'; import virtual from '@farmfe/plugin-virtual'; export default defineConfig({ plugins: [ virtual({ 'virtual-module': 'export const a = 1', 'src/01.js': 'export const module01 = "virtual-module"', }), ], });
// index.js import { a } from 'virtual-module';

这些模块不对应任何真实文件,但可像普通模块一样被导入,特别适合模拟第三方库、环境变量等不便于落盘的数据。

  • @farmfe/plugin-auto-import:从预设和本地导出中扫描并自动注入导入,实现位于 rust-plugins/auto-import,示例见 examples/rust-plugin-auto-import-react 与 examples/rust-plugin-auto-import-vue;
  • @farmfe/plugin-dts:为匹配的 TypeScript 模块生成.d.ts文件,实现位于 rust-plugins/dts;
  • @farmfe/plugin-icons:按需使用 Iconify 图标作为框架组件,实现位于 rust-plugins/icons,示例见 examples/rust-plugin-icons-react 与 examples/rust-plugin-icons-vue;
  • @farmfe/plugin-mdx:将.md和.mdx文件编译为 JSX,实现位于 rust-plugins/mdx;
  • @farmfe/plugin-react-components:用于 React 的按需组件自动导入(详见 react-components.mdx)。启用后无需手写import与组件注册:
// 转换前 export function Main() { return <HelloWorld msg="Hello React + Farm" /> }
// 自动转换为 import HelloWorld from './src/components/HelloWorld' export function Main() { return <HelloWorld msg="Hello React + Farm" /> }

该插件默认扫描src/components目录,核心配置包括:

{ dirs: ['src/components'], // 搜索组件的目录(相对路径) resolvers: [], // 自定义组件的解析器 import_mode: "Absolute", // 组件导入方式:绝对或相对路径 local: true, // 是否对本地组件生效 importStyle: false, // 是否导入 style/index.js,也接受自定义路径 dts: true, // 生成全局声明 components.d.ts(安装了 typescript 时默认 true) include: ["src/components"], exclude: ["node_modules"], }

它还内置了Ant Design、Arco Design、Material UI等流行 UI 库的解析器(通过resolvers: [{ module: "antd", prefix: "Ant" }]启用),并支持树摇——只注册实际使用的组件。生成的components.d.ts需要加入tsconfig.json的include。源码位于 rust-plugins/react-components,示例见 examples/rust-plugin-react-components。

官方 JS 插件(13 个)

JS 插件用于兼容现有 JS 生态工具,官方当前提供以下 13 个:

插件功能仓库源码
@farmfe/js-plugin-postcss在项目中使用 PostCSSjs-plugins/postcss
@farmfe/js-plugin-babel对匹配的 Farm 模块运行 Babeljs-plugins/babel
@farmfe/js-plugin-copy构建结束时复制文件和 glob 匹配结果js-plugins/copy
@farmfe/js-plugin-less支持编译less文件js-plugins/less
@farmfe/js-plugin-svgr将 SVG 文件编译为组件js-plugins/svgr
@farmfe/js-plugin-dts生成*.d.ts类型声明文件js-plugins/dts
@farmfe/js-plugin-sass支持编译sass/scss文件js-plugins/sass
@farmfe/js-plugin-tailwindcssTailwindCSS 集成js-plugins/tailwindcss
@farmfe/js-plugin-visualizer可视化分析产物大小与组成js-plugins/visualizer
@farmfe/js-plugin-electron支持构建 Electron 应用js-plugins/electron
@farmfe/js-plugin-qiankun将 Farm 应用暴露为 qiankun 微应用js-plugins/qiankun
@farmfe/js-plugin-react-compiler通过 Babel 为 JSX/TSX 模块运行 React Compilerjs-plugins/react-compiler
@farmfe/js-plugin-vuetify支持 Vuetify 自动导入和样式解析js-plugins/vuetify

PostCSS:最常用的样式后处理插件

@farmfe/js-plugin-postcss支持 PostCSS 的前置编译工作(详见 js-postcss.mdx),安装时需要同时安装postcss:

pnpm add @farmfe/js-plugin-postcss postcss
import { UserConfig } from '@farmfe/core'; import farmJsPluginPostcss from '@farmfe/js-plugin-postcss'; const config: UserConfig = { plugins: [farmJsPluginPostcss({ /* options */ })] }

其选项类型定义(可对照源码 js-plugins/postcss/src/index.ts):

export type PostcssPluginOptions = { postcssLoadConfig?: { ctx?: postcssLoadConfig.ConfigContext; path?: string; // 默认 farm.config.js 所在目录 options?: Parameters<typeof postcssLoadConfig>[2]; }; filters?: { resolvedPaths?: string[]; moduleTypes?: string[]; }; implementation?: string; // 默认 'postcss' };

三个选项的实践要点:

  • postcssLoadConfig:Farm 使用postcss-load-config加载 PostCSS 配置,可通过path指定配置文件所在目录,例如从client/postcss.config.js加载:
farmJsPluginPostcss({ postcssLoadConfig: { path: path.join(process.cwd(), 'client') } })
  • filters:控制哪些文件由 PostCSS 处理,默认{ moduleTypes: ['css'] }。resolvedPaths与moduleTypes取并集。注意:less/sass 文件应先由@farmfe/js-plugin-less/@farmfe/plugin-sass处理,再进入 PostCSS 管线。
  • implementation:PostCSS 实现包名,默认postcss。

Less 与 Sass 的 JS 版插件

@farmfe/js-plugin-less(详见 js-less.mdx)的选项结构:

export type LessPluginOptions = { lessOptions?: Less.Options; // 参见 Less 官方文档 implementation?: string; // 默认 'less' filters?: { resolvedPaths?: string[]; moduleTypes?: string[]; }; additionalData?: string | ((context?: string, resolvePath?: string) => string | Promise<string>); };

lessOptions可配置 Less 编译路径,例如:

farmJsPluginLess({ lessOptions: { paths: [path.resolve(process.cwd(), 'styles')] } })

additionalData支持字符串与函数两种形式,字符串形式会在每个 less 文件头部注入内容(例如公共变量文件@import "./src/styles/variables.less";),函数形式则可以基于content/resolvePath按文件差异化注入。加载阶段的默认过滤器为{ resolvedPaths: ['\\.less$'] },转换阶段为{ moduleTypes: ['less'] }。

@farmfe/js-plugin-sass(详见 js-sass.mdx)比 Rust 版多提供globals选项——全局 Sass 文件列表,等价于additionalData但更便捷;implementation可切换为sass-embedded(需手动安装sass-embedded);sassOptions支持loadPaths等官方 Sass JS API 选项。

DTS 类型声明生成

@farmfe/js-plugin-dts专为工具库构建设计,为 TS 代码生成.d.ts(详见 js-dts.mdx)。其完整选项如下:

export interface DtsPluginOptions { root?: string; // 依赖根目录 outputDir?: string | string[]; // 声明文件输出目录 entryRoot?: string; // 入口文件的根路径 compilerOptions?: ts.CompilerOptions | null; // ts-morph 初始化使用的编译选项 tsConfigPath?: string; // ts-morph 初始化使用的 tsconfig.json 路径 include?: string | string[]; // include glob exclude?: string | string[]; // exclude glob copyDtsFiles?: boolean; // 是否将源 .d.ts 复制到输出目录,默认 false noEmitOnError?: boolean; // 有诊断错误时是否不输出,默认 false skipDiagnostics?: boolean; // 是否跳过 TS 诊断,默认 true libFolderPath?: string; // 自定义 TypeScript lib 文件夹路径 afterDiagnostic?: (diagnostics: Diagnostic[]) => void | Promise<void>; }

SVG 编译:js-svgr 与 Rust 版 svgr

@farmfe/js-plugin-svgr(详见 js-svgr.mdx)支持svgrOptions(参见 SVGR 官方选项)与filters(默认{ resolvedPaths: ['\\.svg$'] }),适合需要深度自定义 SVGR 行为的场景;如果只需要基础的"SVG 转 React 组件",优先选择性能更好的 Rust 版@farmfe/plugin-svgr。

其余 JS 插件速览

  • @farmfe/js-plugin-babel:对匹配的模块运行 Babel,适合依赖 Babel 插件生态的存量项目(js-plugins/babel);
  • @farmfe/js-plugin-copy:构建结束后复制文件,支持 glob 匹配(js-plugins/copy);
  • @farmfe/js-plugin-visualizer:可视化分析产物体积与组成,源码含 Vue 前端(js-plugins/visualizer);
  • @farmfe/js-plugin-electron:支持构建 Electron 应用,示例见 examples/electron;
  • @farmfe/js-plugin-qiankun:将 Farm 应用暴露为 qiankun 微应用(js-plugins/qiankun);
  • @farmfe/js-plugin-react-compiler:通过 Babel 为 JSX/TSX 运行 React Compiler(js-plugins/react-compiler);
  • @farmfe/js-plugin-vuetify:Vuetify 自动导入与样式解析(js-plugins/vuetify)。

社区插件与 Vite/Rollup 生态兼容

如果官方插件不能满足需求,可以转向 社区插件:

  • Farm 社区插件:例如farm-pulgin-strip等由社区维护的 Rust 插件;
  • Vite/Rollup 插件开箱即用:Farm 兼容 Vite 插件,通过farm.config.ts的vitePlugins字段直接配置,例如@vitejs/plugin-vue、@vitejs/plugin-vue-jsx、vite-plugin-solid、vite-plugin-mock等:
import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; const config: UserConfig = { vitePlugins: [vue(), vueJsx()] }
  • unplugin 生态:可通过unplugin/vite或unplugin/rollup使用几乎所有 unplugin 插件(unplugin-auto-import、unplugin-vue-components、unplugin-icons、unplugin-element-plus等),官方文档还提供了使用vitePlugins配置 unplugin 的完整示例。

此外,官方还维护了 awesome-farm 插件列表仓库,如果你开发了兼容 Farm 的插件,也可以通过 PR 提交到该列表。

官方插件实战选型建议

综合本文对官方插件的梳理,可以给出如下选型思路:

  1. 优先使用 Rust 插件:凡是官方已提供 Rust 实现的场景(React、Vue、Sass、SVG、WASM、Worker、URL、Image、DSV、YAML、Strip、Virtual、Auto-Import 等),都应优先采用,以获得最佳编译性能;
  2. JS 插件用于生态桥接:PostCSS、Less、Babel 这类依赖 JS 生态工具的流程,使用对应的官方 JS 插件;样式链路上注意处理顺序——less/sass 先编译,再由 PostCSS 做后处理;
  3. 善用priority与filters:需要调整插件执行顺序时覆盖priority;给 JS 插件配置精确的filters,可以显著减少不必要的 JS 钩子调用,保住 Rust 侧的高性能编译管线;
  4. 复用 Vite/Rollup 生态:官方插件覆盖不到的 Vite 插件、unplugin 插件可直接通过vitePlugins引入,无需迁移成本。

延伸阅读

  • 插件概览(本指南出处)
  • 使用插件(配置方式、优先级、运行时插件、SWC 插件)
  • 社区插件(Vite/Rollup/unplugin 兼容用法)
  • 编写插件(Rust 插件与 JS 插件开发指南)
  • Rust 插件源码:rust-plugins;JS 插件源码:js-plugins
  • 官方插件配套示例:见 examples 目录下的rust-plugin-*与sass-plugin-rust、tailwindcss-rust-plugin等示例项目
  • 前端构建
  • 构建工具
  • 开发工具

【免费下载链接】farm

Extremely fast Vite-compatible web build tool written in Rust

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

相关推荐

上一篇:ZeroClaw 持有型 crate 例外治理全解析:ADR-016 如何为运行时拆解流程补齐"有边界的例外"
下一篇:CANN runtime 仓库 AI 化代码审查规则详解:从规范加载到 Error Message 专项检视

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

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

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

立即咨询