如何使用parcel-namer-hashless从Parcel中的index.js和index.runtime.js中删除哈希?

问题描述 投票:0回答:1

我正在开发一个 TypeScript 项目,其中使用 Parcel v2.x 进行捆绑,并且我想从输出文件名(特别是 index.runtime.js)中删除哈希值。

我一直在使用 Parcel-namer-hashless 插件,虽然它成功地从我的大多数文件(如 favicon.ico、esp32.js 等)中删除了哈希,但我仍然遇到索引问题。运行时.js 文件。尽管我努力配置插件以删除它们,但它们的文件名中仍然包含哈希值。

这是我迄今为止尝试过的:

在package.json中配置parcel-namer-hashless:

{
  "name": "typescript",
  "version": "1.0.0",
  "description": "This an example of using esptool-js with parcel and typescript",
  "source": "src/index.html",
  "scripts": {
    "genDocs": "cd ../.. && npm run genDocs && mkdir -p examples/typescript/dist && cp -r docs examples/typescript/dist && cd examples/typescript",
    "dev": "npm run clean && npm run genDocs && parcel src/index.html",
    "build": "npm run clean && npm run genDocs && parcel build src/index.html --no-optimize --public-url ./",
    "clean": "rimraf dist .parcel-cache",
    "test": "echo \"Error: no test specified\" && exit 1",
    "postbuild": "mv dist/index.runtime.*.js dist/index.runtime.js"
  },
  "parcelIgnore": [
    "./docs/.+"
  ],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "parcel": "^2.8.3",
    "parcel-namer-hashless": "^1.0.6",
    "parcel-resolver-ignore": "^2.1.5",
    "rimraf": "^4.1.2",
    "typescript": "^4.9.4",
    "web-serial-polyfill": "^1.0.15"
  },
  "parcel-namer-hashless": {
    "include": [
      ".js$",           
      ".ico$"           
    ]
  }
}

配置.parcelrc文件:

{
  "extends": "@parcel/config-default",
  "resolvers": [
    "parcel-resolver-ignore",
    "..."
  ],
  "namers": [
    "parcel-namer-hashless"
  ]
}

清除Parcel缓存并重建多次。

尽管做出了这些努力,index.runtime.js 仍然附加了哈希值。构建输出如下所示:

dist/index.runtime.298534a0.js

所有其他文件均已正确重命名,没有哈希值。

我还尝试添加构建后脚本来手动重命名文件,但如果可能的话,我更希望在 Parcel 中拥有更清晰的解决方案。 我的问题:

如何确保使用 Parcel 和 Parcel-namer-hashless 生成没有哈希值的 index.runtime.js? 有没有更好的方法来配置 Parcel 或 Parcel-namer-hashless 插件来处理运行时文件? Parcel 坚持向运行时文件添加哈希值是否有特定原因,以及如何覆盖此行为?

如有任何意见或建议,我们将不胜感激。预先感谢!

我还使用具有相同输出的 custom-namer.js 进行了尝试:

const { Namer } = require('@parcel/plugin');

module.exports = new Namer({
  async name({ bundle }) {
    const entryAsset = bundle.getMainEntry();

    // Handle the main HTML or JS entry point (index)
    if (entryAsset && entryAsset.filePath.includes('index')) {
      // Check if it's a runtime file (Parcel auto-generates runtime bundles)
      if (bundle.type === 'js' && !bundle.isInline && bundle.needsStableName && bundle.isSplittable === false) {
        // Ensure the runtime script is named without a hash
        return `index.runtime.js`;
      }
      
      // For regular 'index.js' or 'index.html'
      return `index.${bundle.type}`;
    }

    // For all other entry points, use the original file name without hash
    if (entryAsset) {
      const originalName = entryAsset.filePath.split('/').pop().split('.')[0]; // Get original name without extension
      return `${originalName}.${bundle.type}`;
    }

    // Fallback for other dynamically generated chunks or assets
    const id = bundle.id.slice(0, 8); // Shorten bundle ID to 8 characters for uniqueness
    return `bundle-${id}.${bundle.type}`;
  }
});

javascript node.js typescript npm deployment
1个回答
0
投票

我认为无法自定义

*.runtime.*.js
文件名。

applyRuntimes.js 中有引用此行为的注释。 如您所见,文件名被替换为

.runtime.${hashReference}.${bundle.type}

function nameRuntimeBundle(
  bundle: InternalBundle,
  siblingBundle: InternalBundle,
) {
  // We don't run custom namers on runtime bundles as the runtime assumes that they are
  // located at the same nesting level as their owning bundle. Custom naming could
  // be added in future as long as the custom name is validated.
  let {hashReference} = bundle;

  let name = nullthrows(siblingBundle.name)
    // Remove the existing hash from standard file patterns
    // e.g. 'main.[hash].js' -> 'main.js' or 'main~[hash].js' -> 'main.js'
    .replace(new RegExp(`[\\.~\\-_]?${siblingBundle.hashReference}`), '')
    // Ensure the file ends with 'runtime.[hash].js'
    .replace(`.${bundle.type}`, `.runtime.${hashReference}.${bundle.type}`);

  bundle.name = name;
  bundle.displayName = name.replace(hashReference, '[hash]');
}

将自定义

Namer
name
函数应用到文件名后,将创建
*.runtime.*.js
文件,然后执行此
nameRuntimeBundle()
函数。这意味着无法使用
Namer
更改名称。 (
parcel-namer-hashless
包也使用
Namer
,所以它产生相同的结果。)

您可以添加以下配置,通过跳过上述代码(及其相关代码)来避免生成

*.runtime.*.js

  "@parcel/runtime-js": {
    "splitManifestThreshold": 1000000 // default is 100,000 bytes
  },

如果捆绑包大小超过阈值,它将附加

priority: parallel
。使用
*.runtime.*.js
文件解决依赖关系可能需要并行加载(我认为可能是这种情况)。

参考:https://github.com/parcel-bundler/parcel/discussions/9490

© www.soinside.com 2019 - 2024. All rights reserved.