封裝器

打包器外掛程式負責將所有套件中的資源合併到一個輸出檔案中。它們也處理解析 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 使用 @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 參照

#

Transformer 外掛程式可能會在編譯的程式碼中留下對依賴項 ID 的參照(請參閱 Transformer 文件中的 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 函式傳遞給封裝程式,可以呼叫來擷取內嵌套件的內容。

Transformer 外掛程式可能會在編譯的程式碼中留下對依賴項 ID 的參照(請參閱 Transformer 文件中的 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,

匯出符號的 資產

  +exportSymbol: Symbol | string,

符號匯出的名稱

  +symbol: void | null | false | Symbol,

符號可以被參照到的識別碼。

  +loc: ?SourceLocation,

導致此結果的規格說明的位置。

|}
參照
BundleGraphExportSymbolResolution

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

type ExportSymbolResolution = {|
  ...SymbolResolution,
  +exportAs: Symbol | string,
|}
參照
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>,
|}