命名器
命名器插件确定打包的输出文件名。命名器在管道中运行,直到其中一个返回结果。返回的文件路径应相对于目标 distDir
。有关详细信息,请参见目标。
为特定打包覆盖名称
#命名器插件的一个常见用例是为特定打包覆盖 Parcel 的默认命名方案。当命名器无法处理打包时,可以返回 null
,以允许管道中的下一个命名器处理它。有关详细信息,请参见 Parcel 配置文档中的命名器。
此示例将所有 png
和 jpg
文件放入 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.
|}