跳到主要内容

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-scriptplugin-css,您可以覆盖默认优先级时内部插件的行为。 但是一些内部插件的优先级是101,比如plugin-resolveplugin-html,如果你想覆盖默认行为,你应该设置一个更大的优先级。

config

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

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

请注意, Rust Pluginconfig 钩子是在 JS PluginconfigconfigResolved 钩子之后调用的。

plugin_cache_loaded

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

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

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

例子:

注意:

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

build_start

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

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

备注

build_start 仅在第一次编译时调用一次。 如果你想在HMRLazy 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 可以在插件和钩子之间共享,您可以从任何插件中的 loadtransformparse 钩子的参数中获取 meta

load

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

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

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

transform

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

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

编写 transform hook 的正常步骤:

  1. 添加基于 module_typeresolved_pathmodule_idif 保护
  2. 内容 进行转换 3.返回转换后的contentsource_mapmodule_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_moduleprocess_moduleast to ast。 所以如果你想转换加载的内容字符串,你需要使用transform钩子,如果你想转换ast,你应该使用process_module钩子。

parse

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

将**转换后的模块内容**解析为ast。 Farm 原生支持 Js/Jsx/Ts/Tsxcsshtml。 通常你不需要实现这个钩子,除非你想支持除了Js/Jsx/Ts/Tsxcsshtml之外的新的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 将 resolveload 这些不相关的模块并将它们添加到模块图中。

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 仅在第一次编译时调用一次。 如果你想在HMRLazy 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_graphmodule_graphmodules 打包到 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 后,将产出可执行的 htmlcssjs 等文件。

备注

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

render_resource_pot_modules

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

将给定的 ResourcePot 渲染为 rendered_contentrendered_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 仅在第一次编译时调用一次。 HMRLazy 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.