打包器
打包器插件负责将捆绑包中的所有资产组合到一个输出文件中。它们还处理解析 URL 引用、捆绑包内联和生成源映射。
示例
#此示例展示了一个将捆绑包中的所有资产连接在一起的打包器。Bundle
对象的 traverseAsset
方法以深度优先顺序遍历捆绑包中的所有资产。getCode
方法在每个 Asset
上调用以检索其内容。
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
方法中完成。有关如何执行此操作的详细信息,请参阅 加载配置。
源映射
#源映射在浏览器中调试编译和捆绑的代码时帮助开发人员,通过将编译代码中的位置映射回原始源代码。除了将代码组合到最终捆绑包中,打包器还负责将每个资产的源映射组合到捆绑包的源映射中。
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
指定资产中的符号
type SymbolResolution = {|
+asset: Asset,
导出符号的 Asset。
+exportSymbol: Symbol | string,
导出符号的名称。
+symbol: void | null | false | Symbol,
可以引用符号的标识符。
+loc: ?SourceLocation,
导致此结果的说明符的位置。
|}
被引用
BundleGraph,ExportSymbolResolutionExportSymbolResolution parcel/packages/core/types/index.js:1245
type ExportSymbolResolution = {|
...SymbolResolution,
+exportAs: Symbol | string,
|}
被引用
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>,
|}