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 DefaultStatsPrinterPlugin = require("./stats/DefaultStatsPrinterPlugin");
|
||||
|
||||
const { STAGE_BASIC, STAGE_ADVANCED } = require("./OptimizationStages");
|
||||
const { cleverMerge } = require("./util/cleverMerge");
|
||||
|
||||
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
|
|
@ -434,7 +435,7 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
}
|
||||
if (options.optimization.mergeDuplicateChunks) {
|
||||
const MergeDuplicateChunksPlugin = require("./optimize/MergeDuplicateChunksPlugin");
|
||||
new MergeDuplicateChunksPlugin().apply(compiler);
|
||||
new MergeDuplicateChunksPlugin(STAGE_BASIC).apply(compiler);
|
||||
}
|
||||
if (options.optimization.flagIncludedChunks) {
|
||||
const FlagIncludedChunksPlugin = require("./optimize/FlagIncludedChunksPlugin");
|
||||
|
|
@ -474,6 +475,10 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
const SplitChunksPlugin = require("./optimize/SplitChunksPlugin");
|
||||
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) {
|
||||
const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin");
|
||||
new RuntimeChunkPlugin(
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { STAGE_BASIC } = require("../OptimizationStages");
|
||||
const { runtimeEqual } = require("../util/runtime");
|
||||
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
||||
class MergeDuplicateChunksPlugin {
|
||||
constructor(stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler the compiler
|
||||
* @returns {void}
|
||||
|
|
@ -22,7 +25,7 @@ class MergeDuplicateChunksPlugin {
|
|||
compilation.hooks.optimizeChunks.tap(
|
||||
{
|
||||
name: "MergeDuplicateChunksPlugin",
|
||||
stage: STAGE_BASIC
|
||||
stage: this.stage
|
||||
},
|
||||
chunks => {
|
||||
const { chunkGraph, moduleGraph } = compilation;
|
||||
|
|
|
|||
|
|
@ -4724,6 +4724,29 @@ global:
|
|||
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`] = `
|
||||
"asset bundle.js X KiB [emitted] (name: main)
|
||||
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