打包器
打包器插件负责将打包中的所有资源组合成一个输出文件。它们还处理解析 URL 引用、打包内联和生成源映射。
示例
#此示例展示了一个将打包中的所有资源连接在一起的打包器。Bundle
对象的 traverseAsset
方法以深度优先顺序遍历打包中的所有资源。在每个 Asset
上调用 getCode
方法以检索其内容。
import { Packager } from "@parcel/plugin";
export default new Packager({
async package({ bundle }) {
let promises = [];
bundle.traverseAssets((asset) => {
promises.push(asset.getCode());
});
let contents = await Promise.all(promises);
return {
contents: contents.join("\n"),
};
},
});
加载配置
#应在打包器插件的 loadConfig
方法中从用户的项目加载配置。有关如何执行此操作的详细信息,请参见加载配置。
note:使用 Parcel 的配置加载机制以便正确使缓存失效非常重要。避免直接从文件系统读取文件。
源映射
#源映射帮助开发者在浏览器中调试编译和打包的代码,方法是将编译后的代码中的位置映射回原始源代码。除了将代码组合成最终打包外,打包器还负责将每个资源的源映射组合成打包的源映射。
Parcel 使用 @parcel/source-map
库进行源映射操作。有关如何使用它的更多详细信息,请参见源映射。
传递给打包器插件的 getSourceMapReference
函数可用于在打包内容中插入源映射的 URL。Parcel 负责在适当的时候生成内联源映射(例如,遵循目标配置中的 sourceMap
选项)。
import { Packager } from "@parcel/plugin";
import SourceMap from "@parcel/source-map";
import { countLines } from "@parcel/utils";
export default new Packager({
async package({ bundle, options, getSourceMapReference }) {
let promises = [];
bundle.traverseAssets((asset) => {
promises.push(Promise.all([asset.getCode(), asset.getMap()]));
});
let assets = await Promise.all(promises);
let contents = "";
let map = new SourceMap(options.projectRoot);
let lineOffset = 0;
for (let [code, map] of assets) {
contents += code + "\n";
map.addSourceMap(map, lineOffset);
lineOffset += countLines(code) + 1;
}
contents += `\n//# sourceMappingURL=${await getSourceMapReference(map)}\n`;
return { contents, map };
},
});
URL 引用
#转换器插件可能在编译后的代码中留下对依赖 ID 的引用(请参见转换器文档中的 URL 依赖)。打包器应将这些引用替换为生成的打包的 URL。这可以使用 @parcel/utils
中的 replaceURLReferences
函数来完成。
import { Packager } from "@parcel/plugin";
import { replaceURLReferences } from "@parcel/utils";
export default new Packager({
async package({ bundle, bundleGraph }) {
// ...
({ contents, map } = replaceURLReferences({
bundle,
bundleGraph,
contents,
map,
}));
return { contents, map };
},
});
打包内联
#Parcel 支持在另一个打包中内联一个打包的内容。例如,CSS 打包的编译内容可以作为字符串内联到 JavaScript 打包中。有关详细信息,请参见打包内联。
打包内联在打包器插件中实现。传递给打包器的 getInlineBundleContents
函数可用于检索内联打包的内容。
转换器插件可能在编译后的代码中留下对依赖 ID 的引用(请参见转换器文档中的 URL 依赖)。如果这些最终引用内联打包,则应将其替换为该打包的内容。这可以使用 @parcel/utils
中的 replaceInlineReferences
函数来完成。
import { Packager } from "@parcel/plugin";
import { replaceInlineReferences } from "@parcel/utils";
export default new Packager({
async package({ bundle, bundleGraph, getInlineBundleContents }) {
// ...
({ contents, map } = replaceInlineReferences({
bundle,
bundleGraph,
contents,
map,
getInlineBundleContents,
getInlineReplacement: (dependency, inlineType, contents) => ({
from: dependency.id,
to: contents,
}),
}));
return { contents, map };
},
});
相关 API
#SymbolResolution parcel/packages/core/types/index.js:1231
Specifies a symbol in an asset
type SymbolResolution = {|
+asset: Asset,
The Asset which exports the symbol.
+exportSymbol: Symbol | string,
under which name the symbol is exported
+symbol: void | null | false | Symbol,
The identifier under which the symbol can be referenced.
+loc: ?SourceLocation,
The location of the specifier that lead to this result.
|}
Referenced by:
BundleGraph, ExportSymbolResolutionExportSymbolResolution parcel/packages/core/types/index.js:1245
type ExportSymbolResolution = {|
...SymbolResolution,
+exportAs: Symbol | string,
|}
Referenced by:
BundleGraphPackager parcel/packages/core/types/index.js:1649
type Packager<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>,
package({|
bundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
options: PluginOptions,
logger: PluginLogger,
config: ConfigType,
bundleConfig: BundleConfigType,
getInlineBundleContents: (Bundle, BundleGraph<NamedBundle>) => Async<{|
contents: Blob
|}>,
getSourceMapReference: (map: ?SourceMap) => Async<?string>,
|}): Async<BundleResult>,
|}