webpack5共享块文件名



(抱歉,如果这已经被问到和回答之前-我试图寻找一个解决方案,但无法找到任何东西)。

我正在从webpack 4升级到webpack 5.

应用程序有两个入口点:"app"one_answers"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)。

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

  • 在webpack 4中,[name]占位符被描述为"模块名">
  • 在webpack 5中,[name]占位符被描述为"块的名称,如果设置,否则为块的ID">

我知道这是迂腐的,它不应该真正重要的文件是否被称为admin~app121,但有一种方法,我可以有共享块命名为它在webpack 4?

我在文档中使用了这个示例中的代码版本: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'
},
}
}
}
}

最新更新