转换器

转换器插件转换单个资产以编译它,发现依赖项或将其转换为不同的格式。许多转换器是围绕其他工具(如编译器和预处理器)的包装器,负责将它们与 Parcel 集成。

转换资产

#

必须传递给 Transformer 构造函数的一个必需函数是:transform。此函数接收一个 MutableAsset 对象,该对象表示一个文件。可以检索资产的源代码或内容,以及任何关联的源映射(参见下文)。然后,转换器可以以某种方式转换此内容,并将编译后的结果设置回资产。

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
// Retrieve the asset's source code and source map.
let source = await asset.getCode();
let sourceMap = await asset.getMap();

// Run it through some compiler, and set the results
// on the asset.
let {code, map} = compile(source, sourceMap);
asset.setCode(code);
asset.setMap(map);

// Return the asset
return [asset];
}
});

加载配置

#

从用户的项目加载配置应该在 Transformer 插件的 loadConfig 方法中完成。有关如何执行此操作的详细信息,请参见 加载配置

注意:使用 Parcel 的配置加载机制非常重要,以便可以正确地使缓存失效。避免直接从文件系统加载文件。

更改资产类型

#

转换器可以将资产从一种格式转换为另一种格式,例如从 TypeScript 转换为 JavaScript。为此,将资产的 type 属性设置为新的文件类型(例如 js)。然后,资产将由与新类型匹配的管道处理。有关详细信息,请参见 Parcel 配置文档中的 转换器

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let code = await asset.getCode();

let result = compile(code);
asset.type = 'js';
asset.setCode(result);

return [asset];
}
});

环境

#

资产与一个 Environment 相关联,该环境描述了如何编译资产。同一个资产可能会使用不同的环境进行多次处理,例如,在为现代和传统目标构建时。如果可能,Transformer 插件在编译代码时应考虑环境,以确保结果在目标中有效并针对目标进行了优化。有关详细信息,请参见 目标

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let code = await asset.getCode();

let result = asset.env.isBrowser()
? compileForBrowser(code, asset.engines.browser)
: compileForNode(code, asset.engines.node);

asset.setCode(result);
return [asset];
}
});

有关可用属性的详细信息,请参见 Environment API 文档。

添加依赖项

#

除了转换资产的内容外,Transformer 插件还负责发现代码中的依赖项,以便 Parcel 也能处理它们。一些转换器不需要担心这个问题,因为另一个转换器将在之后运行并执行它(例如,默认的 JavaScript 转换器)。如果您正在添加对 Parcel 不支持的现有语言的新语言的支持,或者以其他方式引入了编译代码之外的依赖项,则需要将它们添加到资产中。

可以使用 addDependency 方法将依赖项添加到资产中,传递一个 DependencyOptions 对象。有两个必需的参数:specifier,它是一个描述依赖项位置的字符串,以及 specifierType,它描述了如何解释说明符。有关详细信息,请参见 依赖关系解析

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let code = await asset.getCode();
let deps = code.matchAll(/import "(.*?)"/g);

for (let dep of deps) {
asset.addDependency({
specifier: dep,
specifierType: 'esm'
});
}

return [asset];
}
});

影响捆绑

#

指定依赖项的方式会影响它的捆绑方式。默认情况下,依赖项会捆绑在一起,放入同一个输出文件中。依赖项的 priority 属性可以指定它应该延迟加载或与依赖它的资产并行加载。例如,JavaScript 中的动态 import() 使用 lazy 优先级加载依赖项。参见 代码拆分

bundleBehavior 属性进一步控制依赖项的捆绑方式。例如,依赖项可以被分离到一个新的包中,但通过将 bundleBehavior 设置为 inline 来内联到父包中。参见 包内联

有关每个可用选项的更多详细信息,请参见 DependencyOptions

URL 依赖项

#

在某些语言中,依赖项通过 URL 引用其他文件。在编译后的代码中,这些 URL 引用将需要更新以指向最终的包名称。但是,当资产正在被转换时,包名称还不知道。

addDependency 返回一个唯一的依赖项 ID。这可以作为最终包 URL 的占位符放置在转换后的资产内容中,并且一旦 URL 已知,它将被打包器替换。

作为一种快捷方式,addURLDependency 方法创建一个依赖项,其 specifierType 设置为 urlpriority 设置为 lazy(以创建一个单独的包)。

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let code = await asset.getCode();
let result = code.replace(/import "(.*?)"/g, (m, dep) => {
// Replace the original specifier with a dependency id
// as a placeholder. This will be replaced later with
// the final bundle URL.
let depId = asset.addURLDependency(dep);
return `import "${depId}"`;
});

asset.setCode(result);
return [asset];
}
});

重用 AST

#

如果多个 Transformer 插件按顺序在资产上运行,如果它们可以重用同一个解析的 AST,那么为每个插件解析、转换和代码生成将是浪费的。Parcel 通过将 transform 函数分成几个部分来促进 AST 共享

import {Transformer} from '@parcel/plugin';
import semver from 'semver';

export default new Transformer({
async canReuseAST({ast}) {
return ast.type === 'my-compiler'
&& semver.satisfies(ast.version, '^1.0.0');
},
async parse({asset}) {
return {
type: 'my-compiler',
version: '1.0.0',
program: parse(await asset.getCode())
};
},
async transform({asset}) {
let ast = await asset.getAST();

let compiledAST = compile(ast.program);
asset.setAST({
type: 'my-compiler',
version: '1.0.0',
program: compiledAST
});

return [asset];
},
async generate({ast}) {
let {content, map} = generate(ast.program);
return {
content,
map
};
}
});

源映射

#

源映射在浏览器中调试编译和捆绑的代码时帮助开发人员,通过将编译代码中的位置映射回原始源代码。如果可能,Transformer 插件应该在转换其内容时将源映射添加到资产中。由于资产可能由多个 Transformer 处理,因此除了其内容外,您还应该转换包含在资产中的现有源映射。

Parcel 使用 @parcel/source-map 库进行源映射操作。有关如何使用它的更多详细信息,请参见 源映射。您可能需要将传递给其他工具的源映射进行转换。

import {Transformer} from '@parcel/plugin';
import SourceMap from '@parcel/source-map';

export default new Transformer({
async transform({asset, options}) {
let source = await asset.getCode();
let sourceMap = await asset.getMap();

// Convert the input source map to JSON.
let result = compile(source, sourceMap.toVLQ());
asset.setCode(result.code);

// Convert returned JSON source map to a Parcel SourceMap.
let map = new SourceMap(options.projectRoot);
map.addVLQMap(result.map);
asset.setMap(map);

return [asset];
}
});

二进制数据

#

除了文本源代码外,Transformer 还可以处理二进制内容。这可以通过使用 Buffer 或使用 来完成。

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let buffer = await asset.getBuffer();

let result = transform(buffer);
asset.setBuffer(result);

return [asset];
}
});

查询参数

#

资产可以通过具有 查询参数 的依赖项来引用。这些指定转换器在编译或转换资产时使用的选项。例如,Parcel 图像转换器 使用查询参数来允许用户指定将图像转换为的宽度、高度和格式。同一个资产可能会使用不同的查询参数进行多次编译。

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let buffer = await asset.getBuffer();

let result = resize(
buffer,
asset.query.width,
asset.query.height
);

asset.setBuffer(result);
return [asset];
}
});

返回多个资产

#

到目前为止,所有示例都展示了如何转换单个资产。但是,有时一个文件可能包含多个不同的资产。例如,在 HTML 中,有内联 <script><style> 元素,它们应该通过它们自己的独立 Parcel 管道进行处理。为此,Parcel 允许从转换器返回多个资产。

要创建新资产,请返回一个 TransformerResult 对象数组。这些必须具有 typecontent,但也可以有自己的依赖项,以及 Asset 对象具有的许多相同选项。

通常,除了它可能具有的任何子资产外,还应该返回原始资产。父级可以通过为子级分配 uniqueKey 属性并将该属性作为依赖项的 specifier 来引用来创建对子级的依赖关系。这允许创建实际上不存在于文件系统上的“虚拟”资产,但可以像它们存在一样被引用。

import {Transformer} from '@parcel/plugin';

export default new Transformer({
async transform({asset}) {
let code = await asset.getCode();

// Extract inline assets to return in addition to this asset.
let assets = [asset];

let uniqueKey = `${asset.id}-style`;
assets.push({
type: 'css',
content: '...',
uniqueKey,
bundleBehavior: 'inline'
});

// Add a dependency, using the uniqueKey as a specifier.
asset.addDependency({
specifier: uniqueKey,
specifierType: 'esm'
});

return assets;
}
});

相关 API

#

DependencyOptions parcel/packages/core/types/index.js:476

在创建 Dependency 时使用,请参见。

type DependencyOptions = {|
  +specifier: DependencySpecifier,

用于解析依赖项的说明符。

  +specifierType: SpecifierType,

如何解释说明符。

  • esm:ES 模块说明符。它被解析为 URL,但裸说明符被视为 node_modules。
  • commonjs:CommonJS 说明符。它不被解析为 URL。
  • url:在浏览器中有效的 URL。裸说明符被视为相对 URL。
  • custom:自定义说明符。必须由自定义解析器插件处理。
  +priority?: DependencyPriority,

何时应该加载依赖项。

  • sync:依赖项应该可以同步解析。解析后的资产将被放置在与父级相同的包中,或页面上已有的另一个包中。
  • parallel:依赖项应该被放置在一个与当前包并行加载的单独包中。
  • lazy:依赖项应该被放置在一个稍后加载的单独包中。

默认值:'sync'

  +bundleBehavior?: BundleBehavior,

控制解析后的资产被放置到的包的行为。与 priority 结合使用以确定何时加载包。

  • inline:解析后的资产将被放置在一个新的内联包中。内联包不会写入单独的文件,而是嵌入到父包中。
  • isolated:解析后的资产将与其父级隔离在一个单独的包中。共享资产将被复制。
  +needsStableName?: boolean,

当依赖项是包条目(优先级为“parallel”或“lazy”)时,这将控制该包的命名。needsStableName 表示名称应该随着时间的推移保持稳定,即使包的内容发生变化。这对于用户会手动输入 URL 的条目以及服务工作者或 RSS 提要等事物很有用,其中 URL 必须随着时间的推移保持一致。

  +isOptional?: boolean,

依赖项是否可选。如果无法解析依赖项,则不会导致构建失败。

  +loc?: SourceLocation,

在源文件中找到依赖项的位置。

  +env?: EnvironmentOptions,

依赖项的环境。

  +packageConditions?: Array<string>,

在解析 package.json 的 "exports" 和 "imports" 时要使用的一组自定义条件。这与环境中的条件相结合。但是,它会覆盖从 specifierType 推断出的默认 "import" 和 "require" 条件。要除了自定义条件之外还包含这些条件,请将它们显式添加到此列表中。

  +meta?: Meta,

依赖项的特定于插件的元数据。

  +pipeline?: string,

在 .parcelrc 中定义的依赖项应使用其进行处理的管道。

  +resolveFrom?: FilePath,

应从其中解析依赖项的文件路径。默认情况下,这是指定依赖项的源文件路径。

  +range?: SemverRange,

依赖项的预期 semver 版本范围。

  +symbols?: $ReadOnlyMap<Symbol, {|
    local: Symbol,
    loc: ?SourceLocation,
    isWeak: boolean,
    meta?: Meta,
  |}>,

已解析模块中源文件依赖的符号。

|}
被引用
MutableAssetTransformerResult

Dependency parcel/packages/core/types/index.js:551

一个 Dependency 表示两个资产之间的连接(可能期望从导入者获得一些效果 - 无论是副作用还是正在导入的值)。

interface Dependency {
  +id: string,

依赖项的 ID。

  +specifier: DependencySpecifier,

用于解析依赖项的说明符。

  +specifierType: SpecifierType,

如何解释说明符。

  • esm:ES 模块说明符。它被解析为 URL,但裸说明符被视为 node_modules。
  • commonjs:CommonJS 说明符。它不被解析为 URL。
  • url:在浏览器中有效的 URL。裸说明符被视为相对 URL。
  • custom:自定义说明符。必须由自定义解析器插件处理。
  +priority: DependencyPriority,

何时应该加载依赖项。

  • sync:依赖项应该可以同步解析。解析后的资产将被放置在与父级相同的包中,或页面上已有的另一个包中。
  • parallel:依赖项应该被放置在一个与当前包并行加载的单独包中。
  • lazy:依赖项应该被放置在一个稍后加载的单独包中。

默认值:'sync'

  +bundleBehavior: ?BundleBehavior,

控制解析后的资产被放置到的包的行为。与 priority 结合使用以确定何时加载包。

  • inline:解析后的资产将被放置在一个新的内联包中。内联包不会写入单独的文件,而是嵌入到父包中。
  • isolated:解析后的资产将与其父级隔离在一个单独的包中。共享资产将被复制。
  +needsStableName: boolean,

当依赖项是包条目(优先级为“parallel”或“lazy”)时,这将控制该包的命名。needsStableName 表示名称应该随着时间的推移保持稳定,即使包的内容发生变化。这对于用户会手动输入 URL 的条目以及服务工作者或 RSS 提要等事物很有用,其中 URL 必须随着时间的推移保持一致。

  +isOptional: boolean,

依赖项是否可选。如果无法解析依赖项,则不会导致构建失败。

  +isEntry: boolean,

依赖项是否为入口。

  +loc: ?SourceLocation,

在源文件中找到依赖项的位置。

  +env: Environment,

依赖项的环境。

  +packageConditions: ?Array<string>,

在解析 package.json 的 "exports" 和 "imports" 时要使用的一组自定义条件。这与环境中的条件相结合。但是,它会覆盖从 specifierType 推断出的默认 "import" 和 "require" 条件。要除了自定义条件之外还包含这些条件,请将它们显式添加到此列表中。

  +meta: Meta,

依赖项的特定于插件的元数据。

  +target: ?Target,

如果这是一个入口,则这是与该入口关联的目标。

  +sourceAssetId: ?string,

具有此依赖项的资产的 ID。

  +sourcePath: ?FilePath,

具有此依赖项的资产的文件路径。

  +sourceAssetType: ?string,

引用此依赖项的资产的类型。

  +resolveFrom: ?FilePath,

应从其中解析依赖项的文件路径。默认情况下,这是指定依赖项的源文件路径。

  +range: ?SemverRange,

依赖项的预期 semver 版本范围。

  +pipeline: ?string,

在 .parcelrc 中定义的依赖项应使用其进行处理的管道。

  +symbols: MutableDependencySymbols,
}
被引用
BaseAssetBundleBundleGraphBundleGraphTraversableBundleTraversableDependencyOptionsDependencySpecifierMutableBundleGraphResolverResolvingProgressEventRuntimeAsset

ASTGenerator parcel/packages/core/types/index.js:639

type ASTGenerator = {|
  type: string,
  version: Semver,
|}
被引用
BaseAsset

BaseAsset parcel/packages/core/types/index.js:652

资产表示文件或文件的一部分。它可以表示任何数据类型,包括源代码、二进制数据等。资产可能存在于文件系统中,也可能是虚拟的。

interface BaseAsset {
  +id: string,

资产的 ID。

  +fs: FileSystem,

源文件所在的系统。

  +filePath: FilePath,

资产的文件路径。

  +type: string,

资产的类型。这最初对应于源文件扩展名,但它可能会在转换过程中更改。

  +query: URLSearchParams,

来自依赖项查询字符串的资产的转换器选项。

  +env: Environment,

资产的环境。

  +isSource: boolean,

此资产是否属于项目的一部分,而不是外部依赖项(例如在 node_modules 中)。这表示应应用使用项目配置的转换。

  +meta: Meta,

资产的特定于插件的元数据。

  +bundleBehavior: ?BundleBehavior,

控制将资产放置到哪个包中。

  • inline: 资产将被放置到一个新的内联包中。内联包不会写入单独的文件,而是嵌入到父包中。
  • isolated: 资产将与父级隔离在一个单独的包中。共享资产将被复制。
  +isBundleSplittable: boolean,

如果资产用作包入口,这将控制该包是否可以拆分为多个,或者所有依赖项是否必须放置在一个包中。

  +sideEffects: boolean,

如果资产的任何导出都没有被使用,是否可以省略此资产。这最初由解析器设置,但可以由转换器覆盖。

  +uniqueKey: ?string,

当转换器返回多个资产时,它可以为它们提供唯一的键来识别它们。这可用于在打包期间查找资产,或通过使用唯一键作为依赖项说明符来创建转换器返回的多个资产之间的依赖项。

  +astGenerator: ?ASTGenerator,

AST 的类型。

  +pipeline: ?string,

在 .parcelrc 中定义的资产应使用其进行处理的管道。

  +symbols: AssetSymbols,

资产导出的符号。

  getAST(): Promise<?AST>,

返回当前的 AST

  getCode(): Promise<string>,

以字符串形式返回资产内容。

  getBuffer(): Promise<Buffer>,

以缓冲区形式返回资产内容。

