首页 > 解决方案 > Webpack 5 共享块文件名

问题描述

(抱歉,如果之前有人问过并回答过这个问题 - 我试图寻找解决方案,但找不到任何东西)。

我正在从 webpack 4 → 5 升级应用程序。

该应用程序有两个入口点:“app”和“admin”。

目标是重现与 webpack 4 相同的输出,特别是:

/dist/admin.js      // admin chunk
/dist/admin~app.js  // shared chunk for app + admin
/dist/app.js        // app chunk
/dist/runtime.js    // webpack runtime chunk (from runtimeChunk: "single")
/dist/vendor.js     // vendor chunk (node_modules)

webpack 4 的配置是:

entry: {
  app: "app",
  admin: "admin"
},
output: {
  filename: "[name].js"
},
optimization: {
  moduleIds: "hashed",
  splitChunks: {
    chunks: "all",
    cacheGroups: {
      vendor: {
        name: "vendor",
        test: /[\\/]node_modules[\\/]/
      }
    }
  },
  runtimeChunk: "single"
}

这会产生预期的输出。

在 webpack 5 中,我们现在可以删除output.filenameoptimization.moduleIds因为这些是默认设置,但其他一切基本保持不变:

entry: {
  app: "app",
  admin: "admin"
},
optimization: {
  splitChunks: {
    chunks: "all",
    cacheGroups: {
      vendor: {
        name: "vendor",
        test: /[\\/]node_modules[\\/]/
      }
    }
  },
  runtimeChunk: "single"
}

但是,这会产生以下输出:

/dist/121.js        // shared chunk for app + admin
/dist/admin.js      // admin chunk
/dist/app.js        // app chunk
/dist/runtime.js    // runtime chunk
/dist/vendor.js     // vendor chunk

请注意,以前命名的共享块admin~app.js现在具有(似乎是)一个散列模块 ID 作为名称 ( 121.js)。

我猜测差异可能与文档中的这种变化有关:

我知道这是迂腐的,是否调用文件并不重要,admin~app或者121有没有办法可以像在 webpack 4 中那样命名共享块?

标签: webpack-5

解决方案


我在文档中使用此示例中的代码版本:https ://webpack.js.org/plugins/split-chunks-plugin/#splitchunksname

这可能对你有用,但我实际上并没有拆分节点模块,只有一个包含供应商和非供应商块的缓存组,但我使用相同的特殊name功能。我不知道它如何或为什么起作用,但它似乎做了我最想做的事。

{
    //...
    optimization: {
        // Factor the webpack runtime out into a single dependency rather than
        // baking it into each entry point.
        // Include it before the other deps for each entry point.
        runtimeChunk: 'single',
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: function (module, chunks, cacheGroupKey) {
                        const moduleFileName = module
                            .identifier()
                            .split('/')
                            .reduceRight((item) => item);
                        // This is taken from the documentation but there
                        // seems to be no great explaination but it seems
                        // to be what we need, joining the entry point names
                        // together by ~.  We can then determine which chunk/file
                        // needs to be loaded by each entry point.
                        const allChunksNames = chunks.map((item) => item.name).join('~');
                        return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
                    },
                    chunks: 'all',
                    priority: -10,
                    reuseExistingChunk: true
                },
                commons: {
                    priority: -20,
                    reuseExistingChunk: true,
                    name: function (module, chunks, cacheGroupKey) {
                        const moduleFileName = module
                            .identifier()
                            .split('/')
                            .reduceRight((item) => item);
                        // This is taken from the documentation but there
                        // seems to be no great explaination but it seems
                        // to be what we need, joining the entry point names
                        // together by ~.  We can then determine which chunk/file
                        // needs to be loaded by each entry point.
                        const allChunksNames = chunks.map((item) => item.name).join('~');
                        return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
                    },
                    // Automatically split all code as needed into separate files.
                    chunks: 'all'
                },
            }
        }
    }
}

我的配置看起来更像这样:

{
    //...
    optimization: {
        // Factor the webpack runtime out into a single dependency rather than
        // baking it into each entry point.
        // Include it before the other deps for each entry point.
        runtimeChunk: 'single',
        splitChunks: {
                commons: {
                    name: function (module, chunks, cacheGroupKey) {
                        const moduleFileName = module
                            .identifier()
                            .split('/')
                            .reduceRight((item) => item);
                        // This is taken from the documentation but there
                        // seems to be no great explaination but it seems
                        // to be what we need, joining the entry point names
                        // together by ~.  We can then determine which chunk/file
                        // needs to be loaded by each entry point.
                        const allChunksNames = chunks.map((item) => item.name).join('~');
                        return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
                    },
                    // Automatically split all code as needed into separate files.
                    chunks: 'all'
                },
            }
        }
    }
}

推荐阅读