Webpack 5 供应商分块命名

Webpack 5 vendors chunks naming

在 webpack 4 中,供应商块的名称如 vendors~main~secondary.js,指的是它们相关的块。现在,在 webpack 5 中,vendors chunks 的名字是这样的:vendors-node_modules_react-dom_index_js.js,可读性和可理解性真的很差。

关于如何在使用 webpack 5 时恢复到 webpack 4 的行为有什么技巧吗?

我想我必须用 splitChunks.name 做点什么,但我找不到合适的函数来做那件事。

编辑

虽然 @MrP01 的回答更详尽并且对使用 splitChunks.name 提供了更深入的了解,但这是我最终使用的一个简短片段,它让我可以回到原来的行为。

optimization: {
  splitChunks: {
    chunks: 'all',
    name: (module, chunks, cacheGroupKey) => {
      const allChunksNames = chunks.map((chunk) => chunk.name).join('~');
      const prefix = cacheGroupKey === 'defaultVendors' ? 'vendors' : cacheGroupKey;
      return `${prefix}~${allChunksNames}`;
    },
  },
},

我对 webpack 5 中的新命名方案感觉非常相似。经过相当多的努力和测试,我通过将函数句柄传递给 filename 属性得出了以下结果。

为了得到 'prettier' 个名字——当然这取决于每个人的个人判断——下面的函数规范化名字并去掉其中大部分不必要的部分。

function normalizeName(name) {
  return name.replace(/node_modules/g, "nodemodules").replace(/[\-_.|]+/g, " ")
    .replace(/\b(vendors|nodemodules|js|modules|es)\b/g, "")
    .trim().replace(/ +/g, "-");
}

主要问题是拆分出的块的命名。目前的文档对此不是很明确,但是 config.optimization.splitChunks 中配置的 cacheGroup 设置没有特定的 cacheGroup,适用于所有 cacheGroups。

我还启用了块、资产名称和提取的规范化 css。

module.exports = async () => {
  return {
    config: {
      context: BASE,
      entry: entrypoints,
      output: {
        path: path.resolve(`./.dev/bundles/${locale}`),
        publicPath: `/static/bundles/${locale}/`,
        filename: (pathData) => {
          return normalizeName(pathData.chunk.name) + ".js";
        },
        chunkFilename: (pathData) => {
          return normalizeName(pathData.chunk.id) + ".js";
        },
      },
      devtool: false,
      optimization: {
        splitChunks: {
          chunks: "all",
          name(module, chunks, cacheGroupKey) {
            const moduleFileName = module.identifier().split("/").reduceRight((item) => item);
            // const allChunksNames = chunks.map((item) => item.name).join("-");
            return normalizeName(moduleFileName.replace(/[\/]/g, "-"));
          }
        }
      },
    },
    module: {
      rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          cssLoader,
          postCssLoader
        ]
      },
      {
        test: /\.(ttf|woff|eot|png|jpg|jpeg|svg)$/,
        type: "javascript/auto",
        loader: "file-loader",
        options: {
          name: (resourcePath, resourceQuery) => {
            let ext = path.extname(resourcePath);  // for instance ".jpg"
            return normalizeName(path.basename(resourcePath).slice(0, -ext.length)) + ext;
          }
        }
      }]
    },
    plugins: [
      new MiniCssExtractPlugin({
        filename: (pathData) => normalizeName(pathData.chunk.name) + ".css",
        chunkFilename: (pathData) => normalizeName(pathData.chunk.id) + ".css"
      }),
    ],
  };
};

这导致文件名超出名称限制,生成的输出文件夹中的文件名更短更简洁。