  getStream(): Readable,

以流形式返回资产内容。

  getMap(): Promise<?SourceMap>,

返回资产的源映射(如果可用)。

  getMapBuffer(): Promise<?Buffer>,

返回源映射的缓冲区表示形式(如果可用)。

  getDependencies(): $ReadOnlyArray<Dependency>,

返回资产的依赖项列表。

}
被引用
AssetMutableAssetResolveResult

MutableAsset parcel/packages/core/types/index.js:725

一个可变的 Asset,在转换期间可用。

interface MutableAsset extends BaseAsset {
  type: string,

资产的类型。这最初对应于源文件扩展名,但它可能会在转换过程中更改。

  bundleBehavior: ?BundleBehavior,

控制将资产放置到哪个包中。

  • inline: 资产将被放置到一个新的内联包中。内联包不会写入单独的文件,而是嵌入到父包中。
  • isolated: 资产将与父级隔离在一个单独的包中。共享资产将被复制。
  isBundleSplittable: boolean,

如果资产用作包入口,这将控制该包是否可以拆分为多个,或者所有依赖项是否必须放置在一个包中。

默认值:

  sideEffects: boolean,

如果资产的任何导出都没有被使用,是否可以省略此资产。这最初由解析器设置,但可以由转换器覆盖。

  +symbols: MutableAssetSymbols,

资产导出的符号。

  addDependency(DependencyOptions): string,

向资产添加依赖项。

  addURLDependency(url: string, opts: $Shape<DependencyOptions>): string,

向资产添加 URL 依赖项。这是 addDependency 的快捷方式,它将 specifierType 设置为 'url',并将优先级设置为 'lazy'。

  invalidateOnFileChange(FilePath): void,

当给定文件被修改或删除时,使转换失效。

  invalidateOnFileCreate(FileCreateInvalidation): void,

当匹配的文件被创建时,使转换失效。

  invalidateOnEnvChange(string): void,

当给定的环境变量更改时,使转换失效。

  setCode(string): void,

以字符串形式设置资产内容。

  setBuffer(Buffer): void,

以缓冲区形式设置资产内容。

  setStream(Readable): void,

以流形式设置资产内容。

  setAST(AST): void,

设置资产的 AST

  isASTDirty(): boolean,

返回 AST 是否已被修改。

  setMap(?SourceMap): void,

设置资产的源映射。

  setEnvironment(opts: EnvironmentOptions): void,
}
被引用
转换器

Config parcel/packages/core/types/index.js:809

interface Config {
  +isSource: boolean,

此配置是否属于项目的一部分,而不是外部依赖项(例如在 node_modules 中)。这表示应应用使用项目配置的转换。

  +searchPath: FilePath,

从其中开始搜索配置的文件的路径。

  +env: Environment,

环境

  invalidateOnFileChange(FilePath): void,

当给定文件被修改或删除时,使配置失效。

  invalidateOnFileCreate(FileCreateInvalidation): void,

当匹配的文件被创建时,使配置失效。

  invalidateOnEnvChange(string): void,

当给定的环境变量更改时,使配置失效。

  invalidateOnStartup(): void,

仅在 Parcel 重新启动时使配置失效。

  invalidateOnBuild(): void,

在每次构建时使配置失效。

  addDevDependency(DevDepOptions): void,

向配置添加开发依赖项。如果开发依赖项或其任何依赖项发生更改,则配置将失效。

  setCacheKey(string): void,

设置配置的缓存键。默认情况下,这被计算为传递给 invalidateOnFileChange 的文件或由 getConfig 加载的文件的哈希值。如果没有,则使用从 loadConfig 返回的结果的哈希值。此方法可用于覆盖此行为并显式控制缓存键。这在仅使用文件的一部分以避免不必要的失效,或结果不可哈希(即包含不可序列化的属性,如函数)的情况下很有用。

  getConfig<T>(filePaths: Array<FilePath>, options?: {|
    packageKey?: string,
    parse?: boolean,
    exclude?: boolean,
  |}): Promise<?ConfigResultWithFilePath<T>>,

在配置的 searchPath 的所有父目录中搜索具有给定名称的配置文件。

  getConfigFrom<T>(searchPath: FilePath, filePaths: Array<FilePath>, options?: {|
    packageKey?: string,
    parse?: boolean,
    exclude?: boolean,
  |}): Promise<?ConfigResultWithFilePath<T>>,

在传递的 searchPath 的所有父目录中搜索具有给定名称的配置文件。

