解析器

解析器插件负责将依赖项说明符转换为将由转换器处理的完整文件路径。解析器在管道中运行,直到其中一个解析器返回结果。有关默认解析器的工作原理的详细信息,请参阅 依赖项解析

示例

#

此示例覆盖了 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 之外,解析器插件还会接收一个完整的 Dependency 对象,其中包含有关依赖项的附加元数据。specifierType 属性指示如何解释 specifier(例如,ESM、CommonJS、URL 等)。resolveFrom 属性指定应从中解析依赖项的文件路径(例如,如果说明符是相对路径)。

此示例根据 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;
}
});

缓存失效

#

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 错误或返回 diagnostics。如果解析器抛出异常,解析过程将立即停止,并且错误将显示给用户。

如果解析器改为返回 diagnostics,解析将继续到下一个解析器插件。如果没有任何解析器插件能够解析依赖项,则所有解析器插件的所有诊断信息都将显示给用户。

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.']
}]
};
}
}
});

有关更多详细信息,请参阅 诊断

副作用

#

解析器还可以返回 sideEffects 属性,该属性指示资产在执行时是否可能具有副作用。这通常对应于 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,

对应于 BaseAssetsideEffects

  +code?: string,

解析资产的代码。如果提供,则使用此代码而不是从磁盘读取文件。

  +canDefer?: boolean,

Parcel 本身是否可以延迟此依赖项(默认情况下为 true)。

  +diagnostics?: Diagnostic | Array<Diagnostic>,

解析器可能会返回诊断信息以运行后续解析器,同时仍然提供失败的原因。

  +meta?: JSONObject,

传播(浅合并)到请求的 dependency.meta 上

  +invalidateOnFileCreate?: Array<FileCreateInvalidation>,

如果创建,则应使解析失效的文件路径或模式列表。

  +invalidateOnFileChange?: Array<FilePath>,

如果修改或删除,则应使解析失效的文件列表。

  +invalidateOnEnvChange?: Array<string>,

当给定的环境变量更改时,使解析失效。

|}
被引用
解析器

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