打包器

打包器插件负责将打包中的所有资源组合成一个输出文件。它们还处理解析 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, ExportSymbolResolution

ExportSymbolResolution parcel/packages/core/types/index.js:1245

type ExportSymbolResolution = {|
  ...SymbolResolution,
  +exportAs: Symbol | string,
|}
Referenced by:
BundleGraph

Packager 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>,
|}