mirror of https://github.com/webpack/webpack.git
fix: add extra merge duplicates call after split chunks
This commit is contained in:
parent
6c4fd198d1
commit
1b217a6d94
|
|
@ -53,6 +53,7 @@ const DefaultStatsFactoryPlugin = require("./stats/DefaultStatsFactoryPlugin");
|
||||||
const DefaultStatsPresetPlugin = require("./stats/DefaultStatsPresetPlugin");
|
const DefaultStatsPresetPlugin = require("./stats/DefaultStatsPresetPlugin");
|
||||||
const DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
|
const DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
|
||||||
|
|
||||||
|
const { STAGE_BASIC, STAGE_ADVANCED } = require("./OptimizationStages");
|
||||||
const { cleverMerge } = require("./util/cleverMerge");
|
const { cleverMerge } = require("./util/cleverMerge");
|
||||||
|
|
||||||
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||||
|
|
@ -434,7 +435,7 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
}
|
}
|
||||||
if (options.optimization.mergeDuplicateChunks) {
|
if (options.optimization.mergeDuplicateChunks) {
|
||||||
const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
|
const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
|
||||||
new MergeDuplicateChunksPlugin().apply(compiler);
|
new MergeDuplicateChunksPlugin(STAGE_BASIC).apply(compiler);
|
||||||
}
|
}
|
||||||
if (options.optimization.flagIncludedChunks) {
|
if (options.optimization.flagIncludedChunks) {
|
||||||
const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
|
const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
|
||||||
|
|
@ -474,6 +475,10 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
const SplitChunksPlugin = require("./optimize/SplitChunksPlugin");
|
const SplitChunksPlugin = require("./optimize/SplitChunksPlugin");
|
||||||
new SplitChunksPlugin(options.optimization.splitChunks).apply(compiler);
|
new SplitChunksPlugin(options.optimization.splitChunks).apply(compiler);
|
||||||
}
|
}
|
||||||
|
if (options.optimization.mergeDuplicateChunks) {
|
||||||
|
const MergeDuplicateChunksPluginAdv = require("./optimize/MergeDuplicateChunksPlugin");
|
||||||
|
new MergeDuplicateChunksPluginAdv(STAGE_ADVANCED).apply(compiler);
|
||||||
|
}
|
||||||
if (options.optimization.runtimeChunk) {
|
if (options.optimization.runtimeChunk) {
|
||||||
const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin");
|
const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin");
|
||||||
new RuntimeChunkPlugin(
|
new RuntimeChunkPlugin(
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,15 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { STAGE_BASIC } = require("../OptimizationStages");
|
|
||||||
const { runtimeEqual } = require("../util/runtime");
|
const { runtimeEqual } = require("../util/runtime");
|
||||||
|
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
|
|
||||||
class MergeDuplicateChunksPlugin {
|
class MergeDuplicateChunksPlugin {
|
||||||
|
constructor(stage) {
|
||||||
|
this.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Compiler} compiler the compiler
|
* @param {Compiler} compiler the compiler
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
|
@ -22,7 +25,7 @@ class MergeDuplicateChunksPlugin {
|
||||||
compilation.hooks.optimizeChunks.tap(
|
compilation.hooks.optimizeChunks.tap(
|
||||||
{
|
{
|
||||||
name: "MergeDuplicateChunksPlugin",
|
name: "MergeDuplicateChunksPlugin",
|
||||||
stage: STAGE_BASIC
|
stage: this.stage
|
||||||
},
|
},
|
||||||
chunks => {
|
chunks => {
|
||||||
const { chunkGraph, moduleGraph } = compilation;
|
const { chunkGraph, moduleGraph } = compilation;
|
||||||
|
|
|
||||||
|
|
@ -4724,6 +4724,29 @@ global:
|
||||||
global (webpack x.x.x) compiled successfully in X ms"
|
global (webpack x.x.x) compiled successfully in X ms"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`StatsTestCases should print correct stats for split-chunks-dedup 1`] = `
|
||||||
|
"asset main.js X KiB [emitted] (name: main) (id hint: main)
|
||||||
|
asset table--shared X bytes [emitted]
|
||||||
|
asset row-359--shared X bytes [emitted]
|
||||||
|
asset cell--shared X bytes [emitted]
|
||||||
|
asset templater--shared X bytes [emitted]
|
||||||
|
runtime modules X KiB 11 modules
|
||||||
|
built modules X bytes (javascript) X bytes (share-init) X bytes (consume-shared) [built]
|
||||||
|
cacheable modules X bytes
|
||||||
|
modules by path ./node_modules/ X bytes 4 modules
|
||||||
|
modules by path ./*.js X bytes 2 modules
|
||||||
|
provide-module modules X bytes
|
||||||
|
provide shared module (default) cell@1.0.0 = ./node_modules/cell/index.js X bytes [built] [code generated]
|
||||||
|
provide shared module (default) row@1.0.0 = ./node_modules/row/index.js X bytes [built] [code generated]
|
||||||
|
+ 2 modules
|
||||||
|
consume-shared-module modules X bytes
|
||||||
|
consume shared module (default) table@=1.0.0 (strict) (fallback: ./node_modules/...(truncated) X bytes [built] [code generated]
|
||||||
|
consume shared module (default) row@=1.0.0 (strict) (fallback: ./node_modules...(truncated) X bytes [built] [code generated]
|
||||||
|
consume shared module (default) templater@=1.0.0 (strict) (fallback: ./node_modu...(truncated) X bytes [built] [code generated]
|
||||||
|
consume shared module (default) cell@=1.0.0 (strict) (fallback: ./node_modules/...(truncated) X bytes [built] [code generated]
|
||||||
|
webpack x.x.x compiled successfully in X ms"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
|
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
|
||||||
"asset bundle.js X KiB [emitted] (name: main)
|
"asset bundle.js X KiB [emitted] (name: main)
|
||||||
runtime modules X bytes 3 modules
|
runtime modules X bytes 3 modules
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export default async () => {
|
||||||
|
const { test } = await import(/* webpackMode: "eager" */'./module')
|
||||||
|
|
||||||
|
test()
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { table } from 'table'
|
||||||
|
|
||||||
|
export function test() {
|
||||||
|
expect(table([['1']])).toBe('<table><tr><td>1</td></tr></table>')
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
const { tmpl } = require('templater')
|
||||||
|
|
||||||
|
module.exports.cell = function(cell) {
|
||||||
|
return tmpl(`<td>CELL</td>`, { CELL: cell })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "row",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"cell": "=1.0.0",
|
||||||
|
"templater": "=1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
const { cell } = require('cell')
|
||||||
|
const { tmpl } = require('templater')
|
||||||
|
|
||||||
|
module.exports.row = function(cells) {
|
||||||
|
return tmpl(`<tr>CELLS</tr>`, { CELLS: cells.map(c => cell(c)).join('\n') })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "row",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"cell": "=1.0.0",
|
||||||
|
"templater": "=1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
const { row } = require('row')
|
||||||
|
const { tmpl } = require('templater')
|
||||||
|
|
||||||
|
module.exports.table = function(rows) {
|
||||||
|
return tmpl('<table>ROWS</table>', { ROWS: rows.map(r => row(r)).join('\n') })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "table",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"row": "=1.0.0",
|
||||||
|
"templater": "=1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports.tmpl = function(str, params) {
|
||||||
|
Object.keys(params).forEach((k) => {
|
||||||
|
str = str.replace(new RegExp(k, 'g'), params[k])
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
4
test/statsCases/split-chunks-dedup/node_modules/templater/package.json
generated
vendored
Normal file
4
test/statsCases/split-chunks-dedup/node_modules/templater/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"name": "templater",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"table": "=2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
const { ModuleFederationPlugin } = require("../../../").container;
|
||||||
|
const {
|
||||||
|
WEBPACK_MODULE_TYPE_PROVIDE
|
||||||
|
} = require("../../../lib/ModuleTypeConstants");
|
||||||
|
|
||||||
|
const chunkIdChunkNameMap = new Map();
|
||||||
|
const usedSharedModuleNames = new Set();
|
||||||
|
|
||||||
|
/** @type {import("../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
main: "./"
|
||||||
|
},
|
||||||
|
mode: "production",
|
||||||
|
optimization: {
|
||||||
|
splitChunks: {
|
||||||
|
cacheGroups: {
|
||||||
|
defaultVendors: false,
|
||||||
|
main: {
|
||||||
|
name: "main",
|
||||||
|
enforce: true,
|
||||||
|
minChunks: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
chunkFilename(pathData) {
|
||||||
|
const { chunk } = pathData;
|
||||||
|
if (chunk && "groupsIterable" in chunk) {
|
||||||
|
for (const group of chunk.groupsIterable) {
|
||||||
|
if (group.origins) {
|
||||||
|
for (const origin of group.origins) {
|
||||||
|
if (
|
||||||
|
origin.module.type === WEBPACK_MODULE_TYPE_PROVIDE &&
|
||||||
|
chunk.id
|
||||||
|
) {
|
||||||
|
if (chunkIdChunkNameMap.has(chunk.id)) {
|
||||||
|
return chunkIdChunkNameMap.get(chunk.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
const sharedModuleName = origin.module._name;
|
||||||
|
let suffix = "";
|
||||||
|
if (usedSharedModuleNames.has(sharedModuleName)) {
|
||||||
|
suffix = `-${chunk.id}`;
|
||||||
|
}
|
||||||
|
const chunkName = `${sharedModuleName}${suffix}--shared`;
|
||||||
|
usedSharedModuleNames.add(sharedModuleName);
|
||||||
|
chunkIdChunkNameMap.set(chunk.id, chunkName);
|
||||||
|
|
||||||
|
return chunkName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "[id]--chunk";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new ModuleFederationPlugin({
|
||||||
|
shared: {
|
||||||
|
table: {
|
||||||
|
requiredVersion: "=1.0.0"
|
||||||
|
},
|
||||||
|
cell: {
|
||||||
|
requiredVersion: "=1.0.0"
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
requiredVersion: "=1.0.0"
|
||||||
|
},
|
||||||
|
templater: {
|
||||||
|
requiredVersion: "=1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
assets: true
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue