优化器
优化器插件类似于转换器,但它们接受一个打包而不是单个资源。优化器通常用于实现压缩、树摇/死代码消除以及需要完整打包才能有效的其他大小缩减技术。然而,优化器也可用于任何类型的打包转换,例如添加许可头、将内联打包转换为 base 64 等。
示例
#optimize
方法接收打包的内容和其源映射,并应返回这些内容的转换版本。多个优化器插件可以串行运行,每个优化器的结果都传递给下一个。有关源映射的更多信息,请参见下文。
import { Optimizer } from "@parcel/plugin";
export default new Optimizer({
async optimize({ contents, map }) {
let { code, sourceMap } = optimize(contents, map);
return {
contents: code,
map: sourceMap,
};
},
});
加载配置
#应在优化器插件的 loadConfig
方法中从用户的项目加载配置。有关如何执行此操作的详细信息,请参见加载配置。
note:使用 Parcel 的配置加载机制以便正确使缓存失效非常重要。避免直接从文件系统读取文件。
条件优化
#即使在开发中或指定了 --no-optimize
选项时,Parcel 也始终运行 Optimizer
插件。这是因为优化器可用于任何类型的打包转换,而不仅仅是压缩。如果您的优化器插件正在执行压缩或通常应仅在生产构建中运行,则应检查打包环境的 shouldOptimize
属性,并在其为 false
时返回原始内容。
import {Optimizer} from '@parcel/plugin';
export default new Optimizer({
async optimize({contents, map, bundle}) {
// 如果 shouldOptimize 为 false,则不要压缩。
if (!bundle.env.shouldOptimize) {
return {contents, map};
}
let {code, sourceMap} = minify(contents, map);
return {
contents: code,
map: sourceMap
};
}
});
二进制内容
#传递给优化器的输入内容可能是字符串、Buffer 或 ReadableStream。通常,源代码将是字符串,二进制内容将是 Buffer 或流,但您不应假设如此。@parcel/utils
包包含一些帮助在它们之间转换的函数:blobToString
和 blobToBuffer
。优化器可以返回这些表示中的任何一种。
import {Optimizer} from '@parcel/plugin';
import {blobToBuffer} from '@parcel/utils';
export default new Optimizer({
async optimize({contents}) {
let buffer = await blobToBuffer(contents);
let optimized = optimize(buffer);
return {contents: optimized};
}
});
源映射
#源映射帮助开发者在浏览器中调试编译和打包的代码,方法是将编译后的代码中的位置映射回原始源代码。优化器插件应转换提供的源映射,同时还要转换打包的内容。
Parcel 使用 @parcel/source-map
库进行源映射操作。有关如何使用它的更多详细信息,请参见源映射。您可能需要在传递给其他工具的源映射之间进行转换。
传递给优化器插件的 getSourceMapReference
函数可用于在打包内容中插入源映射的 URL。Parcel 负责在适当的时候生成内联源映射(例如,遵循目标配置中的 sourceMap
选项)。
import { Optimizer } from "@parcel/plugin";
import SourceMap from "@parcel/source-map";
export default new Optimizer({
async optimize({ contents, map, getSourceMapReference }) {
// 将输入源映射转换为 JSON。
let result = optimize(contents, map.toVLQ());
// 将返回的 JSON 源映射转换为 Parcel SourceMap。
let sourceMap = new SourceMap(options.projectRoot);
sourceMap.addVLQMap(result.map);
// 将源映射引用添加到编译后的代码
let url = await getSourceMapReference(sourceMap);
result.code += `\n//# sourceMappingURL=${url}\n`;
return {
contents: result.code,
sourceMap,
};
},
});
相关 API
#Optimizer parcel/packages/core/types/index.js:1680
type Optimizer<ConfigType, BundleConfigType> = {|
loadConfig?: ({|
config: Config,
options: PluginOptions,
logger: PluginLogger,
|}) => Async<ConfigType>,
loadBundleConfig?: ({|
bundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
config: Config,
options: PluginOptions,
logger: PluginLogger,
|}) => Async<BundleConfigType>,
optimize({|
bundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
contents: Blob,
map: ?SourceMap,
options: PluginOptions,
logger: PluginLogger,
config: ConfigType,
bundleConfig: BundleConfigType,
getSourceMapReference: (map: ?SourceMap) => Async<?string>,
|}): Async<BundleResult>,
|}