跳到主要内容

Rust Plugin Api

备注

本文档仅涵盖插件钩子详情。 有关如何创建、构建和发布 rust 插件,请参阅:编写 Rust 插件

配置 Rust 插件​

通过 plugins 选项添加 Rust 插件:

farm.config.ts

在字符串中配置 Rust 插件包名称(或路径),并在对象中配置其选项。

编写 Rust 插件​

有关详细信息,请参阅编写 Rust 插件。

插件 Hook 概述​

Farm 提供了很多 rollup 风格的 hook,这些 hook 分为 build 阶段和 generate 阶段: Farm 插件 钩子

所有插件挂钩都接受一个名为 CompilationContext 的参数。 所有共享的编译信息都存储在 context 中。

Hook 共有三种(与 Rollup 相同):

  • first:钩子串行执行,当钩子返回非空值时立即返回。 (null 在 JS 中表示 null 和 undefined,在 Rust 中表示 None)。
  • serial: 钩子串行执行,每个钩子的结果将传递到下一个钩子,使用最后一个钩子的结果作为最终结果。
  • parallel:钩子在线程池中并行执行,并且应该被隔离。
备注

有关完整的 Plugin Hooks 定义,请参阅Plugin Trait

name​

  • required: true
  • default:

返回此插件的名称。 例子:

priority​

  • required: false
  • default:

定义该插件的优先级,值越大,该插件越早执行。 当插件具有相同优先级时,它们将按照与plugins中注册的顺序相同的顺序执行。

备注

默认情况下,所有自定义插件的优先级都是 100。有些内部插件的优先级是 99,比如 plugin-script、plugin-css,您可以覆盖默认优先级时内部插件的行为。 但是一些内部插件的优先级是101,比如plugin-resolve,plugin-html,如果你想覆盖默认行为,你应该设置一个更大的优先级。

config​

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

在编译开始之前在config钩子中修改配置。 Config 结构体的定义请参考Config。 例子:

请注意, Rust Plugin 的 config 钩子是在 JS Plugin 的 config 和 configResolved 钩子之后调用的。

plugin_cache_loaded​

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

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

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

例子:

注意:

  • deserialize 由 farmfe_core 导出,它可以帮助您反序列化 Vec<u8> 中的结构体或枚举。
  • 缓存的结构体或枚举必须是rkyv可序列化的,您可以使用farmfe_core公开的#[cache_item]快速创建可缓存的结构体。

build_start​

  • required: false
  • hook type: parallel
  • default:

在第一次编译开始之前调用。 您可以使用此挂钩来初始化插件的任何初始状态。

备注

build_start 仅在第一次编译时调用一次。 如果你想在HMR或Lazy Compilation中更新ModuleGraph时做一些事情,你应该使用update_modules钩子。

resolve​

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

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

a.ts

那么解析参数将是:

默认解析器的解析结果为:

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

在上面的示例中,我们调用 context.plugin_driver.resolve 并将 caller 作为参数传递,然后我们应该添加一个类似 if caller.as_str() == "FarmPluginCss" 的保护以避免无限循环。

注意:

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

load​

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

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

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

transform​

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

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

编写 transform hook 的正常步骤:

  1. 添加基于 module_type 或 resolved_path 或 module_id 的 if 保护
  2. 对 内容 进行转换 3.返回转换后的content、source_map和module_type

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

备注

transform 钩子是内容到内容。 有一个类似的钩子叫做 process_module , process_module 是ast to ast。 所以如果你想转换加载的内容字符串,你需要使用transform钩子,如果你想转换ast,你应该使用process_module钩子。

parse​

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

将**转换后的模块内容**解析为ast。 Farm 原生支持 Js/Jsx/Ts/Tsx、css 和 html。 通常你不需要实现这个钩子,除非你想支持除了Js/Jsx/Ts/Tsx、css和html之外的新的module_type,在这种情况下使用ModuleMetaData::Custom。

process_module​

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

对解析结果进行变换,通常做**ast变换**。 例如,Farm 将 ts 转换成 js:

在上面的示例中,我们忽略非脚本模块,并且去掉 ts/tsx 模块的 ast 中类型信息。

analyze_deps​

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

分析模块的依赖关系。 例如,我们有 a.ts :

a.ts

那么通常这个钩子应该将2个条目推送到params.deps:

param.deps 稍后将传递给 resolve 钩子。 您还可以根据需要添加与模块的 ast 不相关的新 deps,Farm 将 resolve 、 load 这些不相关的模块并将它们添加到模块图中。

finalize_modules​

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

在密封模块之前做任何你想做的事情。 请注意,您只能修改 param.module 。

build_end​

  • required: false
  • hook type: parallel
  • default:

当从config.input开始的所有依赖都被处理并且ModuleGraph被成功构建时调用,您可以通过context.module_graph在这里获得完整解析的ModuleGraph。

备注

build_end 仅在第一次编译时调用一次。 如果你想在HMR或Lazy Compilation中更新ModuleGraph时做一些事情,你应该使用module_graph_updated钩子。

generate_start​

  • required: false
  • hook type: parallel
  • default:

在生成阶段开始之前调用。

optimize_module_graph​

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

您可以在此处对 module_graph 进行优化。 对于内部插件,Farm 在这个钩子中进行树摇动和缩小。

analyze_module_graph​

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

分析module_graph的**动态导入,并根据动态导入**对模块进行分组,返回分组后的模块。

注意

通常你不应该实现这个钩子,除非你想在 Farm 中实现一个全新的打包算法。

partial_bundling​

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

基于 module_group_graph 和 module_graph 将 modules 打包到 Vec<ResourcePot> 。 ResourcePot 是 Farm 用于保存打包模块的结构,它将被生成到 generate_resources 钩子中的最终资源,您可以将 ResourcePot 视为其他工具的 Chunk。

注意:

  • 该钩子会在 首次编译 、 HMR 和 延迟编译 中被调用,请确保该钩子不包含副作用(对于相同的模块,始终返回相同的 Vec<ResourcePot> )。
  • 你应该在这个钩子中设置module.resource_pot。

请参阅 Farm 中部分捆绑的内部实现以获得最佳实践。 请参阅 RFC-003 部分捆绑 了解 Farm 如何设计捆绑。

注意

通常你不应该实现这个钩子,除非你想在 Farm 中实现一个全新的打包算法。 如果您覆盖此挂钩,除非您遵循与 Farm 相同的打包规范,否则 config.partial_bundling 可能无法工作。

process_resource_pots​

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

对 ResourcePots 进行一些转换。 注意,此时ResourcePots还没有渲染,这意味着你无法获取ResourcePot的渲染代码,只能添加,删除,改造ResourcePot内部的模块

render_start​

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

在 resource pot 渲染之前调用。 渲染 resource pot 后,将产出可执行的 html 、 css 、 js 等文件。

备注

render_start 仅在第一次编译时调用一次。 HMR 或 Lazy Compilation 不会触发 render_start 钩子。

render_resource_pot_modules​

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

将给定的 ResourcePot 渲染为 rendered_content 和 rendered_source_map_chain 。 该钩子用于将 模块的 ast 渲染为打包代码。 如果您只想修改打包代码,请改用 render_resource_pot。

如果您确实需要使用此钩子,请参阅 plugin_runtime 以获得最佳实践。

备注

通常,您不应该为原生支持的模块类型(如 js/jsx/ts/tsx/css/html )覆盖此钩子,只有当您确保要覆盖 Farm 中内部模块类型的默认行为时,才应该使用此钩子, 或者您想支持自定义模块类型。

render_resource_pot​

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

转换给定 ResourcePot 的渲染捆绑代码。 返回 渲染内容 和 source map 。

在上面的示例中,我们转换了 css Resource Pot 的内容,将所有 <--layer--> 替换为 replaced_code。

augment_resource_hash​

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

从给定 resource pot 生成资源时附加额外哈希。

optimize_resource_pot​

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

对渲染的 resource pot 进行一些优化。 例如,替换、压缩等等。 如果要修改此钩子的渲染内容,只需修改 resource_pot.meta.rendered_content 并将此转换的 source map 附加到 resource_pot.meta.rendered_source_map_chain 中。

备注

像压缩这样的优化是由 Farm 内部处理的,请确保您确实需要使用这个钩子。

generate_resources​

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

为给定的渲染 resource pot 生成最终资源。 返回 生成的资源 和 可选的 source map 。

备注

对于原生支持的 ModuleTypes ,如 js/ts/jsx/tsx/css/html/static assets ,通常不需要实现此钩子。 当您想要支持 Farm 本身不支持的新型资源时,请使用此钩子。

finalize_resources​

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

对生成的资源进行一些最终的处理工作,例如根据生成的资源转换html(插入<script>、<link>标签)。

您还可以在此处 添加 或 删除 资源。

generate_end​

  • required: false
  • hook type: parallel
  • default:

当所有生成阶段完成时调用(包括 finalize_resources )。 您可以在这里做一些清理工作。

finish​

  • required: false
  • hook type: parallel
  • default:

当所有编译工作完成时调用(包括 构建阶段 和 生成阶段 )。 您可以在这里做一些清理工作。

备注

finish 仅在第一次编译时调用一次。 HMR 或 Lazy Compilation 不会触发 finish 钩子。 您应该使用 update_finished 钩子代替。

write_plugin_cache​

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

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

例如,为静态资源写入缓存:

update_modules​

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

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

  • paths 是将为此更新重新编译的路径
  • 返回新的paths,后续编译将更新返回的新路径。

module_graph_updated​

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

调用compiler.update(module_paths)时调用。 对于执行一些操作(例如修改模块图)很有用。

update_finished​

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

调用compiler.update(module_paths)时调用。 该钩子在所有编译工作完成后调用,包括资源重新生成和最终处理。

handle_persistent_cached_module​

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

当启用持久缓存并且模块的缓存命中时调用。 返回 true 以跳过加载此模块的缓存。

Extremely Fast Web Build Tool Written in Rust

Copyright © 2024 Farm Community. Built with Docusaurus.