命名器

命名器插件确定打包的输出文件名。命名器在管道中运行,直到其中一个返回结果。返回的文件路径应相对于目标 distDir。有关详细信息,请参见目标

为特定打包覆盖名称

#

命名器插件的一个常见用例是为特定打包覆盖 Parcel 的默认命名方案。当命名器无法处理打包时,可以返回 null,以允许管道中的下一个命名器处理它。有关详细信息,请参见 Parcel 配置文档中的命名器

此示例将所有 pngjpg 文件放入 images 文件夹,文件名与其原始文件名相同。

import { Namer } from "@parcel/plugin";
import path from "path";

export default new Namer({
name({ bundle }) {
if (bundle.type === "png" || bundle.type === "jpg") {
let filePath = bundle.getMainEntry().filePath;
return `images/${path.basename(filePath)}`;
}

// 允许下一个命名器处理此打包。
return null;
},
});

note:此示例不确保所有文件名都是唯一的。如果两个图像在不同目录中具有相同的文件名,构建将失败。

内容哈希

#

在生产构建中,包含打包内容的哈希是一个重要的优化,它使浏览器能够无限期地缓存已加载的文件。当打包的内容发生变化时,其文件名也会发生变化,这充当了缓存失效机制。有关详细信息,请参见内容哈希文档。

在对打包进行命名时,最终内容尚未知,因此 Parcel 在每个 Bundle 对象上提供了 hashReference 属性。这是一个不透明的占位符值,稍后在写入最终打包时将被实际哈希替换。在返回的打包名称中使用此值以包含内容哈希。

在包含哈希之前,请务必检查 bundle.needsStableName 属性。当此值为 true 时,依赖项期望打包的文件名随时间保持一致。例如,服务工作者要求其 URL 永不更改,并且用户希望可见的 URL(如 HTML 页面)是人类可读的并保持一致。

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

export default new Namer({
name({bundle}) {
let name = yourNamingFunction(bundle);
if (!bundle.needsStableName) {
name += "." + bundle.hashReference;
}
return name + "." + bundle.type;
}
});

即使禁用内容哈希(例如在开发中,或使用 --no-content-hash),哈希也是确保返回的打包名称唯一的好方法。在这种情况下,hashReference 将被替换为原始文件路径的哈希,这不会随时间改变。

目标

#

命名器插件还应尊重与打包关联的 Target目标允许用户在 package.json 中配置入口打包的输出文件名。如果打包在入口打包组中并包含入口资源,则命名器插件应在可用时使用 bundle.target.distEntry 作为输出文件名。

import { Namer } from "@parcel/plugin";

export default new Namer({
name({ bundle, bundleGraph }) {
let bundleGroup = bundleGraph.getBundleGroupsContainingBundle(bundle)[0];
let isEntry = bundleGraph.isEntryBundleGroup(bundleGroup);
let bundleGroupBundles = bundleGraph.getBundlesInBundleGroup(bundleGroup);
let mainBundle = bundleGroupBundles.find((b) =>
b.getEntryAssets().some((a) => a.id === bundleGroup.entryAssetId)
);

if (isEntry && bundle.id === mainBundle.id && bundle.target?.distEntry) {
return bundle.target.distEntry;
}

// ...
},
});

加载配置

#

应在命名器插件的 loadConfig 方法中从用户的项目加载配置。有关如何执行此操作的详细信息,请参见加载配置

note:使用 Parcel 的配置加载机制以便正确使缓存失效非常重要。避免直接从文件系统读取文件。

相关 API

#

Namer parcel/packages/core/types/index.js:1597

type Namer<ConfigType> = {|
  loadConfig?: ({|
    config: Config,
    options: PluginOptions,
    logger: PluginLogger,
  |}) => Promise<ConfigType> | ConfigType,
  name({|
    bundle: Bundle,
    bundleGraph: BundleGraph<Bundle>,
    config: ConfigType,
    options: PluginOptions,
    logger: PluginLogger,
  |}): Async<?FilePath>,

Return a filename/-path for bundle or nullish to leave it to the next namer plugin.

|}
Referenced by:
NamedBundle