解析器

解析器外掛負責將依賴項規格轉換為轉換器將處理的完整檔案路徑。解析器會在管線中執行,直到其中一個傳回結果。請參閱 依賴項解析,以瞭解預設解析器如何運作的詳細資訊。

範例

#

此範例會覆寫 special-module 的解析,否則會傳回 null,以允許管線中的下一個解析器處理依賴項。請參閱 Parcel 設定文件中的 解析器,以瞭解其運作方式的詳細資訊。

import {Resolver} from '@parcel/plugin';
import path from 'path';

export default new Resolver({
async resolve({specifier}) {
if (specifier === 'special-module') {
return {
filePath: path.join(__dirname, 'special-module.js')
};
}

// Let the next resolver in the pipeline handle
// this dependency.
return null;
}
});

載入設定

#

應在解析器外掛的 loadConfig 方法中載入使用者的專案設定。請參閱 載入設定,以瞭解如何執行此操作的詳細資訊。

注意:使用 Parcel 的設定載入機制非常重要,才能正確地使快取失效。避免直接從檔案系統載入檔案。

虛擬模組

#

解析器除了解析為檔案系統上的檔案,也可以直接傳回 code。這允許按需以程式方式產生虛擬模組。不過,您仍必須傳回 filePath,因為這表示應該如何解析程式碼中的任何依賴項,以及轉換器應如何處理原始碼(例如,依據副檔名)。

import {Resolver} from '@parcel/plugin';
import path from 'path';

export default new Resolver({
async resolve({specifier}) {
if (specifier === 'special-module') {
return {
filePath: path.join(__dirname, 'special-module.js'),
code: 'export default "This is a special module!";'
};
}

return null;
}
});

相依性資訊

#

除了 specifier 之外,Resolver 外掛程式還會收到一個完整的 Dependency 物件,其中包含相依性的其他資訊。specifierType 屬性指出 specifier 應如何解釋(例如 ESM、CommonJS、URL 等)。resolveFrom 屬性指定應從何處解析相依性(例如,如果 specifier 是相對路徑)。

此範例會根據 specifierType 解析相對 URL 和路徑。

import {Resolver} from '@parcel/plugin';
import path from 'path';
import {fileURLToPath, pathToFileURL} from 'url';

export default new Resolver({
async resolve({specifier, dependency}) {
return {
filePath: dependency.specifierType === 'url'
? fileURLToPath(
new URL(specifier, pathToFileURL(dependency.resolveFrom))
)
: path.resolve(dependency.resolveFrom, specifier)
};
}
});

排除模組

#

isExcluded 屬性可傳回以指出應從建置中排除模組。此範例會排除 aws-sdk,它會自動包含在 AWS 主機環境中,不需要套件化。

import {Resolver} from '@parcel/plugin';

export default new Resolver({
async resolve({specifier}) {
if (specifier === 'aws-sdk') {
return {isExcluded: true};
}

return null;
}
});

快取失效

#

Resolver 外掛程式的結果會自動快取在 Parcel 中。如果您在解析期間從檔案系統中讀取任何檔案,您需要告訴 Parcel 這些檔案,以便它可以監視這些檔案,並在檔案變更時使解析失效。

invalidateOnFileChange 屬性應設定為在解析期間成功讀取的所有檔案陣列。invalidateOnFileCreate 屬性應設定為 FileCreateInvalidation 物件陣列,描述如果建立檔案,應使解析失效的檔案。

import {Resolver} from '@parcel/plugin';
import path from 'path';

export default new Resolver({
async resolve({specifier, options}) {
let aliasFile = path.join(options.projectRoot, 'alias.json');

try {
let aliasConfig = await options.inputFS.readFile(aliasFile);
let aliases = JSON.parse(aliasConfig);
return {
filePath: aliases[specifier] || null,
invalidateOnFileChange: [aliasFile]
};
} catch (err) {
return {
invalidateOnFileCreate: [{filePath: aliasFile}]
};
}
}
});

診斷

#

解析器外掛可能會在解析期間遇到錯誤。發生這種情況時,它可能會 throw 錯誤或傳回 診斷。如果解析器拋出錯誤,解析程序會立即停止,並向使用者顯示錯誤。

如果解析器改為傳回 診斷,解析會繼續進行到下一個解析器外掛。如果沒有任何解析器外掛能夠解析相依性,則會向使用者顯示所有解析器外掛的所有診斷。

import {Resolver} from '@parcel/plugin';
import path from 'path';

export default new Resolver({
async resolve({specifier, options}) {
let aliasFile = path.join(options.projectRoot, 'alias.json');

try {
let aliasConfig = await options.inputFS.readFile(aliasFile);
let aliases = JSON.parse(aliasConfig);
return {
filePath: aliases[specifier] || null,
invalidateOnFileChange: [aliasFile]
};
} catch (err) {
return {
invalidateOnFileCreate: [{filePath: aliasFile}],
diagnostics: [
{
message: 'Could not read alias.json',
hints: ['Create an alias.json file in the project root.']
}]
};
}
}
});

請參閱 診斷 以取得更多詳細資料。

副作用

#

解析器也可以傳回 副作用 屬性,表示執行資產時可能會產生副作用。這通常對應於 package.json 中的同一個屬性,並用於 範圍提升

相關 API

#

ResolveResult parcel/packages/core/types/index.js:1539

type ResolveResult = {|
  +filePath?: FilePath,

已解析檔案的絕對路徑。

  +pipeline?: ?string,

用於編譯已解析檔案的選用命名管線。

  +query?: URLSearchParams,

編譯已解析檔案時,轉換器要使用的查詢參數。

  +isExcluded?: boolean,

是否應將已解析檔案從建置中排除。

  +priority?: DependencyPriority,

覆寫相依性上設定的優先順序。

  +sideEffects?: boolean,

對應於 BaseAsset副作用

  +code?: string,

已解析資產的程式碼。如果提供,則使用此程式碼,而不是從磁碟讀取檔案。

  +canDefer?: boolean,

此相依性是否可以由 Parcel 本身延後 (預設為 true)。

  +diagnostics?: Diagnostic | Array<Diagnostic>,

解析器可能會傳回診斷,以便在提供失敗原因的同時,執行後續解析器。

  +meta?: JSONObject,

散佈(淺層合併)到請求的 dependency.meta

  +invalidateOnFileCreate?: Array<FileCreateInvalidation>,

如果建立,檔案路徑或模式的清單應該使解析失效。

  +invalidateOnFileChange?: Array<FilePath>,

如果修改或刪除,檔案的清單應該使解析失效。

  +invalidateOnEnvChange?: Array<string>,

當給定的環境變數變更時,使解析失效。

|}
由以下項目參照
解析器

解析器 parcel/packages/core/types/index.js:1723

type Resolver<ConfigType> = {|
  loadConfig?: ({|
    config: Config,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Promise<ConfigType> | ConfigType,
  resolve({|
    dependency: Dependency,
    options: PluginOptions,
    logger: PluginLogger,
    specifier: FilePath,
    pipeline: ?string,
    config: ConfigType,
  |}): Async<?ResolveResult>,
|}