From 0ab5b9e00ca88045505e035fdd51d8f48bb6a4aa Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Tue, 12 Nov 2024 19:42:30 +0300 Subject: [PATCH] feat: export `MergeDuplicateChunks` plugin --- declarations/plugins/BannerPlugin.d.ts | 2 +- lib/index.js | 3 +++ lib/optimize/MergeDuplicateChunksPlugin.js | 18 +++++++++++++++++- schemas/plugins/BannerPlugin.json | 2 +- .../optimize/MergeDuplicateChunksPlugin.json | 11 +++++++++++ .../StatsTestCases.basictest.js.snap | 10 +++++----- .../split-chunks-dedup/webpack.config.js | 6 +++++- types.d.ts | 8 +++++++- 8 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 schemas/plugins/optimize/MergeDuplicateChunksPlugin.json diff --git a/declarations/plugins/BannerPlugin.d.ts b/declarations/plugins/BannerPlugin.d.ts index d42d50d65..8f40cefae 100644 --- a/declarations/plugins/BannerPlugin.d.ts +++ b/declarations/plugins/BannerPlugin.d.ts @@ -51,7 +51,7 @@ export interface BannerPluginOptions { */ raw?: boolean; /** - * Specifies the banner. + * Specifies the stage when add a banner. */ stage?: number; /** diff --git a/lib/index.js b/lib/index.js index 80d1a1772..6d4bf60d6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -443,6 +443,9 @@ module.exports = mergeExports(fn, { get LimitChunkCountPlugin() { return require("./optimize/LimitChunkCountPlugin"); }, + get MergeDuplicateChunksPlugin() { + return require("./optimize/MergeDuplicateChunksPlugin.js"); + }, get MinChunkSizePlugin() { return require("./optimize/MinChunkSizePlugin"); }, diff --git a/lib/optimize/MergeDuplicateChunksPlugin.js b/lib/optimize/MergeDuplicateChunksPlugin.js index 76cc24795..e461ca671 100644 --- a/lib/optimize/MergeDuplicateChunksPlugin.js +++ b/lib/optimize/MergeDuplicateChunksPlugin.js @@ -6,11 +6,27 @@ "use strict"; const { STAGE_BASIC } = require("../OptimizationStages"); +const createSchemaValidation = require("../util/create-schema-validation"); const { runtimeEqual } = require("../util/runtime"); /** @typedef {import("../Compiler")} Compiler */ +const validate = createSchemaValidation( + require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js"), + () => + require("../../schemas/plugins/optimize/MergeDuplicateChunksPlugin.json"), + { + name: "Merge Duplicate Chunks Plugin", + baseDataPath: "options" + } +); + class MergeDuplicateChunksPlugin { + constructor(options = { stage: STAGE_BASIC }) { + validate(options); + this.options = options; + } + /** * @param {Compiler} compiler the compiler * @returns {void} @@ -22,7 +38,7 @@ class MergeDuplicateChunksPlugin { compilation.hooks.optimizeChunks.tap( { name: "MergeDuplicateChunksPlugin", - stage: STAGE_BASIC + stage: this.options.stage }, chunks => { const { chunkGraph, moduleGraph } = compilation; diff --git a/schemas/plugins/BannerPlugin.json b/schemas/plugins/BannerPlugin.json index 3167d41cc..9c3dfc0ae 100644 --- a/schemas/plugins/BannerPlugin.json +++ b/schemas/plugins/BannerPlugin.json @@ -90,7 +90,7 @@ "type": "boolean" }, "stage": { - "description": "Specifies the banner.", + "description": "Specifies the stage when add a banner.", "type": "number" }, "test": { diff --git a/schemas/plugins/optimize/MergeDuplicateChunksPlugin.json b/schemas/plugins/optimize/MergeDuplicateChunksPlugin.json new file mode 100644 index 000000000..12f591a2c --- /dev/null +++ b/schemas/plugins/optimize/MergeDuplicateChunksPlugin.json @@ -0,0 +1,11 @@ +{ + "title": "MergeDuplicateChunksPluginOptions", + "type": "object", + "additionalProperties": false, + "properties": { + "stage": { + "description": "Specifies the stage for merging duplicate chunks.", + "type": "number" + } + } +} diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap index e57d33574..c89955b92 100644 --- a/test/__snapshots__/StatsTestCases.basictest.js.snap +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -4813,22 +4813,22 @@ assets by path *.wasm X KiB asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] -chunk (runtime: main) 573.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default) +chunk (runtime: main) 573.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] ./Q_rsqrt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] -chunk (runtime: main) 672.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default) +chunk (runtime: main) 672.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] ./duff.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] chunk (runtime: main) 787.bundle.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors) ./node_modules/env.js X bytes [built] [code generated] chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] runtime modules X KiB 11 modules ./index.js X bytes [built] [code generated] -chunk (runtime: main) 836.bundle.js X KiB (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default) +chunk (runtime: main) 836.bundle.js X KiB (javascript) X bytes (webassembly) [rendered] ./testFunction.wasm X bytes (javascript) X bytes (webassembly) [dependent] [built] [code generated] ./tests.js X KiB [built] [code generated] -chunk (runtime: main) 946.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default) +chunk (runtime: main) 946.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] ./fact.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] ./fast-math.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] -chunk (runtime: main) 989.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] reused as split chunk (cache group: default) +chunk (runtime: main) 989.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] ./popcnt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] runtime modules X KiB 11 modules cacheable modules X KiB (javascript) X KiB (webassembly) diff --git a/test/statsCases/split-chunks-dedup/webpack.config.js b/test/statsCases/split-chunks-dedup/webpack.config.js index 04bb7fa18..27ff95859 100644 --- a/test/statsCases/split-chunks-dedup/webpack.config.js +++ b/test/statsCases/split-chunks-dedup/webpack.config.js @@ -1,4 +1,5 @@ -const { ModuleFederationPlugin } = require("../../../").container; +const webpack = require("../../../"); +const { ModuleFederationPlugin } = webpack.container; const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../../../lib/ModuleTypeConstants"); @@ -70,6 +71,9 @@ module.exports = { requiredVersion: "=1.0.0" } } + }), + new webpack.optimize.MergeDuplicateChunksPlugin({ + stage: 10 }) ], stats: { diff --git a/types.d.ts b/types.d.ts index 56d09097c..aba7d2701 100644 --- a/types.d.ts +++ b/types.d.ts @@ -513,7 +513,7 @@ declare interface BannerPluginOptions { raw?: boolean; /** - * Specifies the banner. + * Specifies the stage when add a banner. */ stage?: number; @@ -8643,6 +8643,11 @@ declare class MemoryCachePlugin { */ apply(compiler: Compiler): void; } +declare class MergeDuplicateChunksPlugin { + constructor(options?: { stage: -10 }); + options: { stage: -10 }; + apply(compiler: Compiler): void; +} declare class MinChunkSizePlugin { constructor(options: MinChunkSizePluginOptions); options: MinChunkSizePluginOptions; @@ -16122,6 +16127,7 @@ declare namespace exports { AggressiveMergingPlugin, AggressiveSplittingPlugin, LimitChunkCountPlugin, + MergeDuplicateChunksPlugin, MinChunkSizePlugin, ModuleConcatenationPlugin, RealContentHashPlugin,