跳到主要内容

Js Plugin Api

Farm Js Plugin 设计了类似 rollup 风格的设计插件系统,可以轻松地从 Rollup/Vite/Webpack 迁移您的插件/项目。

配置 Js 插件

通过 plugins 选项添加 JS 插件:

farm.config.ts

编写Js插件

Farm Js 插件是一个普通的 javascript 对象,它公开了一组 hook 。 例如:

my-farm-plugin.ts
备注
  • Farm提供create-farm-plugin工具来帮助您快速创建和开发您的js插件。 有关编写 JS 插件的更多详细信息,请参阅编写 JS 插件

Plugin Hook Overview

Js 插件 Hook 与 Rust 插件相同,请参阅 Rust 插件 Hook 概述

备注

并非所有钩子都暴露给 Js 插件,只有本文档中列出的钩子可用。

hooks

name

  • type: string
  • required: true

该插件的名称,不能为空。

priority

  • type: number
  • required: false
  • default: 100

该插件的优先级,默认为 100priority 控制插件的执行顺序,值越大,插件越早执行。

备注

请注意,大多数 Farm 内部插件(如 plugin-scriptplugin-resolve )的优先级是 99 ,这意味着您的插件始终在内部插件之前执行。 如果您想让您的插件在农场内部插件之后执行,请将 priority 设置为小于 99 的值,例如: 98 。 优先级值也可以为负数,您可以将其设置为 -9999 以确保它始终最后执行。

config

  • type: config?: (config: UserConfig) => UserConfig | Promise<UserConfig>;
  • hook type: serial
  • required: false

config钩子中修改Farm config,返回(部分)修改后的配置,返回的配置将深度合并到从cli和配置文件解析的配置中。 您也可以直接更改配置。

示例:

备注

在解析所有 用户插件 后,会调用 config 钩子,因此在 config 钩子中将新插件添加到配置中无效。

configResolved

  • type: configResolved?: (config: ResolvedUserConfig) => void | Promise<void>;
  • hook type: serial
  • required: false

当配置解析时调用(在调用所有插件的 config 钩子之后)。 当您想要获得插件的最终解析配置时很有用。

示例:

configureDevServer

  • type: configureDevServer?: (server: Server) => void | Promise<void>;
  • hook type: serial
  • required: false
备注

请注意,该钩子仅在开发模式下运行。

Dev Server 准备就绪时调用,您可以获得开发服务器实例。

示例:

备注

js pluginconfigconfigResolved 钩子都会在 rust pluginconfig 钩子之前被调用。

configureCompiler

  • type: configureCompiler?: (compiler: Compiler) => void | Promise<void>;
  • hook type: serial
  • required: false

Rust Compiler 准备好时调用,该钩子在开发和生产中运行。 您可以在此处获取 Compiler 实例

示例:

buildStart

  • type: buildStart?: { executor: Callback<Record<string, never>, void> };
  • hook type: parallel
  • required: false

在编译开始之前调用。 你可以在这里做一些初始化工作。

Example:

备注

buildStart 仅在第一次编译时调用一次。 后期编译如 Lazy CompilationHMR Update 不会触发 buildStart

resolve

  • required: false
  • hook type: first
  • type:
备注

解析钩子的所有过滤器 sourcesimporters 都是 正则字符串

importer 解析自定义 source ,例如从 a.ts resolve ./b

a.ts

那么 resolve 参数将是:

默认的 resolve 结果为:

HookContext 用于在您可以递归挂钩时传递状态,例如,您的插件在 resolve hook 中调用 context.resolve

