From 3e75d36d18f8450805f760e787a83087bb0a8fce Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 11 Dec 2019 21:55:18 +0300 Subject: [PATCH 01/20] deprecate using string as a loader options --- lib/NormalModuleFactory.js | 10 ++++++++++ lib/util/deprecation.js | 2 ++ 2 files changed, 12 insertions(+) diff --git a/lib/NormalModuleFactory.js b/lib/NormalModuleFactory.js index 1463c78c7..4e1903c6d 100644 --- a/lib/NormalModuleFactory.js +++ b/lib/NormalModuleFactory.js @@ -23,6 +23,7 @@ const RuleSetCompiler = require("./rules/RuleSetCompiler"); const UseEffectRulePlugin = require("./rules/UseEffectRulePlugin"); const LazySet = require("./util/LazySet"); const { cachedCleverMerge } = require("./util/cleverMerge"); +const { createDeprecation } = require("./util/deprecation"); const { join } = require("./util/fs"); /** @typedef {import("./Generator")} Generator */ @@ -577,6 +578,15 @@ class NormalModuleFactory extends ModuleFactory { resolveContext, callback ) { + for (const item of array) { + if (typeof item.options === "string") { + createDeprecation( + `Using string as a loader options is deprecated (${item.loader}${item.options})`, + "LOADER_OPTIONS_STRING" + ).call(null); + } + } + if (array.length === 0) return callback(null, array); asyncLib.map( array, diff --git a/lib/util/deprecation.js b/lib/util/deprecation.js index 55aa884c7..41851985e 100644 --- a/lib/util/deprecation.js +++ b/lib/util/deprecation.js @@ -158,3 +158,5 @@ exports.createArrayToSetDeprecationSet = name => { exports.arrayToSetDeprecation(SetDeprecatedArray.prototype, name); return SetDeprecatedArray; }; + +exports.createDeprecation = createDeprecation; From c11f89c9769f08eab7ac976f1a77f7b9b0687dcd Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Mon, 16 Dec 2019 13:40:04 +0300 Subject: [PATCH 02/20] pr comments --- lib/NormalModuleFactory.js | 10 ---------- lib/rules/UseEffectRulePlugin.js | 8 ++++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/NormalModuleFactory.js b/lib/NormalModuleFactory.js index 4e1903c6d..1463c78c7 100644 --- a/lib/NormalModuleFactory.js +++ b/lib/NormalModuleFactory.js @@ -23,7 +23,6 @@ const RuleSetCompiler = require("./rules/RuleSetCompiler"); const UseEffectRulePlugin = require("./rules/UseEffectRulePlugin"); const LazySet = require("./util/LazySet"); const { cachedCleverMerge } = require("./util/cleverMerge"); -const { createDeprecation } = require("./util/deprecation"); const { join } = require("./util/fs"); /** @typedef {import("./Generator")} Generator */ @@ -578,15 +577,6 @@ class NormalModuleFactory extends ModuleFactory { resolveContext, callback ) { - for (const item of array) { - if (typeof item.options === "string") { - createDeprecation( - `Using string as a loader options is deprecated (${item.loader}${item.options})`, - "LOADER_OPTIONS_STRING" - ).call(null); - } - } - if (array.length === 0) return callback(null, array); asyncLib.map( array, diff --git a/lib/rules/UseEffectRulePlugin.js b/lib/rules/UseEffectRulePlugin.js index 8d44abb12..16892fa04 100644 --- a/lib/rules/UseEffectRulePlugin.js +++ b/lib/rules/UseEffectRulePlugin.js @@ -5,6 +5,8 @@ "use strict"; +const { createDeprecation } = require("../util/deprecation"); + /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ /** @typedef {import("./RuleSetCompiler").Effect} Effect */ @@ -77,6 +79,12 @@ class UseEffectRulePlugin { if (!ident) ident = defaultIdent; references.set(ident, options); } + if (typeof options === "string") { + createDeprecation( + `Using string as a loader options is deprecated (${loader}: ${options})`, + "LOADER_OPTIONS_STRING" + ).call(null); + } return { type: enforce ? `use-${enforce}` : "use", value: { From 70e9be9158c7bb4502d9cc40d9eeca6090c5918a Mon Sep 17 00:00:00 2001 From: Erik van der Bas - PC Date: Mon, 16 Dec 2019 13:21:39 +0100 Subject: [PATCH 03/20] Assign fallback ChunkGraph to HotUpdateChunks --- lib/HotModuleReplacementPlugin.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/HotModuleReplacementPlugin.js b/lib/HotModuleReplacementPlugin.js index 6d51b0e34..38d28071b 100644 --- a/lib/HotModuleReplacementPlugin.js +++ b/lib/HotModuleReplacementPlugin.js @@ -7,6 +7,7 @@ const { SyncBailHook } = require("tapable"); const { RawSource } = require("webpack-sources"); +const ChunkGraph = require("./ChunkGraph"); const HotUpdateChunk = require("./HotUpdateChunk"); const NormalModule = require("./NormalModule"); const RuntimeGlobals = require("./RuntimeGlobals"); @@ -331,6 +332,7 @@ class HotModuleReplacementPlugin { ); if (newModules.length > 0 || removedModules.length > 0) { const hotUpdateChunk = new HotUpdateChunk(); + ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph); hotUpdateChunk.id = chunkId; chunkGraph.attachModules(hotUpdateChunk, newModules); chunkGraph.attachRuntimeModules( From 3fc0a55babfa1c867aee29be180531ced5204998 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2019 13:55:54 +0000 Subject: [PATCH 04/20] chore(deps-dev): bump @types/node from 12.12.17 to 12.12.18 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.12.17 to 12.12.18. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7ee1a3eae..308391d53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -409,9 +409,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@>=4.5.0", "@types/node@^12.6.9": - version "12.12.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.17.tgz#191b71e7f4c325ee0fb23bc4a996477d92b8c39b" - integrity sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA== + version "12.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" + integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== "@types/normalize-package-data@^2.4.0": version "2.4.0" From 5d18a8e27d3085b9b86dc225447b342833ee0701 Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 11 Dec 2019 00:58:26 +0300 Subject: [PATCH 05/20] persistent cache for concat modules --- lib/Compilation.js | 217 ++++++++++++---------- lib/optimize/ConcatenatedModule.js | 59 +++++- lib/optimize/ModuleConcatenationPlugin.js | 101 ++++++---- lib/util/internalSerializables.js | 2 + 4 files changed, 235 insertions(+), 144 deletions(-) diff --git a/lib/Compilation.js b/lib/Compilation.js index 0ff7c08e3..a2529b2e8 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -11,7 +11,8 @@ const { SyncHook, SyncBailHook, SyncWaterfallHook, - AsyncSeriesHook + AsyncSeriesHook, + AsyncSeriesBailHook } = require("tapable"); const util = require("util"); const { CachedSource } = require("webpack-sources"); @@ -316,8 +317,8 @@ class Compilation { /** @type {SyncHook<[Iterable, Iterable]>} */ afterOptimizeTree: new SyncHook(["chunks", "modules"]), - /** @type {SyncBailHook<[Iterable, Iterable]>} */ - optimizeChunkModules: new SyncBailHook(["chunks", "modules"]), + /** @type {AsyncSeriesBailHook<[Iterable, Iterable]>} */ + optimizeChunkModules: new AsyncSeriesBailHook(["chunks", "modules"]), /** @type {SyncHook<[Iterable, Iterable]>} */ afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]), /** @type {SyncBailHook<[], boolean>} */ @@ -1523,123 +1524,135 @@ class Compilation { this.hooks.afterOptimizeTree.call(this.chunks, this.modules); - while (this.hooks.optimizeChunkModules.call(this.chunks, this.modules)) { - /* empty */ - } - this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules); - - const shouldRecord = this.hooks.shouldRecord.call() !== false; - - this.hooks.reviveModules.call(this.modules, this.records); - this.hooks.beforeModuleIds.call(this.modules); - this.hooks.moduleIds.call(this.modules); - this.hooks.optimizeModuleIds.call(this.modules); - this.hooks.afterOptimizeModuleIds.call(this.modules); - - this.hooks.reviveChunks.call(this.chunks, this.records); - this.hooks.beforeChunkIds.call(this.chunks); - this.hooks.chunkIds.call(this.chunks); - this.hooks.optimizeChunkIds.call(this.chunks); - this.hooks.afterOptimizeChunkIds.call(this.chunks); - - this.sortItemsWithChunkIds(); - - if (shouldRecord) { - this.hooks.recordModules.call(this.modules, this.records); - this.hooks.recordChunks.call(this.chunks, this.records); - } - - this.hooks.optimizeCodeGeneration.call(this.modules); - - this.hooks.beforeModuleHash.call(); - this.createModuleHashes(); - this.hooks.afterModuleHash.call(); - - this.hooks.beforeCodeGeneration.call(); - this.codeGenerationResults = this.codeGeneration(); - this.hooks.afterCodeGeneration.call(); - - this.hooks.beforeRuntimeRequirements.call(); - this.processRuntimeRequirements(this.entrypoints.values()); - this.hooks.afterRuntimeRequirements.call(); - - this.hooks.beforeHash.call(); - this.createHash(); - this.hooks.afterHash.call(); - - if (shouldRecord) { - this.hooks.recordHash.call(this.records); - } - - this.clearAssets(); - - this.hooks.beforeModuleAssets.call(); - this.createModuleAssets(); - - const cont = () => { - this.hooks.additionalChunkAssets.call(this.chunks); - this.summarizeDependencies(); - if (shouldRecord) { - this.hooks.record.call(this, this.records); - } - - this.hooks.additionalAssets.callAsync(err => { + this.hooks.optimizeChunkModules.callAsync( + this.chunks, + this.modules, + err => { if (err) { return callback( - makeWebpackError(err, "Compilation.hooks.additionalAssets") + makeWebpackError(err, "Compilation.hooks.optimizeChunkModules") ); } - this.hooks.optimizeChunkAssets.callAsync(this.chunks, err => { - if (err) { - return callback( - makeWebpackError(err, "Compilation.hooks.optimizeChunkAssets") - ); + + this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules); + + const shouldRecord = this.hooks.shouldRecord.call() !== false; + + this.hooks.reviveModules.call(this.modules, this.records); + this.hooks.beforeModuleIds.call(this.modules); + this.hooks.moduleIds.call(this.modules); + this.hooks.optimizeModuleIds.call(this.modules); + this.hooks.afterOptimizeModuleIds.call(this.modules); + + this.hooks.reviveChunks.call(this.chunks, this.records); + this.hooks.beforeChunkIds.call(this.chunks); + this.hooks.chunkIds.call(this.chunks); + this.hooks.optimizeChunkIds.call(this.chunks); + this.hooks.afterOptimizeChunkIds.call(this.chunks); + + this.sortItemsWithChunkIds(); + + if (shouldRecord) { + this.hooks.recordModules.call(this.modules, this.records); + this.hooks.recordChunks.call(this.chunks, this.records); + } + + this.hooks.optimizeCodeGeneration.call(this.modules); + + this.hooks.beforeModuleHash.call(); + this.createModuleHashes(); + this.hooks.afterModuleHash.call(); + + this.hooks.beforeCodeGeneration.call(); + this.codeGenerationResults = this.codeGeneration(); + this.hooks.afterCodeGeneration.call(); + + this.hooks.beforeRuntimeRequirements.call(); + this.processRuntimeRequirements(this.entrypoints.values()); + this.hooks.afterRuntimeRequirements.call(); + + this.hooks.beforeHash.call(); + this.createHash(); + this.hooks.afterHash.call(); + + if (shouldRecord) { + this.hooks.recordHash.call(this.records); + } + + this.clearAssets(); + + this.hooks.beforeModuleAssets.call(); + this.createModuleAssets(); + + const cont = () => { + this.hooks.additionalChunkAssets.call(this.chunks); + this.summarizeDependencies(); + if (shouldRecord) { + this.hooks.record.call(this, this.records); } - this.hooks.afterOptimizeChunkAssets.call(this.chunks); - this.hooks.optimizeAssets.callAsync(this.assets, err => { + + this.hooks.additionalAssets.callAsync(err => { if (err) { return callback( - makeWebpackError(err, "Compilation.hooks.optimizeAssets") + makeWebpackError(err, "Compilation.hooks.additionalAssets") ); } - this.hooks.afterOptimizeAssets.call(this.assets); - if (this.hooks.needAdditionalSeal.call()) { - this.unseal(); - return this.seal(callback); - } - this.hooks.finishAssets.callAsync(this.assets, err => { + this.hooks.optimizeChunkAssets.callAsync(this.chunks, err => { if (err) { return callback( - makeWebpackError(err, "Compilation.hooks.finishAssets") + makeWebpackError( + err, + "Compilation.hooks.optimizeChunkAssets" + ) ); } - this.hooks.afterFinishAssets.call(this.assets); - this.cache.storeBuildDependencies( - this.buildDependencies, - err => { - if (err) { - return callback(err); - } - return this.hooks.afterSeal.callAsync(callback); + this.hooks.afterOptimizeChunkAssets.call(this.chunks); + this.hooks.optimizeAssets.callAsync(this.assets, err => { + if (err) { + return callback( + makeWebpackError(err, "Compilation.hooks.optimizeAssets") + ); } - ); + this.hooks.afterOptimizeAssets.call(this.assets); + if (this.hooks.needAdditionalSeal.call()) { + this.unseal(); + return this.seal(callback); + } + this.hooks.finishAssets.callAsync(this.assets, err => { + if (err) { + return callback( + makeWebpackError(err, "Compilation.hooks.finishAssets") + ); + } + this.hooks.afterFinishAssets.call(this.assets); + this.cache.storeBuildDependencies( + this.buildDependencies, + err => { + if (err) { + return callback(err); + } + return this.hooks.afterSeal.callAsync(callback); + } + ); + }); + }); }); }); - }); - }); - }; + }; - if (this.hooks.shouldGenerateChunkAssets.call() !== false) { - this.hooks.beforeChunkAssets.call(); - this.createChunkAssets(err => { - if (err) { - return callback(err); + if (this.hooks.shouldGenerateChunkAssets.call() !== false) { + this.hooks.beforeChunkAssets.call(); + this.createChunkAssets(err => { + if (err) { + return callback(err); + } + cont(); + }); + } else { + cont(); } - cont(); - }); - } else { - cont(); - } + } + ); }); } diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index ebd401444..98dbd7285 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -29,6 +29,7 @@ const LazySet = require("../util/LazySet"); const { concatComparators, keepOriginalOrder } = require("../util/comparators"); const createHash = require("../util/createHash"); const contextify = require("../util/identifier").contextify; +const makeSerializable = require("../util/makeSerializable"); const propertyAccess = require("../util/propertyAccess"); /** @typedef {import("webpack-sources").Source} Source */ @@ -549,14 +550,15 @@ class ConcatenatedModule extends Module { /** * @param {Module} rootModule the root module of the concatenation * @param {Set} modules all modules in the concantenation (including the root module) - * @param {Compilation} compilation the compilation */ - constructor(rootModule, modules, compilation) { + constructor(rootModule, modules) { super("javascript/esm", null); // Info from Factory this.rootModule = rootModule; this.factoryMeta = rootModule.factoryMeta; + /** @private @type {Set} */ + this._modules = modules; const modulesArray = Array.from(modules); @@ -575,10 +577,23 @@ class ConcatenatedModule extends Module { // Caching this._numberOfConcatenatedModules = modules.size; + /** @private @type {string} */ + this._cachedCodeGenerationHash = ""; + /** @private @type {CodeGenerationResult} */ + this._cachedCodeGeneration = undefined; // Graph this.dependencies = []; + this._orderedConcatenationList = null; + this._identifier = null; + } + + /** + * @param {Compilation} compilation the compilation + */ + attach(compilation) { + const { rootModule, _modules: modules } = this; this._orderedConcatenationList = ConcatenatedModule._createConcatenationList( rootModule, modules, @@ -825,6 +840,12 @@ class ConcatenatedModule extends Module { moduleGraph, chunkGraph }) { + const hashDigest = this._getHashDigest(chunkGraph, dependencyTemplates); + if (this._cachedCodeGenerationHash === hashDigest) { + // We can reuse the cached data + return this._cachedCodeGeneration; + } + /** @type {Set} */ const runtimeRequirements = new Set(); @@ -1116,10 +1137,15 @@ class ConcatenatedModule extends Module { } } - return { + /** @type {CodeGenerationResult} */ + const resultEntry = { sources: new Map([["javascript", new CachedSource(result)]]), runtimeRequirements }; + + this._cachedCodeGeneration = resultEntry; + this._cachedCodeGenerationHash = hashDigest; + return resultEntry; } _analyseModule( @@ -1396,8 +1422,35 @@ class ConcatenatedModule extends Module { } super.updateHash(hash, chunkGraph); } + + serialize(context) { + const { write } = context; + // constructor + write(this.rootModule); + write(this.modules); + // deserialize + write(this._cachedCodeGenerationHash); + write(this._cachedCodeGeneration); + super.serialize(context); + } + + static deserialize(context) { + const { read } = context; + const obj = new ConcatenatedModule(read(), new Set(read())); + obj.deserialize(context); + return obj; + } + + deserialize(context) { + const { read } = context; + this._cachedCodeGenerationHash = read(); + this._cachedCodeGeneration = read(); + super.deserialize(context); + } } +makeSerializable(ConcatenatedModule, "webpack/lib/optimize/ConcatenatedModule"); + class HarmonyImportSpecifierDependencyConcatenatedTemplate extends DependencyTemplate { constructor(originalTemplate, modulesMap) { super(); diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index debbb44e5..15d985144 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -5,8 +5,10 @@ "use strict"; +const asyncLib = require("neo-async"); const ChunkGraph = require("../ChunkGraph"); const ModuleGraph = require("../ModuleGraph"); +const ModuleRestoreError = require("../ModuleRestoreError"); const { STAGE_DEFAULT } = require("../OptimizationStages"); const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); @@ -99,12 +101,12 @@ class ModuleConcatenationPlugin { } }; - compilation.hooks.optimizeChunkModules.tap( + compilation.hooks.optimizeChunkModules.tapAsync( { name: "ModuleConcatenationPlugin", stage: STAGE_DEFAULT }, - (allChunks, modules) => { + (allChunks, modules, cb) => { const chunkGraph = compilation.chunkGraph; const relevantModules = []; const possibleInners = new Set(); @@ -326,44 +328,65 @@ class ModuleConcatenationPlugin { return b.modules.size - a.modules.size; }); const usedModules = new Set(); - for (const concatConfiguration of concatConfigurations) { - if (usedModules.has(concatConfiguration.rootModule)) continue; - const modules = concatConfiguration.getModules(); - const rootModule = concatConfiguration.rootModule; - const newModule = new ConcatenatedModule( - rootModule, - modules, - compilation - ); - ChunkGraph.setChunkGraphForModule(newModule, chunkGraph); - ModuleGraph.setModuleGraphForModule(newModule, moduleGraph); - for (const warning of concatConfiguration.getWarningsSorted()) { - moduleGraph - .getOptimizationBailout(newModule) - .push(formatBailoutWarning(warning[0], warning[1])); - } - moduleGraph.cloneModuleAttributes(rootModule, newModule); - for (const m of modules) { - compilation.modules.delete(m); - usedModules.add(m); - // add to builtModules when one of the included modules was built - if (compilation.builtModules.has(m)) { - compilation.builtModules.add(newModule); - } - // remove module from chunk - chunkGraph.replaceModule(m, newModule); - // replace module references with the concatenated module - moduleGraph.moveModuleConnections(m, newModule, c => { - return !( - c.dependency instanceof HarmonyImportDependency && - modules.has(c.originModule) && - modules.has(c.module) - ); + + asyncLib.each( + concatConfigurations, + (concatConfiguration, cb) => { + if (usedModules.has(concatConfiguration.rootModule)) + return cb(); + const modules = concatConfiguration.getModules(); + const rootModule = concatConfiguration.rootModule; + let newModule = new ConcatenatedModule(rootModule, modules); + newModule.attach(compilation); + const identifier = newModule.identifier(); + const cacheName = `${compilation.compilerPath}/concatModule/${identifier}`; + compilation.cache.get(cacheName, null, (err, cacheModule) => { + if (err) return cb(new ModuleRestoreError(newModule, err)); + + if (cacheModule) { + cacheModule.updateCacheModule(newModule); + newModule = cacheModule; + newModule.attach(compilation); + } + + ChunkGraph.setChunkGraphForModule(newModule, chunkGraph); + ModuleGraph.setModuleGraphForModule(newModule, moduleGraph); + for (const warning of concatConfiguration.getWarningsSorted()) { + moduleGraph + .getOptimizationBailout(newModule) + .push(formatBailoutWarning(warning[0], warning[1])); + } + moduleGraph.cloneModuleAttributes(rootModule, newModule); + for (const m of modules) { + compilation.modules.delete(m); + usedModules.add(m); + // add to builtModules when one of the included modules was built + if (compilation.builtModules.has(m)) { + compilation.builtModules.add(newModule); + } + // remove module from chunk + chunkGraph.replaceModule(m, newModule); + // replace module references with the concatenated module + moduleGraph.moveModuleConnections(m, newModule, c => { + return !( + c.dependency instanceof HarmonyImportDependency && + modules.has(c.originModule) && + modules.has(c.module) + ); + }); + } + // add concatenated module to the compilation + compilation.modules.add(newModule); + + compilation.cache.store(cacheName, null, newModule, err => { + if (err) return cb(new ModuleRestoreError(newModule, err)); + + cb(); + }); }); - } - // add concatenated module to the compilation - compilation.modules.add(newModule); - } + }, + cb + ); } ); } diff --git a/lib/util/internalSerializables.js b/lib/util/internalSerializables.js index e0af6cf40..e5616f599 100644 --- a/lib/util/internalSerializables.js +++ b/lib/util/internalSerializables.js @@ -127,6 +127,8 @@ module.exports = { require("../dependencies/WebAssemblyExportImportedDependency"), "dependencies/WebAssemblyImportDependency": () => require("../dependencies/WebAssemblyImportDependency"), + "optimize/ConcatenatedModule": () => + require("../optimize/ConcatenatedModule"), DependenciesBlock: () => require("../DependenciesBlock"), ExternalModule: () => require("../ExternalModule"), Module: () => require("../Module"), From f12b8abcc09534202ca57ba124c10517a408c9fd Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 16 Dec 2019 14:50:10 +0100 Subject: [PATCH 06/20] Create error class for cache store errors --- lib/Compilation.js | 3 ++- lib/ModuleStoreError.js | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 lib/ModuleStoreError.js diff --git a/lib/Compilation.js b/lib/Compilation.js index a2529b2e8..58ada3d59 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -36,6 +36,7 @@ const ModuleGraph = require("./ModuleGraph"); const ModuleNotFoundError = require("./ModuleNotFoundError"); const ModuleProfile = require("./ModuleProfile"); const ModuleRestoreError = require("./ModuleRestoreError"); +const ModuleStoreError = require("./ModuleStoreError"); const ModuleTemplate = require("./ModuleTemplate"); const RuntimeGlobals = require("./RuntimeGlobals"); const RuntimeTemplate = require("./RuntimeTemplate"); @@ -952,7 +953,7 @@ class Compilation { } if (err) { this.hooks.failedModule.call(module, err); - return callback(err); + return callback(new ModuleStoreError(module, err)); } this.hooks.succeedModule.call(module); return callback(); diff --git a/lib/ModuleStoreError.js b/lib/ModuleStoreError.js new file mode 100644 index 000000000..6d81e22b7 --- /dev/null +++ b/lib/ModuleStoreError.js @@ -0,0 +1,44 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const WebpackError = require("./WebpackError"); + +/** @typedef {import("./Module")} Module */ + +class ModuleStoreError extends WebpackError { + /** + * @param {Module} module module tied to dependency + * @param {string | Error} err error thrown + */ + constructor(module, err) { + let message = "Module storing failed: "; + let details = undefined; + if (err !== null && typeof err === "object") { + if (typeof err.stack === "string" && err.stack) { + const stack = err.stack; + message += stack; + } else if (typeof err.message === "string" && err.message) { + message += err.message; + } else { + message += err; + } + } else { + message += String(err); + } + + super(message); + + this.name = "ModuleStoreError"; + this.details = details; + this.module = module; + this.error = err; + + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = ModuleStoreError; From 922500ed0d8a3fcaa26be694f38bbfe6addcd2a0 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 16 Dec 2019 14:51:34 +0100 Subject: [PATCH 07/20] test caching for concatenated modules --- test/TestCasesCachePack.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/TestCasesCachePack.test.js b/test/TestCasesCachePack.test.js index 51ac0ba0d..3a4cc8352 100644 --- a/test/TestCasesCachePack.test.js +++ b/test/TestCasesCachePack.test.js @@ -10,7 +10,8 @@ describe("TestCases", () => { }, optimization: { innerGraph: true, - usedExports: true + usedExports: true, + concatenateModules: true } }); }); From 73fd64fc90546b3510147c50e77dfe9c99df24b9 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 16 Dec 2019 18:44:33 +0100 Subject: [PATCH 08/20] refactor refactor ConcatenatedModule to avoid compilation argument avoid caching inner modules in ConcatenatedModule improve performance of ModuleConcatenationPlugin add ModuleStoreError when storing of module fails --- lib/optimize/ConcatenatedModule.js | 277 ++++++++++-------- lib/optimize/ModuleConcatenationPlugin.js | 194 ++++++++---- .../__snapshots__/StatsTestCases.test.js.snap | 76 ++--- 3 files changed, 329 insertions(+), 218 deletions(-) diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 98dbd7285..dcf76a89a 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -550,126 +550,76 @@ class ConcatenatedModule extends Module { /** * @param {Module} rootModule the root module of the concatenation * @param {Set} modules all modules in the concantenation (including the root module) + * @param {ModuleGraph} moduleGraph the module graph + * @param {Object=} associatedObjectForCache object for caching + * @returns {ConcatenatedModule} the module */ - constructor(rootModule, modules) { + static createFromModuleGraph( + rootModule, + modules, + moduleGraph, + associatedObjectForCache + ) { + const orderedConcatenationList = ConcatenatedModule._createConcatenationList( + rootModule, + modules, + moduleGraph + ); + const identifier = ConcatenatedModule._createIdentifier( + rootModule, + orderedConcatenationList, + associatedObjectForCache + ); + return new ConcatenatedModule({ + identifier, + rootModule, + orderedConcatenationList, + modules + }); + } + + /** + * @param {Object} options options + * @param {string} options.identifier the identifier of the module + * @param {Module=} options.rootModule the root module of the concatenation + * @param {Set=} options.modules all concatenated modules + * @param {TODO=} options.orderedConcatenationList the list of concentated modules and externals + */ + constructor({ identifier, rootModule, modules, orderedConcatenationList }) { super("javascript/esm", null); // Info from Factory + /** @type {string} */ + this._identifier = identifier; + /** @type {Module} */ this.rootModule = rootModule; - this.factoryMeta = rootModule.factoryMeta; - /** @private @type {Set} */ + /** @type {Set} */ this._modules = modules; - - const modulesArray = Array.from(modules); - - // Info from Build - this.buildInfo = { - strict: true, - cacheable: modulesArray.every(m => m.buildInfo.cacheable), - moduleArgument: rootModule.buildInfo.moduleArgument, - exportsArgument: rootModule.buildInfo.exportsArgument, - fileDependencies: new LazySet(), - contextDependencies: new LazySet(), - missingDependencies: new LazySet(), - assets: undefined - }; - this.buildMeta = rootModule.buildMeta; + this._orderedConcatenationList = orderedConcatenationList; + this.factoryMeta = rootModule && rootModule.factoryMeta; // Caching - this._numberOfConcatenatedModules = modules.size; /** @private @type {string} */ this._cachedCodeGenerationHash = ""; /** @private @type {CodeGenerationResult} */ this._cachedCodeGeneration = undefined; - - // Graph - this.dependencies = []; - - this._orderedConcatenationList = null; - this._identifier = null; } /** - * @param {Compilation} compilation the compilation + * Assuming this module is in the cache. Update the (cached) module with + * the fresh module from the factory. Usually updates internal references + * and properties. + * @param {Module} module fresh module + * @returns {void} */ - attach(compilation) { - const { rootModule, _modules: modules } = this; - this._orderedConcatenationList = ConcatenatedModule._createConcatenationList( - rootModule, - modules, - compilation - ); - for (const info of this._orderedConcatenationList) { - if (info.type === "concatenated") { - const m = info.module; - - // populate dependencies - for (const d of m.dependencies.filter( - dep => - !(dep instanceof HarmonyImportDependency) || - !modules.has(compilation.moduleGraph.getModule(dep)) - )) { - this.dependencies.push(d); - } - if (m.presentationalDependencies !== undefined) { - for (const d of m.presentationalDependencies.filter( - dep => - !(dep instanceof HarmonyImportDependency) || - !modules.has(compilation.moduleGraph.getModule(dep)) - )) { - this.addPresentationalDependency(d); - } - } - // populate file dependencies - if (m.buildInfo.fileDependencies) { - this.buildInfo.fileDependencies.addAll(m.buildInfo.fileDependencies); - } - // populate context dependencies - if (m.buildInfo.contextDependencies) { - this.buildInfo.contextDependencies.addAll( - m.buildInfo.contextDependencies - ); - } - // populate missing dependencies - if (m.buildInfo.missingDependencies) { - this.buildInfo.missingDependencies.addAll( - m.buildInfo.missingDependencies - ); - } - // populate warnings - const warnings = m.getWarnings(); - if (warnings !== undefined) { - for (const warning of warnings) { - this.addWarning(warning); - } - } - // populate errors - const errors = m.getErrors(); - if (errors !== undefined) { - for (const error of errors) { - this.addError(error); - } - } - - if (m.buildInfo.assets) { - if (this.buildInfo.assets === undefined) { - this.buildInfo.assets = Object.create(null); - } - Object.assign(this.buildInfo.assets, m.buildInfo.assets); - } - if (m.buildInfo.assetsInfo) { - if (this.buildInfo.assetsInfo === undefined) { - this.buildInfo.assetsInfo = new Map(); - } - for (const [key, value] of m.buildInfo.assetsInfo) { - this.buildInfo.assetsInfo.set(key, value); - } - } - } - } - this._identifier = this._createIdentifier(compilation.compiler.root); + updateCacheModule(module) { + super.updateCacheModule(module); + const m = /** @type {ConcatenatedModule} */ (module); + this._identifier = m._identifier; + this.rootModule = m.rootModule; + this._modules = m._modules; + this._orderedConcatenationList = m._orderedConcatenationList; } - /** * @returns {Set} types availiable (do not mutate) */ @@ -697,7 +647,7 @@ class ConcatenatedModule extends Module { readableIdentifier(requestShortener) { return ( this.rootModule.readableIdentifier(requestShortener) + - ` + ${this._numberOfConcatenatedModules - 1} modules` + ` + ${this._modules.size - 1} modules` ); } @@ -725,7 +675,90 @@ class ConcatenatedModule extends Module { * @returns {void} */ build(options, compilation, resolver, fs, callback) { - throw new Error("Cannot build this module. It should be already built."); + const { rootModule } = this; + this.buildInfo = { + strict: true, + cacheable: true, + moduleArgument: rootModule.buildInfo.moduleArgument, + exportsArgument: rootModule.buildInfo.exportsArgument, + fileDependencies: new LazySet(), + contextDependencies: new LazySet(), + missingDependencies: new LazySet(), + assets: undefined + }; + this.buildMeta = rootModule.buildMeta; + this.clearDependenciesAndBlocks(); + this.clearWarningsAndErrors(); + + for (const info of this._orderedConcatenationList) { + if (info.type === "concatenated") { + const m = info.module; + + // populate cacheable + if (!m.buildInfo.cacheable) { + this.buildInfo.cacheable = false; + } + + // populate dependencies + for (const d of m.dependencies.filter( + dep => + !(dep instanceof HarmonyImportDependency) || + !this._modules.has(compilation.moduleGraph.getModule(dep)) + )) { + this.dependencies.push(d); + } + + // populate file dependencies + if (m.buildInfo.fileDependencies) { + this.buildInfo.fileDependencies.addAll(m.buildInfo.fileDependencies); + } + // populate context dependencies + if (m.buildInfo.contextDependencies) { + this.buildInfo.contextDependencies.addAll( + m.buildInfo.contextDependencies + ); + } + // populate missing dependencies + if (m.buildInfo.missingDependencies) { + this.buildInfo.missingDependencies.addAll( + m.buildInfo.missingDependencies + ); + } + + // populate warnings + const warnings = m.getWarnings(); + if (warnings !== undefined) { + for (const warning of warnings) { + this.addWarning(warning); + } + } + + // populate errors + const errors = m.getErrors(); + if (errors !== undefined) { + for (const error of errors) { + this.addError(error); + } + } + + // populate assets + if (m.buildInfo.assets) { + if (this.buildInfo.assets === undefined) { + this.buildInfo.assets = Object.create(null); + } + Object.assign(this.buildInfo.assets, m.buildInfo.assets); + } + if (m.buildInfo.assetsInfo) { + if (this.buildInfo.assetsInfo === undefined) { + this.buildInfo.assetsInfo = new Map(); + } + for (const [key, value] of m.buildInfo.assetsInfo) { + this.buildInfo.assetsInfo.set(key, value); + } + } + } + } + callback(); } /** @@ -749,12 +782,10 @@ class ConcatenatedModule extends Module { * @private * @param {Module} rootModule the root of the concatenation * @param {Set} modulesSet a set of modules which should be concatenated - * @param {Compilation} compilation the compilation context + * @param {ModuleGraph} moduleGraph the module graph * @returns {ConcatenationEntry[]} concatenation list */ - static _createConcatenationList(rootModule, modulesSet, compilation) { - const { moduleGraph } = compilation; - + static _createConcatenationList(rootModule, modulesSet, moduleGraph) { const list = []; const set = new Set(); @@ -813,13 +844,17 @@ class ConcatenatedModule extends Module { return list; } - _createIdentifier(associatedObjectForCache) { + static _createIdentifier( + rootModule, + orderedConcatenationList, + associatedObjectForCache + ) { let orderedConcatenationListIdentifiers = ""; - for (let i = 0; i < this._orderedConcatenationList.length; i++) { - if (this._orderedConcatenationList[i].type === "concatenated") { + for (let i = 0; i < orderedConcatenationList.length; i++) { + if (orderedConcatenationList[i].type === "concatenated") { orderedConcatenationListIdentifiers += contextify( - this.rootModule.context, - this._orderedConcatenationList[i].module.identifier(), + rootModule.context, + orderedConcatenationList[i].module.identifier(), associatedObjectForCache ); orderedConcatenationListIdentifiers += " "; @@ -827,7 +862,7 @@ class ConcatenatedModule extends Module { } const hash = createHash("md4"); hash.update(orderedConcatenationListIdentifiers); - return this.rootModule.identifier() + "|" + hash.digest("hex"); + return rootModule.identifier() + "|" + hash.digest("hex"); } /** @@ -1425,18 +1460,18 @@ class ConcatenatedModule extends Module { serialize(context) { const { write } = context; - // constructor - write(this.rootModule); - write(this.modules); - // deserialize write(this._cachedCodeGenerationHash); write(this._cachedCodeGeneration); super.serialize(context); } static deserialize(context) { - const { read } = context; - const obj = new ConcatenatedModule(read(), new Set(read())); + const obj = new ConcatenatedModule({ + identifier: undefined, + rootModule: undefined, + orderedConcatenationList: undefined, + modules: undefined + }); obj.deserialize(context); return obj; } diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 15d985144..94ce1a965 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -9,6 +9,7 @@ const asyncLib = require("neo-async"); const ChunkGraph = require("../ChunkGraph"); const ModuleGraph = require("../ModuleGraph"); const ModuleRestoreError = require("../ModuleRestoreError"); +const ModuleStoreError = require("../ModuleStoreError"); const { STAGE_DEFAULT } = require("../OptimizationStages"); const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); @@ -106,10 +107,12 @@ class ModuleConcatenationPlugin { name: "ModuleConcatenationPlugin", stage: STAGE_DEFAULT }, - (allChunks, modules, cb) => { + (allChunks, modules, callback) => { + const logger = compilation.getLogger("ModuleConcatenationPlugin"); const chunkGraph = compilation.chunkGraph; const relevantModules = []; const possibleInners = new Set(); + logger.time("select relevant modules"); for (const module of modules) { // Only harmony modules are valid for optimization if ( @@ -272,12 +275,20 @@ class ModuleConcatenationPlugin { possibleInners.add(module); } + logger.timeEnd("select relevant modules"); + logger.debug( + `${relevantModules.length} potential root modules, ${possibleInners.size} potential inner modules` + ); // sort by depth // modules with lower depth are more likely suited as roots // this improves performance, because modules already selected as inner are skipped + logger.time("sort relevant modules"); relevantModules.sort((a, b) => { return moduleGraph.getDepth(a) - moduleGraph.getDepth(b); }); + logger.timeEnd("sort relevant modules"); + + logger.time("find modules to concatenate"); const concatConfigurations = []; const usedAsInner = new Set(); for (const currentRoot of relevantModules) { @@ -291,18 +302,33 @@ class ModuleConcatenationPlugin { // cache failures to add modules const failureCache = new Map(); + // potential optional import candiates + /** @type {Set} */ + const candidates = new Set(); + // try to add all imports for (const imp of this._getImports(compilation, currentRoot)) { + candidates.add(imp); + } + + for (const imp of candidates) { + // _tryToAdd modifies the config even if it fails + // so make sure to only accept changes when it succeed + const backup = currentConfiguration.snapshot(); const problem = this._tryToAdd( compilation, currentConfiguration, imp, possibleInners, + candidates, failureCache ); if (problem) { failureCache.set(imp, problem); currentConfiguration.addWarning(imp, problem); + + // roll back + currentConfiguration.rollback(backup); } } if (!currentConfiguration.isEmpty()) { @@ -313,42 +339,91 @@ class ModuleConcatenationPlugin { } } } else { + const optimizationBailouts = moduleGraph.getOptimizationBailout( + currentRoot + ); for (const warning of currentConfiguration.getWarningsSorted()) { - moduleGraph - .getOptimizationBailout(currentRoot) - .push(formatBailoutWarning(warning[0], warning[1])); + optimizationBailouts.push( + formatBailoutWarning(warning[0], warning[1]) + ); } } } + logger.timeEnd("find modules to concatenate"); + logger.debug( + `${concatConfigurations.length} concat configurations` + ); // HACK: Sort configurations by length and start with the longest one // to get the biggers groups possible. Used modules are marked with usedModules // TODO: Allow to reuse existing configuration while trying to add dependencies. // This would improve performance. O(n^2) -> O(n) + logger.time(`sort concat configurations`); concatConfigurations.sort((a, b) => { return b.modules.size - a.modules.size; }); + logger.timeEnd(`sort concat configurations`); const usedModules = new Set(); + logger.time("create concatenated modules"); asyncLib.each( concatConfigurations, - (concatConfiguration, cb) => { - if (usedModules.has(concatConfiguration.rootModule)) - return cb(); - const modules = concatConfiguration.getModules(); + (concatConfiguration, callback) => { const rootModule = concatConfiguration.rootModule; - let newModule = new ConcatenatedModule(rootModule, modules); - newModule.attach(compilation); + + // Avoid overlapping configurations + // TODO: remove this when todo above is fixed + if (usedModules.has(rootModule)) return callback(); + const modules = concatConfiguration.getModules(); + for (const m of modules) { + usedModules.add(m); + } + + // Create a new ConcatenatedModule + let newModule = ConcatenatedModule.createFromModuleGraph( + rootModule, + modules, + moduleGraph, + compiler.root + ); + + // get name for caching const identifier = newModule.identifier(); - const cacheName = `${compilation.compilerPath}/concatModule/${identifier}`; - compilation.cache.get(cacheName, null, (err, cacheModule) => { - if (err) return cb(new ModuleRestoreError(newModule, err)); + const cacheName = `${compilation.compilerPath}/ModuleConcatenationPlugin/${identifier}`; - if (cacheModule) { - cacheModule.updateCacheModule(newModule); - newModule = cacheModule; - newModule.attach(compilation); - } + const restore = () => { + compilation.cache.get(cacheName, null, (err, cacheModule) => { + if (err) { + return callback(new ModuleRestoreError(newModule, err)); + } + if (cacheModule) { + cacheModule.updateCacheModule(newModule); + newModule = cacheModule; + } + + build(); + }); + }; + + const build = () => { + newModule.build( + compiler.options, + compilation, + null, + null, + err => { + if (err) { + if (!err.module) { + err.module = newModule; + } + return callback(err); + } + integrateAndStore(); + } + ); + }; + + const integrateAndStore = () => { ChunkGraph.setChunkGraphForModule(newModule, chunkGraph); ModuleGraph.setModuleGraphForModule(newModule, moduleGraph); for (const warning of concatConfiguration.getWarningsSorted()) { @@ -359,7 +434,7 @@ class ModuleConcatenationPlugin { moduleGraph.cloneModuleAttributes(rootModule, newModule); for (const m of modules) { compilation.modules.delete(m); - usedModules.add(m); + // add to builtModules when one of the included modules was built if (compilation.builtModules.has(m)) { compilation.builtModules.add(newModule); @@ -379,13 +454,20 @@ class ModuleConcatenationPlugin { compilation.modules.add(newModule); compilation.cache.store(cacheName, null, newModule, err => { - if (err) return cb(new ModuleRestoreError(newModule, err)); + if (err) { + return callback(new ModuleStoreError(newModule, err)); + } - cb(); + callback(); }); - }); + }; + + restore(); }, - cb + err => { + logger.timeEnd("create concatenated modules"); + process.nextTick(() => callback(err)); + } ); } ); @@ -426,10 +508,18 @@ class ModuleConcatenationPlugin { * @param {ConcatConfiguration} config concat configuration (will be modified when added) * @param {Module} module the module to be added * @param {Set} possibleModules modules that are candidates + * @param {Set} candidates list of potential candidates (will be added to) * @param {Map} failureCache cache for problematic modules to be more performant * @returns {Module} the problematic module */ - _tryToAdd(compilation, config, module, possibleModules, failureCache) { + _tryToAdd( + compilation, + config, + module, + possibleModules, + candidates, + failureCache + ) { const cacheEntry = failureCache.get(module); if (cacheEntry) { return cacheEntry; @@ -446,11 +536,8 @@ class ModuleConcatenationPlugin { return module; } - // Clone config to make experimental changes - const testConfig = config.clone(); - // Add the module - testConfig.add(module); + config.add(module); const moduleGraph = compilation.moduleGraph; @@ -461,9 +548,10 @@ class ModuleConcatenationPlugin { const problem = this._tryToAdd( compilation, - testConfig, + config, connection.originModule, possibleModules, + candidates, failureCache ); if (problem) { @@ -472,21 +560,9 @@ class ModuleConcatenationPlugin { } } - // Commit experimental changes - config.set(testConfig); - - // Eagerly try to add imports too if possible + // Add imports to possible candiates list for (const imp of this._getImports(compilation, module)) { - const problem = this._tryToAdd( - compilation, - config, - imp, - possibleModules, - failureCache - ); - if (problem) { - config.addWarning(imp, problem); - } + candidates.add(imp); } return null; } @@ -496,22 +572,14 @@ class ConcatConfiguration { /** * * @param {Module} rootModule the root module - * @param {ConcatConfiguration=} cloneFrom base config */ - constructor(rootModule, cloneFrom) { + constructor(rootModule) { this.rootModule = rootModule; - if (cloneFrom) { - /** @type {StackedMap} */ - this.modules = cloneFrom.modules.createChild(); - /** @type {StackedMap} */ - this.warnings = cloneFrom.warnings.createChild(); - } else { - /** @type {StackedMap} */ - this.modules = new StackedMap(); - this.modules.set(rootModule, true); - /** @type {StackedMap} */ - this.warnings = new StackedMap(); - } + /** @type {StackedMap} */ + this.modules = new StackedMap(); + this.modules.set(rootModule, true); + /** @type {StackedMap} */ + this.warnings = new StackedMap(); } add(module) { @@ -549,14 +617,14 @@ class ConcatConfiguration { return this.modules.asSet(); } - clone() { - return new ConcatConfiguration(this.rootModule, this); + snapshot() { + const base = this.modules; + this.modules = this.modules.createChild(); + return base; } - set(config) { - this.rootModule = config.rootModule; - this.modules = config.modules; - this.warnings = config.warnings; + rollback(snapshot) { + this.modules = snapshot; } } diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 4fac74991..22c06c10e 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -641,26 +641,26 @@ Entrypoint entry-1 = vendor-1.js entry-1.js `; exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = ` -"Hash: cc1067a9ed68395a22d361ebf4f77d289ef5d090 +"Hash: 369dce9696722aff8630778eed1bb35adfdf68ee Child - Hash: cc1067a9ed68395a22d3 + Hash: 369dce9696722aff8630 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - app.e7c3ca90761b75404b15-1.js 5.86 KiB [emitted] [immutable] [name: app] + app.28702b7a86e378694d09-1.js 5.86 KiB [emitted] [immutable] [name: app] vendor.611fd9bad8fe7de29fe7-1.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor] - Entrypoint app = vendor.611fd9bad8fe7de29fe7-1.js app.e7c3ca90761b75404b15-1.js + Entrypoint app = vendor.611fd9bad8fe7de29fe7-1.js app.28702b7a86e378694d09-1.js ./entry-1.js + 2 modules 190 bytes [built] ./constants.js 87 bytes [built] + 3 hidden modules Child - Hash: 61ebf4f77d289ef5d090 + Hash: 778eed1bb35adfdf68ee Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - app.3543b1c65e6a5b58cae6-2.js 5.87 KiB [emitted] [immutable] [name: app] + app.11dd0b201bfcb5fa156a-2.js 5.87 KiB [emitted] [immutable] [name: app] vendor.611fd9bad8fe7de29fe7-2.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor] - Entrypoint app = vendor.611fd9bad8fe7de29fe7-2.js app.3543b1c65e6a5b58cae6-2.js + Entrypoint app = vendor.611fd9bad8fe7de29fe7-2.js app.11dd0b201bfcb5fa156a-2.js ./entry-2.js + 2 modules 197 bytes [built] ./constants.js 87 bytes [built] + 3 hidden modules" @@ -684,52 +684,52 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1` `; exports[`StatsTestCases should print correct stats for context-independence 1`] = ` -"Hash: 6506665a35d2ca5d31ac6506665a35d2ca5d31accf181f0e0e06350b116acf181f0e0e06350b116a +"Hash: 3bbcc69a5b6015de0e133bbcc69a5b6015de0e13b817462215fe98066a27b817462215fe98066a27 Child - Hash: 6506665a35d2ca5d31ac + Hash: 3bbcc69a5b6015de0e13 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - 703-3e2afd6460ceb1cd6f5f.js 438 bytes [emitted] [immutable] - 703-3e2afd6460ceb1cd6f5f.js.map 343 bytes [emitted] [dev] - main-a1003986d61ab330d2c5.js 8.14 KiB [emitted] [immutable] [name: main] - main-a1003986d61ab330d2c5.js.map 7.2 KiB [emitted] [dev] [name: (main)] - Entrypoint main = main-a1003986d61ab330d2c5.js (main-a1003986d61ab330d2c5.js.map) + 703-97267ca95e3cfbc183d4.js 438 bytes [emitted] [immutable] + 703-97267ca95e3cfbc183d4.js.map 343 bytes [emitted] [dev] + main-6b11eb1f2bbfff254738.js 8.14 KiB [emitted] [immutable] [name: main] + main-6b11eb1f2bbfff254738.js.map 7.2 KiB [emitted] [dev] [name: (main)] + Entrypoint main = main-6b11eb1f2bbfff254738.js (main-6b11eb1f2bbfff254738.js.map) ./a/index.js 40 bytes [built] ./a/chunk.js + 1 modules 66 bytes [built] + 6 hidden modules Child - Hash: 6506665a35d2ca5d31ac + Hash: 3bbcc69a5b6015de0e13 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - 703-3e2afd6460ceb1cd6f5f.js 438 bytes [emitted] [immutable] - 703-3e2afd6460ceb1cd6f5f.js.map 343 bytes [emitted] [dev] - main-a1003986d61ab330d2c5.js 8.14 KiB [emitted] [immutable] [name: main] - main-a1003986d61ab330d2c5.js.map 7.2 KiB [emitted] [dev] [name: (main)] - Entrypoint main = main-a1003986d61ab330d2c5.js (main-a1003986d61ab330d2c5.js.map) + 703-97267ca95e3cfbc183d4.js 438 bytes [emitted] [immutable] + 703-97267ca95e3cfbc183d4.js.map 343 bytes [emitted] [dev] + main-6b11eb1f2bbfff254738.js 8.14 KiB [emitted] [immutable] [name: main] + main-6b11eb1f2bbfff254738.js.map 7.2 KiB [emitted] [dev] [name: (main)] + Entrypoint main = main-6b11eb1f2bbfff254738.js (main-6b11eb1f2bbfff254738.js.map) ./b/index.js 40 bytes [built] ./b/chunk.js + 1 modules 66 bytes [built] + 6 hidden modules Child - Hash: cf181f0e0e06350b116a + Hash: b817462215fe98066a27 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - 703-d51a9ad771055bba3447.js 962 bytes [emitted] [immutable] - main-f8577eeb56b10147974d.js 8.48 KiB [emitted] [immutable] [name: main] - Entrypoint main = main-f8577eeb56b10147974d.js + 703-e96ad695ea376e8e9157.js 962 bytes [emitted] [immutable] + main-856478c0c82303c87701.js 8.48 KiB [emitted] [immutable] [name: main] + Entrypoint main = main-856478c0c82303c87701.js ./a/index.js 40 bytes [built] ./a/chunk.js + 1 modules 66 bytes [built] + 6 hidden modules Child - Hash: cf181f0e0e06350b116a + Hash: b817462215fe98066a27 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - 703-d51a9ad771055bba3447.js 962 bytes [emitted] [immutable] - main-f8577eeb56b10147974d.js 8.48 KiB [emitted] [immutable] [name: main] - Entrypoint main = main-f8577eeb56b10147974d.js + 703-e96ad695ea376e8e9157.js 962 bytes [emitted] [immutable] + main-856478c0c82303c87701.js 8.48 KiB [emitted] [immutable] [name: main] + Entrypoint main = main-856478c0c82303c87701.js ./b/index.js 40 bytes [built] ./b/chunk.js + 1 modules 66 bytes [built] + 6 hidden modules" @@ -1588,7 +1588,7 @@ If you don't want to include a polyfill, you can use an empty module like this: `; exports[`StatsTestCases should print correct stats for module-reasons 1`] = ` -"Hash: a74cbe7b899ea89c631e +"Hash: 7ad27c2fa358483a7fdd Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -2441,6 +2441,14 @@ LOG from webpack.SplitChunksPlugin modules: Xms queue: Xms maxSize: Xms + +LOG from ModuleConcatenationPlugin + select relevant modules: Xms + sort relevant modules: Xms + find modules to concatenate: Xms + sort concat configurations: Xms + create concatenated modules: Xms ++ 2 hidden lines " `; @@ -2531,7 +2539,7 @@ Entrypoint e2 = runtime.js e2.js" `; exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = ` -"Hash: ea361a8a1e8207bed262 +"Hash: 419464d6e886f327e369 Time: Xms Built at: 1970-04-20 12:42:42 Entrypoint index = index.js @@ -2561,7 +2569,7 @@ external \\"external\\" 42 bytes [built] `; exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = ` -"Hash: e2c7355c011145721c930f50cdfccf67cfa8eb2a +"Hash: e2c7355c011145721c93cfe13e3565883e0c5a86 Child Hash: e2c7355c011145721c93 Time: Xms @@ -2581,7 +2589,7 @@ Child ./common_lazy_shared.js 25 bytes [built] + 12 hidden modules Child - Hash: 0f50cdfccf67cfa8eb2a + Hash: cfe13e3565883e0c5a86 Time: Xms Built at: 1970-04-20 12:42:42 Entrypoint first = b-vendor.js b-first.js @@ -2608,7 +2616,7 @@ Child `; exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` -"Hash: dd7339ec873427ae72f9 +"Hash: 9ee30c02e5810205c6ce Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -2659,7 +2667,7 @@ Entrypoint main = main.js `; exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = ` -"Hash: 5e65a865b852c4d57af6 +"Hash: bba4214f926bfb74bb29 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size From fa57ed946cd30ad4f358cfff043a553851515daa Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 16 Dec 2019 19:48:27 +0100 Subject: [PATCH 09/20] extend persistent-caching example with bigger module concatenation --- examples/persistent-caching/README.md | 43 ++++++++++++++++++++++--- examples/persistent-caching/example.js | 3 ++ examples/persistent-caching/template.md | 8 +++++ package.json | 1 + yarn.lock | 5 +++ 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/examples/persistent-caching/README.md b/examples/persistent-caching/README.md index f95723e5c..0978b4986 100644 --- a/examples/persistent-caching/README.md +++ b/examples/persistent-caching/README.md @@ -9,6 +9,9 @@ import "react-dom"; import "acorn"; import "core-js"; import "date-fns"; +import "lodash"; +import * as _ from "lodash-es"; +console.log(_); ``` # webpack.config.js @@ -49,13 +52,43 @@ module.exports = (env = "development") => ({ # Info +## Unoptimized + ``` Hash: 0a1b2c3d4e5f6a7b8c9d -Version: webpack 5.0.0-beta.6 - Asset Size -output.js 2 MiB [emitted] [name: main] +Version: webpack 5.0.0-beta.9 + Asset Size +output.js 4.04 MiB [emitted] [name: main] Entrypoint main = output.js -chunk output.js (main) 1.74 MiB (javascript) 0 bytes (runtime) [entry] +chunk output.js (main) 2.85 MiB (javascript) 0 bytes (runtime) [entry] > ./example.js main - 529 chunk modules + 1172 chunk modules +``` + +## Production mode + +``` +Hash: 0a1b2c3d4e5f6a7b8c9d +Version: webpack 5.0.0-beta.9 + Asset Size + output.js 510 KiB [emitted] [big] [name: main] +output.js.LICENSE 1.49 KiB [emitted] +Entrypoint main [big] = output.js +chunk output.js (main) 1.8 MiB (javascript) 0 bytes (runtime) [entry] + > ./example.js main + 530 chunk modules + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). +This can impact web performance. +Assets: + output.js (510 KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. +Entrypoints: + main (510 KiB) + output.js + +WARNING in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ ``` diff --git a/examples/persistent-caching/example.js b/examples/persistent-caching/example.js index 786fd8e0e..f04e6a667 100644 --- a/examples/persistent-caching/example.js +++ b/examples/persistent-caching/example.js @@ -6,3 +6,6 @@ import "react-dom"; import "acorn"; import "core-js"; import "date-fns"; +import "lodash"; +import * as _ from "lodash-es"; +console.log(_); diff --git a/examples/persistent-caching/template.md b/examples/persistent-caching/template.md index 890a19bfa..2df3585bd 100644 --- a/examples/persistent-caching/template.md +++ b/examples/persistent-caching/template.md @@ -12,6 +12,14 @@ _{{webpack.config.js}}_ # Info +## Unoptimized + ``` _{{stdout}}_ ``` + +## Production mode + +``` +_{{production:stdout}}_ +``` diff --git a/package.json b/package.json index fa9972363..cfd4dfe92 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "less-loader": "^5.0.0", "lint-staged": "^9.2.1", "lodash": "^4.17.4", + "lodash-es": "^4.17.15", "memory-fs": "~0.5.0", "mini-css-extract-plugin": "^0.8.0", "mini-svg-data-uri": "^1.1.3", diff --git a/yarn.lock b/yarn.lock index 7ee1a3eae..c12cb554c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3916,6 +3916,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash-es@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" From 33d9f7bdbf3546c811d91f14ad4a125bce0cb91d Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Dec 2019 11:24:23 +0100 Subject: [PATCH 10/20] bugfix: candiates should only be added when adding was successful --- lib/optimize/ModuleConcatenationPlugin.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 94ce1a965..12d6f662b 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -315,12 +315,13 @@ class ModuleConcatenationPlugin { // _tryToAdd modifies the config even if it fails // so make sure to only accept changes when it succeed const backup = currentConfiguration.snapshot(); + const impCandiates = new Set(); const problem = this._tryToAdd( compilation, currentConfiguration, imp, possibleInners, - candidates, + impCandiates, failureCache ); if (problem) { @@ -329,6 +330,10 @@ class ModuleConcatenationPlugin { // roll back currentConfiguration.rollback(backup); + } else { + for (const c of impCandiates) { + candidates.add(c); + } } } if (!currentConfiguration.isEmpty()) { From 7205a200191806d9c3aeb187b44a6c1230c1a3b6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 11:07:51 +0000 Subject: [PATCH 11/20] chore(deps): bump terser-webpack-plugin from 2.2.1 to 2.3.1 Bumps [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) from 2.2.1 to 2.3.1. - [Release notes](https://github.com/webpack-contrib/terser-webpack-plugin/releases) - [Changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v2.2.1...v2.3.1) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 308391d53..7e86f3c9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2326,10 +2326,10 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.0.0.tgz#cd4b7dd97b7185b7e17dbfe2d6e4115ee3eeb8fc" - integrity sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw== +find-cache-dir@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.2.0.tgz#e7fe44c1abc1299f516146e563108fd1006c1874" + integrity sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg== dependencies: commondir "^1.0.1" make-dir "^3.0.0" @@ -5535,7 +5535,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0: +schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" integrity sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg== @@ -5570,10 +5570,10 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.2.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -serialize-javascript@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" - integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -6057,23 +6057,23 @@ temp-write@^4.0.0: uuid "^3.3.2" terser-webpack-plugin@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz#5569e6c7d8be79e5e43d6da23acc3b6ba77d22bd" - integrity sha512-jwdauV5Al7zopR6OAYvIIRcxXCSvLjZjr7uZE8l2tIWb/ryrGN48sJftqGf5k9z09tWhajx53ldp0XPI080YnA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.1.tgz#6a63c27debc15b25ffd2588562ee2eeabdcab923" + integrity sha512-dNxivOXmDgZqrGxOttBH6B4xaxT4zNC+Xd+2K8jwGDMK5q2CZI+KZMA1AAnSRT+BTRvuzKsDx+fpxzPAmAMVcA== dependencies: cacache "^13.0.1" - find-cache-dir "^3.0.0" + find-cache-dir "^3.2.0" jest-worker "^24.9.0" - schema-utils "^2.5.0" - serialize-javascript "^2.1.0" + schema-utils "^2.6.1" + serialize-javascript "^2.1.2" source-map "^0.6.1" - terser "^4.3.9" + terser "^4.4.3" webpack-sources "^1.4.3" -terser@^4.3.9: - version "4.3.9" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.9.tgz#e4be37f80553d02645668727777687dad26bbca8" - integrity sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA== +terser@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.3.tgz#401abc52b88869cf904412503b1eb7da093ae2f0" + integrity sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA== dependencies: commander "^2.20.0" source-map "~0.6.1" From 6deaf49dd2ff65a0b022493cbf583a37f86e923a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 12:46:37 +0000 Subject: [PATCH 12/20] chore(deps-dev): bump style-loader from 1.0.1 to 1.0.2 Bumps [style-loader](https://github.com/webpack-contrib/style-loader) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/webpack-contrib/style-loader/releases) - [Changelog](https://github.com/webpack-contrib/style-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/style-loader/compare/v1.0.1...v1.0.2) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 308391d53..345589189 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5964,9 +5964,9 @@ strip-json-comments@~2.0.1: integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= style-loader@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.1.tgz#aec6d4c61d0ed8d0a442faed741d4dfc6573888a" - integrity sha512-CnpEkSR1C+REjudiTWCv4+ssP7SCiuaQZJTZDWBRwTJoS90mdqkB8uOGMHKgVeUzpaU7IfLWoyQbvvs5Joj3Xw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.2.tgz#433d72eab8d1dd7d64c648b8ad7d9cbff3184111" + integrity sha512-xehHGWeCPrr+R/bU82To0j7L7ENzH30RHYmMhmAumbuIpQ/bHmv3SAj1aTRfBSszkXoqNtpKnJyWXEDydS+KeA== dependencies: loader-utils "^1.2.3" schema-utils "^2.0.1" From cc500384f69d23114153ff5707d8d5f97ee5d18d Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Dec 2019 14:22:18 +0100 Subject: [PATCH 13/20] update snapshots --- .../__snapshots__/StatsTestCases.test.js.snap | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 4fac74991..5d7af3c5d 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -811,9 +811,9 @@ external \\"test\\" 42 bytes [built]" `; exports[`StatsTestCases should print correct stats for filter-warnings 1`] = ` -"Hash: 9c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed33269c6e8f427e9f60ed3326 +"Hash: c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9c7acc7e9d00613f9def9 Child undefined: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -843,49 +843,49 @@ Child undefined: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child Terser: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle1.js 556 bytes [emitted] [name: main] Entrypoint main = bundle1.js Child /Terser/: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle2.js 556 bytes [emitted] [name: main] Entrypoint main = bundle2.js Child warnings => true: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle3.js 556 bytes [emitted] [name: main] Entrypoint main = bundle3.js Child [Terser]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle4.js 556 bytes [emitted] [name: main] Entrypoint main = bundle4.js Child [/Terser/]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle5.js 556 bytes [emitted] [name: main] Entrypoint main = bundle5.js Child [warnings => true]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size bundle6.js 556 bytes [emitted] [name: main] Entrypoint main = bundle6.js Child should not filter: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -915,7 +915,7 @@ Child should not filter: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child /should not filter/: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -945,7 +945,7 @@ Child /should not filter/: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child warnings => false: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -975,7 +975,7 @@ Child warnings => false: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child [should not filter]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -1005,7 +1005,7 @@ Child [should not filter]: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child [/should not filter/]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -1035,7 +1035,7 @@ Child [/should not filter/]: WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0] Child [warnings => false]: - Hash: 9c6e8f427e9f60ed3326 + Hash: c7acc7e9d00613f9def9 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -3753,7 +3753,7 @@ require.include() is deprecated and will be removed soon. `; exports[`StatsTestCases should print correct stats for warnings-terser 1`] = ` -"Hash: dcfa5b734e4c3a1e9e77 +"Hash: 65ad992aa3bdc02fd512 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size From 0d4e1584c06176f11b1ce10a2b706978d5367f52 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 14:17:09 +0000 Subject: [PATCH 14/20] chore(deps-dev): bump @types/node from 12.12.18 to 12.12.19 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.12.18 to 12.12.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 308391d53..7519695fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -409,9 +409,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@>=4.5.0", "@types/node@^12.6.9": - version "12.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.18.tgz#8d16634797d63c2af5bc647ce879f8de20b56469" - integrity sha512-DBkZuIMFuAfjJHiunyRc+aNvmXYNwV1IPMgGKGlwCp6zh6MKrVtmvjSWK/axWcD25KJffkXgkfvFra8ndenXAw== + version "12.12.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.19.tgz#6133aa2a765accdec89ad7792b651a0830f7a34e" + integrity sha512-OXw80IpKyLeuZ5a8r2XCxVNnRAtS3lRDHBleSUQmbgu3C6eKqRsz7/5XNBU0EvK0RTVfotvYFgvRwwe2jeoiKw== "@types/normalize-package-data@^2.4.0": version "2.4.0" From afb8b4b21c173347a159f0829d5ffa4e7765e028 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 14:23:20 +0000 Subject: [PATCH 15/20] chore(deps-dev): bump mini-css-extract-plugin from 0.8.0 to 0.8.1 Bumps [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) from 0.8.0 to 0.8.1. - [Release notes](https://github.com/webpack-contrib/mini-css-extract-plugin/releases) - [Changelog](https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.8.0...v0.8.1) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 308391d53..4341baf26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4154,9 +4154,9 @@ mimic-fn@^2.1.0: integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mini-css-extract-plugin@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz#81d41ec4fe58c713a96ad7c723cdb2d0bd4d70e1" - integrity sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw== + version "0.8.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.1.tgz#0b3cd3f9610e60860c58493ed170ca6d3c35daf3" + integrity sha512-YOMfkqV07IlP3xVFMuTXze8K+fa5WXW8PE3rb2P01XAD5UxpbrwMHIYQ/DPfWaOmTnS16TD7d8CRi8AyOmgJ8g== dependencies: loader-utils "^1.1.0" normalize-url "1.9.1" From 8318d7bf98e1b5ff083ff6da971028c11fe9d89f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 14:29:08 +0000 Subject: [PATCH 16/20] chore(deps-dev): bump css-loader from 3.3.2 to 3.4.0 Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v3.3.2...v3.4.0) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 308391d53..34a59fbfc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1518,9 +1518,9 @@ cross-spawn@^7.0.0: which "^2.0.1" css-loader@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.3.2.tgz#41b2086528aa4fbf8c0692e874bc14f081129b21" - integrity sha512-4XSiURS+YEK2fQhmSaM1onnUm0VKWNf6WWBYjkp9YbSDGCBTVZ5XOM6Gkxo8tLgQlzkZOBJvk9trHlDk4gjEYg== + version "3.4.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.0.tgz#9fb263436783117a41d014e45e8eaeba54dd6670" + integrity sha512-JornYo4RAXl1Mzt0lOSVPmArzAMV3rGY2VuwtaDc732WTWjdwTaeS19nCGWMcSCf305Q396lhhDAJEWWM0SgPQ== dependencies: camelcase "^5.3.1" cssesc "^3.0.0" From cfac87382f6c1828f084110489831e1bc79cc24e Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Dec 2019 16:33:06 +0100 Subject: [PATCH 17/20] cleaup add missing loader options place --- lib/rules/UseEffectRulePlugin.js | 19 ++++++++++++++----- lib/util/deprecation.js | 2 -- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/rules/UseEffectRulePlugin.js b/lib/rules/UseEffectRulePlugin.js index 16892fa04..9baf58a99 100644 --- a/lib/rules/UseEffectRulePlugin.js +++ b/lib/rules/UseEffectRulePlugin.js @@ -5,7 +5,7 @@ "use strict"; -const { createDeprecation } = require("../util/deprecation"); +const util = require("util"); /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ /** @typedef {import("./RuleSetCompiler").Effect} Effect */ @@ -80,10 +80,11 @@ class UseEffectRulePlugin { references.set(ident, options); } if (typeof options === "string") { - createDeprecation( - `Using string as a loader options is deprecated (${loader}: ${options})`, - "LOADER_OPTIONS_STRING" - ).call(null); + util.deprecate( + () => {}, + `Using a string as loader options is deprecated (${path}.options)`, + "DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING" + )(); } return { type: enforce ? `use-${enforce}` : "use", @@ -157,6 +158,14 @@ class UseEffectRulePlugin { ); } + if (typeof options === "string") { + util.deprecate( + () => {}, + `Using a string as loader options is deprecated (${path}.options)`, + "DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING" + )(); + } + result.effects.push({ type: enforce ? `use-${enforce}` : "use", value: { diff --git a/lib/util/deprecation.js b/lib/util/deprecation.js index 41851985e..55aa884c7 100644 --- a/lib/util/deprecation.js +++ b/lib/util/deprecation.js @@ -158,5 +158,3 @@ exports.createArrayToSetDeprecationSet = name => { exports.arrayToSetDeprecation(SetDeprecatedArray.prototype, name); return SetDeprecatedArray; }; - -exports.createDeprecation = createDeprecation; From 085f3d7f891a64f7c78f77fc7670ffb112f050e2 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Dec 2019 17:15:49 +0100 Subject: [PATCH 18/20] improve location reporting --- lib/rules/UseEffectRulePlugin.js | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/rules/UseEffectRulePlugin.js b/lib/rules/UseEffectRulePlugin.js index 9baf58a99..c02e089f8 100644 --- a/lib/rules/UseEffectRulePlugin.js +++ b/lib/rules/UseEffectRulePlugin.js @@ -43,25 +43,27 @@ class UseEffectRulePlugin { /** * + * @param {string} path options path * @param {string} defaultIdent default ident when none is provided * @param {object} item user provided use value * @returns {Effect|function(any): Effect[]} effect */ - const useToEffect = (defaultIdent, item) => { + const useToEffect = (path, defaultIdent, item) => { if (typeof item === "function") { - return data => useToEffectsWithoutIdent(item(data)); + return data => useToEffectsWithoutIdent(path, item(data)); } else { - return useToEffectRaw(defaultIdent, item); + return useToEffectRaw(path, defaultIdent, item); } }; /** * + * @param {string} path options path * @param {string} defaultIdent default ident when none is provided * @param {object} item user provided use value * @returns {Effect} effect */ - const useToEffectRaw = (defaultIdent, item) => { + const useToEffectRaw = (path, defaultIdent, item) => { if (typeof item === "string") { return { type, @@ -98,16 +100,17 @@ class UseEffectRulePlugin { }; /** + * @param {string} path options path * @param {any} items user provided use value * @returns {Effect[]} effects */ - const useToEffectsWithoutIdent = items => { + const useToEffectsWithoutIdent = (path, items) => { if (Array.isArray(items)) { - return items.map(item => - useToEffectRaw("[[missing ident]]", item) + return items.map((item, idx) => + useToEffectRaw(`${path}[${idx}]`, "[[missing ident]]", item) ); } - return [useToEffectRaw("[[missing ident]]", items)]; + return [useToEffectRaw(path, "[[missing ident]]", items)]; }; /** @@ -117,15 +120,18 @@ class UseEffectRulePlugin { */ const useToEffects = (path, items) => { if (Array.isArray(items)) { - return items.map((item, idx) => - useToEffect(`${path}[${idx}]`, item) - ); + return items.map((item, idx) => { + const subPath = `${path}[${idx}]`; + return useToEffect(subPath, subPath, item); + }); } - return [useToEffect(path, items)]; + return [useToEffect(path, path, items)]; }; if (typeof use === "function") { - result.effects.push(data => useToEffectsWithoutIdent(use(data))); + result.effects.push(data => + useToEffectsWithoutIdent(`${path}.use`, use(data)) + ); } else { for (const effect of useToEffects(`${path}.use`, use)) { result.effects.push(effect); From 63afbf9bf14bf0146ac9f2a9838b84d8fb6d4634 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 17 Dec 2019 17:18:52 +0100 Subject: [PATCH 19/20] add deprecation testing for config test cases --- .prettierignore | 1 + test/ConfigTestCases.test.js | 13 ++++++ .../localization/deprecations.js | 1 + .../loaders/issue-3320/deprecations.js | 10 +++++ .../mini-css-extract-plugin/deprecations.js | 14 +++++++ .../plugins/profiling-plugin/deprecations.js | 3 ++ .../rule-set/chaining/deprecations.js | 18 +++++++++ .../simple-use-array-fn/deprecations.js | 5 +++ .../simple-use-fn-array/deprecations.js | 5 +++ .../rule-set/simple/deprecations.js | 5 +++ .../deprecations.js | 3 ++ test/helpers/deprecationTracking.js | 40 +++++++++++++++++++ 12 files changed, 118 insertions(+) create mode 100644 test/configCases/custom-source-type/localization/deprecations.js create mode 100644 test/configCases/loaders/issue-3320/deprecations.js create mode 100644 test/configCases/plugins/mini-css-extract-plugin/deprecations.js create mode 100644 test/configCases/plugins/profiling-plugin/deprecations.js create mode 100644 test/configCases/rule-set/chaining/deprecations.js create mode 100644 test/configCases/rule-set/simple-use-array-fn/deprecations.js create mode 100644 test/configCases/rule-set/simple-use-fn-array/deprecations.js create mode 100644 test/configCases/rule-set/simple/deprecations.js create mode 100644 test/configCases/source-map/source-map-with-profiling-plugin/deprecations.js create mode 100644 test/helpers/deprecationTracking.js diff --git a/.prettierignore b/.prettierignore index 7ca974bc4..decfb8994 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,7 @@ test/*.* !test/*.js !test/**/webpack.config.js +!test/**/deprecations.js # Ignore example fixtures examples/*.* diff --git a/test/ConfigTestCases.test.js b/test/ConfigTestCases.test.js index cdfcc1d8d..7a1831acc 100644 --- a/test/ConfigTestCases.test.js +++ b/test/ConfigTestCases.test.js @@ -7,6 +7,7 @@ const mkdirp = require("mkdirp"); const rimraf = require("rimraf"); const checkArrayExpectation = require("./checkArrayExpectation"); const createLazyTestEnv = require("./helpers/createLazyTestEnv"); +const deprecationTracking = require("./helpers/deprecationTracking"); const FakeDocument = require("./helpers/FakeDocument"); const webpack = require(".."); @@ -107,6 +108,7 @@ describe("ConfigTestCases", () => { } if (testConfig.timeout) setDefaultTimeout(testConfig.timeout); + const deprecationTracker = deprecationTracking.start(); webpack(options, (err, stats) => { if (err) { const fakeStats = { @@ -168,6 +170,17 @@ describe("ConfigTestCases", () => { ) ) return; + const deprecations = deprecationTracker(); + if ( + checkArrayExpectation( + testDirectory, + { deprecations }, + "deprecation", + "Deprecation", + done + ) + ) + return; const globalContext = { console: console, diff --git a/test/configCases/custom-source-type/localization/deprecations.js b/test/configCases/custom-source-type/localization/deprecations.js new file mode 100644 index 000000000..44a05b2a7 --- /dev/null +++ b/test/configCases/custom-source-type/localization/deprecations.js @@ -0,0 +1 @@ +module.exports = [{ code: /DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_MANIFEST/ }]; diff --git a/test/configCases/loaders/issue-3320/deprecations.js b/test/configCases/loaders/issue-3320/deprecations.js new file mode 100644 index 000000000..aac174551 --- /dev/null +++ b/test/configCases/loaders/issue-3320/deprecations.js @@ -0,0 +1,10 @@ +module.exports = [ + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[2\]\.options\)/ + }, + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[3\]\.use\[0\]\.options\)/ + } +]; diff --git a/test/configCases/plugins/mini-css-extract-plugin/deprecations.js b/test/configCases/plugins/mini-css-extract-plugin/deprecations.js new file mode 100644 index 000000000..19f3a4df6 --- /dev/null +++ b/test/configCases/plugins/mini-css-extract-plugin/deprecations.js @@ -0,0 +1,14 @@ +module.exports = [ + { code: /DEP_WEBPACK_CHUNK_GROUP_GET_MODULE_INDEX_2/ }, + { code: /DEP_WEBPACK_CHUNK_MODULES_ITERABLE/ }, + { code: /DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_MANIFEST/ }, + { code: /DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_OUTPUT_OPTIONS/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_RENDER_CURRENT_HASH_CODE/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_RENDER_MANIFEST/ }, + { code: /DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE_FN/ }, + { code: /DEP_WEBPACK_MODULE_ID/ }, + { code: /DEP_WEBPACK_MODULE_UPDATE_HASH/ } +]; diff --git a/test/configCases/plugins/profiling-plugin/deprecations.js b/test/configCases/plugins/profiling-plugin/deprecations.js new file mode 100644 index 000000000..dee16addc --- /dev/null +++ b/test/configCases/plugins/profiling-plugin/deprecations.js @@ -0,0 +1,3 @@ +module.exports = [ + { code: /DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK/ } +]; diff --git a/test/configCases/rule-set/chaining/deprecations.js b/test/configCases/rule-set/chaining/deprecations.js new file mode 100644 index 000000000..6452ef041 --- /dev/null +++ b/test/configCases/rule-set/chaining/deprecations.js @@ -0,0 +1,18 @@ +module.exports = [ + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /rules\[0\].use\[0\]/ + }, + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /rules\[0\].use\[1\]/ + }, + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /rules\[1\].use\[0\]/ + }, + { + code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, + message: /rules\[1\].use\[1\]/ + } +]; diff --git a/test/configCases/rule-set/simple-use-array-fn/deprecations.js b/test/configCases/rule-set/simple-use-array-fn/deprecations.js new file mode 100644 index 000000000..509a3520b --- /dev/null +++ b/test/configCases/rule-set/simple-use-array-fn/deprecations.js @@ -0,0 +1,5 @@ +module.exports = [ + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[0\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[1\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[2\]/ } +]; diff --git a/test/configCases/rule-set/simple-use-fn-array/deprecations.js b/test/configCases/rule-set/simple-use-fn-array/deprecations.js new file mode 100644 index 000000000..509a3520b --- /dev/null +++ b/test/configCases/rule-set/simple-use-fn-array/deprecations.js @@ -0,0 +1,5 @@ +module.exports = [ + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[0\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[1\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[2\]/ } +]; diff --git a/test/configCases/rule-set/simple/deprecations.js b/test/configCases/rule-set/simple/deprecations.js new file mode 100644 index 000000000..509a3520b --- /dev/null +++ b/test/configCases/rule-set/simple/deprecations.js @@ -0,0 +1,5 @@ +module.exports = [ + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[0\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[1\]/ }, + { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, message: /oneOf\[2\]/ } +]; diff --git a/test/configCases/source-map/source-map-with-profiling-plugin/deprecations.js b/test/configCases/source-map/source-map-with-profiling-plugin/deprecations.js new file mode 100644 index 000000000..dee16addc --- /dev/null +++ b/test/configCases/source-map/source-map-with-profiling-plugin/deprecations.js @@ -0,0 +1,3 @@ +module.exports = [ + { code: /DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK/ } +]; diff --git a/test/helpers/deprecationTracking.js b/test/helpers/deprecationTracking.js new file mode 100644 index 000000000..02b92ab91 --- /dev/null +++ b/test/helpers/deprecationTracking.js @@ -0,0 +1,40 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const util = require("util"); + +let interception = undefined; + +const originalDeprecate = util.deprecate; +util.deprecate = (fn, message, code) => { + const original = originalDeprecate(fn, message, code); + + return function(...args) { + if (interception) { + interception.set(`${code}: ${message}`, { code, message }); + return fn.apply(this, args); + } else { + return original.apply(this, args); + } + }; +}; + +exports.start = handler => { + interception = new Map(); + + return () => { + const map = interception; + interception = undefined; + return Array.from(map) + .sort(([a], [b]) => { + if (a < b) return -1; + if (a > b) return 1; + return 0; + }) + .map(([key, data]) => data); + }; +}; From c2574cbdc2fba5ea98260a8e3c7a8e340964fcb4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 18:37:03 +0000 Subject: [PATCH 20/20] chore(deps-dev): bump @types/node from 12.12.19 to 12.12.20 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.12.19 to 12.12.20. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1cfac4293..b9cf254f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -409,9 +409,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@>=4.5.0", "@types/node@^12.6.9": - version "12.12.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.19.tgz#6133aa2a765accdec89ad7792b651a0830f7a34e" - integrity sha512-OXw80IpKyLeuZ5a8r2XCxVNnRAtS3lRDHBleSUQmbgu3C6eKqRsz7/5XNBU0EvK0RTVfotvYFgvRwwe2jeoiKw== + version "12.12.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.20.tgz#7b693038ce661fe57a7ffa4679440b5e7c5e8b99" + integrity sha512-VAe+DiwpnC/g448uN+/3gRl4th0BTdrR9gSLIOHA+SUQskaYZQDOHG7xmjiE7JUhjbXnbXytf6Ih+/pA6CtMFQ== "@types/normalize-package-data@^2.4.0": version "2.4.0"