  getPackage(): Promise<?PackageJSON>,

从配置的 searchPath 中找到最近的 package.json。

}
被引用
BundlerNamerOptimizerPackagerResolverRuntimeTransformer

GenerateOutput parcel/packages/core/types/index.js:882

type GenerateOutput = {|
  +content: Blob,
  +map?: ?SourceMap,
|}
被引用
转换器

TransformerResult parcel/packages/core/types/index.js:896

转换器可以返回多个结果对象以创建新的资产。例如,一个文件可能包含不同类型的多个部分,这些部分应由其各自的转换管道处理。

type TransformerResult = {|
  +type: string,

资产的类型。

  +content?: ?Blob,

资产的内容。需要内容或 AST

  +ast?: ?AST,

资产的 AST。需要内容或 AST

  +map?: ?SourceMap,

资产的源映射。

  +dependencies?: $ReadOnlyArray<DependencyOptions>,

资产的依赖项。

  +env?: EnvironmentOptions | Environment,

资产的环境。选项与输入资产的环境合并。

  +bundleBehavior?: ?BundleBehavior,

控制将资产放置到哪个包中。

  • inline: 资产将被放置到一个新的内联包中。内联包不会写入单独的文件,而是嵌入到父包中。
  • isolated: 资产将与父级隔离在一个单独的包中。共享资产将被复制。
  +isBundleSplittable?: boolean,

如果资产用作包入口,这将控制该包是否可以拆分为多个,或者所有依赖项是否必须放置在一个包中。

  +meta?: Meta,

资产的特定于插件的元数据。

  +pipeline?: ?string,

在 .parcelrc 中定义的资产应使用其进行处理的管道。

  +sideEffects?: boolean,

如果资产的任何导出都没有被使用,是否可以省略此资产。这最初由解析器设置,但可以由转换器覆盖。

  +symbols?: $ReadOnlyMap<Symbol, {|
    local: Symbol,
    loc: ?SourceLocation,
  |}>,

资产导出的符号。

  +uniqueKey?: ?string,

当转换器返回多个资产时,它可以为它们提供唯一的键来识别它们。这可用于在打包期间查找资产,或通过使用唯一键作为依赖项说明符来创建转换器返回的多个资产之间的依赖项。

|}
被引用
转换器

ResolveOptions parcel/packages/core/types/index.js:976

type ResolveOptions = {|
  +specifierType?: SpecifierType,

如何解释说明符。

  • esm:ES 模块说明符。它被解析为 URL,但裸说明符被视为 node_modules。
  • commonjs:CommonJS 说明符。它不被解析为 URL。
  • url:在浏览器中有效的 URL。裸说明符被视为相对 URL。
  • custom:自定义说明符。必须由自定义解析器插件处理。
  +packageConditions?: Array<string>,

在解析 package.json 的 "exports" 和 "imports" 时要使用的一组自定义条件。

|}
被引用
ResolveFn

ResolveFn parcel/packages/core/types/index.js:992

类型
type ResolveFn = (from: FilePath, to: string, options?: ResolveOptions) => Promise<FilePath>;
被引用
转换器

Transformer parcel/packages/core/types/index.js:1063

转换器插件的方法。

type Transformer<ConfigType> = {|
  loadConfig?: ({|
    config: Config,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Promise<ConfigType> | ConfigType,
  canReuseAST?: ({|
    ast: AST,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => boolean,

是否可以重用来自先前转换器的 AST(以防止双重解析)

  parse?: ({|
    asset: Asset,
    config: ConfigType,
    resolve: ResolveFn,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Async<?AST>,

将内容解析为 ast

  transform({|
    asset: MutableAsset,
    config: ConfigType,
    resolve: ResolveFn,
    options: PluginOptions,
    logger: PluginLogger,
  |}): Async<Array<TransformerResult | MutableAsset>>,

转换资产和/或添加新资产

  postProcess?: ({|
    assets: Array<MutableAsset>,
    config: ConfigType,
    resolve: ResolveFn,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Async<Array<TransformerResult>>,
标记为实验性

在转换后进行一些处理

  generate?: ({|
    asset: Asset,
    ast: AST,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Async<GenerateOutput>,

AST 字符串化

|}