在上面的例子中,我们调用 context.resolve 并传递 caller 作为参数,然后我们应该添加一个类似 if (hookContext.caller === 'my-plugin') { 的保护以避免无限循环。

注意:

  • 默认情况下,您的resolve hook在Farm内部默认解析器之后执行,只有内部解析器无法解析的源才会传递给您的插件,这意味着如果您想覆盖默认解析器 ,您需要将插件的优先级设置为大于101
  • 通常 resolved_path 是指向文件的真实绝对路径。 但是您仍然可以返回一个 虚拟模块 id ,例如 virtual:my-module ,但是对于虚拟模块,您需要实现 load 钩子来自定义如何加载虚拟模块。 在 Farm 中,resolved_path + query = module_id
  • ResolveKind 表示 import type,示例值:require(由 commonjs require 导入)、cssImport(由 css 的 import 语句导入)等。
  • meta 可以在插件和钩子之间共享,您可以从任何插件中的 loadtransformparse 钩子的参数中获取 meta

load

  • required: false
  • hook type: first
  • type:

自定义如何从已解析的模块路径或模块 ID 加载模块。 例如加载一个虚拟模块:

load 挂钩中加载模块时需要返回 module_typecontentsource_map 是可选的,如果您在 load 钩子中进行转换(不推荐,我们建议在这种情况下使用 transform 钩子)或者从其他位置加载原始源地图,则可以返回源地图。

load hookfilters.resolvedPathresolvedPath + query,例如:/root/src/index.vue?vue&type=style&lang=css。 如果你想在过滤模块时忽略查询,可以使用 $: src/index\\.vue$; 如果你想通过查询来过滤模块,例如过滤 lang=css,可以使用src/index.vue\\.+\\?vue&.+lang=css

transform

  • required: false
  • hook type: serial
  • type:

根据**模块内容模块类型**进行转换。 将 sass 转换为 css 的示例:

编写 transform hook 的正常步骤:

  1. 添加基于 moduleTyperesolvedPathmoduleIdif 保护
  2. 内容 进行转换 3.返回转换后的contentsourceMapmoduleType

对于 ignorePreviousSourceMap ,如果您处理了 param.sourceMapChain 并折叠了 transform hook 中以前插件的源映射。 您应该将 ignorePreviousSourceMap 设置为 true 以确保源映射正确。 否则,您应该始终将此选项设置为 false 并让 Farm 处理源映射链。

对于 filters:

  • 当同时指定 resolvedPathsmoduleTypes 时,取并集。
  • filters.resolvedPathsresolvedPath + query,例如:/root/src/index.vue?vue&type=style&lang=css。 如果你想在过滤模块时忽略查询,可以使用 $: src/index\\.vue$; 如果你想通过查询来过滤模块,例如过滤 lang=css,可以使用src/index.vue\\.+\\?vue&.+lang=css
  • filters.moduleTypes 不是 ** regex,它必须与 ModuleType 完全匹配,如 cssjstsx 等。
备注

transform 钩子是内容到内容。 有一个类似的钩子叫做 process_moduleprocess_moduleast 到 ast。 由于性能问题,Js 插件不支持 process_module 钩子,如果您想要 ast 到 ast 转换,请尝试使用 Rust Plugin

buildEnd

  • type: buildEnd?: { executor: Callback<Record<string, never>, void> };
  • hook type: parallel
  • required: false

ModuleGraph 构建之后、资源渲染和生成开始之前调用。 您可以在此处进行一些状态更新或完成工作。

示例:

备注

buildEnd 仅在第一次编译时调用一次。 稍后编译如Lazy CompilationHMR Update不会触发buildEnd

renderStart

  • type: renderStart?: { executor: Callback<Config['config'], void>; };
  • hook type: parallel
  • required: false

在资源渲染开始之前调用。

示例:

备注

renderStart 仅在第一次编译时调用一次。 稍后编译如 Lazy CompilationHMR Update 将不会触发 renderStart

renderResourcePot

  • required: false
  • hook type: serial
  • type:

Resource Pot 是最终输出的打包后的文件的抽象表示,您可以返回转换后的 resourcePot content 来改变最终的包。 例如渲染CSS:

我们将 css 资源罐中的所有 <--layer--> 进行转换,并将其替换为真正的 css 代码

备注

当同时指定了 filters.moduleIdsfilters.resourcePotTypes 时,取并集。

augmentResourceHash

  • required: false
  • hook type: serial
  • type:

为给定资源罐附加资源哈希。 如果您想在生成资源哈希时添加附加条件,则非常有用。

备注

当同时指定了 filters.moduleIdsfilters.resourcePotTypes 时,取并集。

finalizeResources

  • required: false
  • hook type: serial
  • type:

对所有生成的资源进行一些转换,返回 转换后的resourcesMap 。 您可以在此钩子中 添加删除修改 最终生成的资源。

注意:

  • bytes 是最终输出的二进制,对于 js/css/html 代码,可以使用 Buffer.from(bytes).toString() 来获取代码。
  • name 是最终的文件名。
  • origin 代表这个 Resource 的来源,ResourcePot 表示它是从 ResourcePot 生成的,而 ResourcePot 是一个模块包; Module 表示它来自 Module ,例如 .png/.jpg 等静态文件来自 Module

transformHtml

  • required: false
  • hook type: serial
  • type:

order 控制 transformHtml 执行时机:

  • 0: 代表 pre, 在 parse 之前执行,在这里可以转换原始的 html。
  • 1 and 2: 代表 normal and post, 在 parse 和 generate resources 之后执行. 在这个阶段, 所有的 <script>, <link> 标签都已经被注入。

转换最终生成的html(注入所有<script><link>标签后)。

备注

您应该修改 htmlResourcebytes 字段并返回更新后的 htmlResource ,改变任何其他字段不会产生任何影响

writeResources

  • required: false
  • hook type: serial
  • type:

在所有资源写入磁盘之后调用。

pluginCacheLoaded

  • required: false
  • hook type: serial
  • type:

扩展插件的持久缓存加载。

当启用 持久缓存 时,在命中缓存时可能会跳过 loadtransform 钩子。 如果您的插件依赖于以前的编译结果(例如,基于现有模块加载虚拟模块),您可能需要实现此钩子来加载插件的缓存信息,以确保缓存按预期工作。

示例:

备注

您必须决定如何在插件中将缓存 序列化/反序列化字节 。 作为一个基本示例,您可以通过 [...Buffer.from(JSON.stringify(data))] 反序列化数据

writePluginCache

  • required: false
  • hook type: serial
  • type:

扩展插件的持久缓存写入。 writePluginCache 通常与 pluginCacheLoaded 一起使用来读写插件的持久缓存。 返回数据的序列化字节。

示例:

备注

您必须决定如何在插件中将缓存 序列化/反序列化字节 。 作为一个基本示例,您可以通过 [...Buffer.from(JSON.stringify(data))] 反序列化数据

finish

  • type: finish?: { executor: Callback<Record<string, never>, void> };
  • hook type: parallel
  • required: false

在资源渲染开始之前调用。

例子:

备注

finish 仅在第一次编译时调用一次。 稍后编译,如 Lazy CompilationHMR Update ,不会触发 finish

updateModules

  • required: false
  • hook type: serial
  • type:

调用compiler.update(module_paths)时调用。 对于执行 HMR 时执行一些操作(例如清除以前的状态或忽略某些文件)很有用。

  • paths 是将为此更新重新编译的路径
  • 返回新的paths,后续的编译将更新返回的新路径。
Extremely Fast Web Build Tool Written in Rust

Copyright © 2024 Farm Community. Built with Docusaurus.