webpack 5.59.0 → 5.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/README.md +1 -7
- package/hot/lazy-compilation-node.js +3 -1
- package/hot/poll.js +1 -1
- package/hot/signal.js +1 -1
- package/lib/APIPlugin.js +33 -0
- package/lib/BannerPlugin.js +10 -4
- package/lib/Cache.js +1 -1
- package/lib/CacheFacade.js +4 -11
- package/lib/Chunk.js +6 -3
- package/lib/ChunkGraph.js +1 -2
- package/lib/ChunkGroup.js +1 -1
- package/lib/CleanPlugin.js +81 -20
- package/lib/Compilation.js +179 -91
- package/lib/Compiler.js +86 -17
- package/lib/ConstPlugin.js +2 -2
- package/lib/ContextModule.js +142 -51
- package/lib/ContextModuleFactory.js +65 -25
- package/lib/DelegatedModule.js +1 -1
- package/lib/DelegatedModuleFactoryPlugin.js +1 -1
- package/lib/Dependency.js +17 -0
- package/lib/DependencyTemplate.js +9 -0
- package/lib/DependencyTemplates.js +1 -1
- package/lib/DllModule.js +1 -1
- package/lib/EntryOptionPlugin.js +2 -0
- package/lib/ErrorHelpers.js +2 -2
- package/lib/EvalDevToolModulePlugin.js +16 -1
- package/lib/EvalSourceMapDevToolPlugin.js +18 -1
- package/lib/ExportsInfo.js +4 -4
- package/lib/ExternalModule.js +94 -54
- package/lib/ExternalModuleFactoryPlugin.js +5 -5
- package/lib/FileSystemInfo.js +89 -44
- package/lib/Generator.js +3 -0
- package/lib/HookWebpackError.js +1 -1
- package/lib/HotModuleReplacementPlugin.js +3 -1
- package/lib/LoaderOptionsPlugin.js +1 -1
- package/lib/Module.js +27 -4
- package/lib/ModuleFilenameHelpers.js +8 -4
- package/lib/ModuleHashingError.js +29 -0
- package/lib/MultiCompiler.js +1 -1
- package/lib/MultiWatching.js +1 -1
- package/lib/NodeStuffPlugin.js +10 -0
- package/lib/NormalModule.js +41 -26
- package/lib/NormalModuleFactory.js +42 -37
- package/lib/ProgressPlugin.js +4 -5
- package/lib/RawModule.js +1 -1
- package/lib/RuntimeGlobals.js +29 -1
- package/lib/RuntimeModule.js +1 -1
- package/lib/RuntimePlugin.js +77 -1
- package/lib/RuntimeTemplate.js +114 -2
- package/lib/Template.js +2 -1
- package/lib/TemplatedPathPlugin.js +48 -23
- package/lib/WatchIgnorePlugin.js +19 -7
- package/lib/Watching.js +33 -19
- package/lib/WebpackOptionsApply.js +57 -11
- package/lib/asset/AssetGenerator.js +193 -63
- package/lib/asset/AssetModulesPlugin.js +3 -0
- package/lib/asset/RawDataUrlModule.js +148 -0
- package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -4
- package/lib/buildChunkGraph.js +36 -6
- package/lib/cache/PackFileCacheStrategy.js +7 -4
- package/lib/cache/ResolverCachePlugin.js +90 -29
- package/lib/cli.js +44 -3
- package/lib/config/browserslistTargetHandler.js +41 -6
- package/lib/config/defaults.js +115 -19
- package/lib/config/normalization.js +9 -0
- package/lib/config/target.js +10 -0
- package/lib/container/ContainerEntryModule.js +8 -5
- package/lib/container/FallbackModule.js +4 -4
- package/lib/container/RemoteModule.js +4 -2
- package/lib/css/CssExportsGenerator.js +139 -0
- package/lib/css/CssGenerator.js +109 -0
- package/lib/css/CssLoadingRuntimeModule.js +440 -0
- package/lib/css/CssModulesPlugin.js +462 -0
- package/lib/css/CssParser.js +618 -0
- package/lib/css/walkCssTokens.js +659 -0
- package/lib/debug/ProfilingPlugin.js +24 -21
- package/lib/dependencies/AMDRequireDependency.js +6 -6
- package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
- package/lib/dependencies/CommonJsFullRequireDependency.js +5 -1
- package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -3
- package/lib/dependencies/CommonJsRequireContextDependency.js +5 -1
- package/lib/dependencies/ContextDependency.js +1 -0
- package/lib/dependencies/ContextDependencyHelpers.js +3 -3
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
- package/lib/dependencies/ContextElementDependency.js +41 -3
- package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
- package/lib/dependencies/CssExportDependency.js +85 -0
- package/lib/dependencies/CssImportDependency.js +75 -0
- package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
- package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
- package/lib/dependencies/CssUrlDependency.js +132 -0
- package/lib/dependencies/ExportsInfoDependency.js +6 -0
- package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
- package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -5
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -3
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +25 -17
- package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
- package/lib/dependencies/HarmonyImportDependency.js +23 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +142 -45
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -22
- package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
- package/lib/dependencies/ImportContextDependency.js +0 -2
- package/lib/dependencies/ImportMetaContextDependency.js +35 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
- package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
- package/lib/dependencies/ImportMetaPlugin.js +22 -3
- package/lib/dependencies/LoaderPlugin.js +4 -2
- package/lib/dependencies/RequireContextDependency.js +0 -16
- package/lib/dependencies/RequireEnsureDependency.js +2 -2
- package/lib/dependencies/URLDependency.js +3 -8
- package/lib/dependencies/URLPlugin.js +1 -1
- package/lib/esm/ModuleChunkFormatPlugin.js +74 -49
- package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +25 -9
- package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
- package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
- package/lib/hmr/LazyCompilationPlugin.js +54 -26
- package/lib/hmr/lazyCompilationBackend.js +51 -12
- package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
- package/lib/ids/HashedModuleIdsPlugin.js +11 -14
- package/lib/ids/IdHelpers.js +25 -11
- package/lib/ids/NamedModuleIdsPlugin.js +6 -9
- package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
- package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
- package/lib/ids/SyncModuleIdsPlugin.js +140 -0
- package/lib/index.js +13 -0
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
- package/lib/javascript/BasicEvaluatedExpression.js +5 -2
- package/lib/javascript/ChunkHelpers.js +33 -0
- package/lib/javascript/JavascriptGenerator.js +1 -0
- package/lib/javascript/JavascriptModulesPlugin.js +27 -2
- package/lib/javascript/JavascriptParser.js +82 -48
- package/lib/javascript/StartupHelpers.js +7 -30
- package/lib/library/AssignLibraryPlugin.js +39 -15
- package/lib/library/EnableLibraryPlugin.js +11 -0
- package/lib/library/UmdLibraryPlugin.js +5 -3
- package/lib/node/NodeTargetPlugin.js +3 -0
- package/lib/node/NodeWatchFileSystem.js +85 -31
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +23 -8
- package/lib/node/RequireChunkLoadingRuntimeModule.js +24 -9
- package/lib/optimize/ConcatenatedModule.js +21 -9
- package/lib/optimize/ModuleConcatenationPlugin.js +5 -2
- package/lib/optimize/SplitChunksPlugin.js +8 -1
- package/lib/runtime/AsyncModuleRuntimeModule.js +27 -17
- package/lib/runtime/BaseUriRuntimeModule.js +31 -0
- package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
- package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
- package/lib/schemes/HttpUriPlugin.js +77 -14
- package/lib/serialization/FileMiddleware.js +44 -9
- package/lib/sharing/ConsumeSharedModule.js +8 -2
- package/lib/sharing/ConsumeSharedRuntimeModule.js +26 -5
- package/lib/sharing/ProvideSharedModule.js +4 -2
- package/lib/sharing/ShareRuntimeModule.js +1 -1
- package/lib/sharing/utils.js +1 -1
- package/lib/stats/DefaultStatsFactoryPlugin.js +113 -68
- package/lib/stats/DefaultStatsPrinterPlugin.js +89 -24
- package/lib/util/ArrayHelpers.js +30 -0
- package/lib/util/AsyncQueue.js +1 -1
- package/lib/util/compileBooleanMatcher.js +1 -1
- package/lib/util/create-schema-validation.js +9 -2
- package/lib/util/createHash.js +12 -0
- package/lib/util/deprecation.js +10 -2
- package/lib/util/deterministicGrouping.js +1 -1
- package/lib/util/extractUrlAndGlobal.js +3 -0
- package/lib/util/fs.js +11 -0
- package/lib/util/hash/BatchedHash.js +7 -4
- package/lib/util/hash/md4.js +20 -0
- package/lib/util/hash/wasm-hash.js +163 -0
- package/lib/util/hash/xxhash64.js +5 -139
- package/lib/util/identifier.js +65 -44
- package/lib/util/internalSerializables.js +15 -0
- package/lib/util/nonNumericOnlyHash.js +22 -0
- package/lib/util/semver.js +17 -10
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +9 -3
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +20 -9
- package/lib/webpack.js +10 -3
- package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +33 -22
- package/module.d.ts +215 -0
- package/package.json +23 -28
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +254 -29
- package/schemas/plugins/DllReferencePlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/ProgressPlugin.check.js +1 -1
- package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.json +2 -1
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
- package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
- package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
- package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssParserOptions.json +3 -0
- package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
- package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
- package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
- package/types.d.ts +628 -179
@@ -28,7 +28,8 @@ module.exports = function () {
|
|
28
28
|
var currentStatus = "idle";
|
29
29
|
|
30
30
|
// while downloading
|
31
|
-
var blockingPromises;
|
31
|
+
var blockingPromises = 0;
|
32
|
+
var blockingPromisesWaiting = [];
|
32
33
|
|
33
34
|
// The update info
|
34
35
|
var currentUpdateApplyHandlers;
|
@@ -218,17 +219,28 @@ module.exports = function () {
|
|
218
219
|
return Promise.all(results);
|
219
220
|
}
|
220
221
|
|
222
|
+
function unblock() {
|
223
|
+
if (--blockingPromises === 0) {
|
224
|
+
setStatus("ready").then(function () {
|
225
|
+
if (blockingPromises === 0) {
|
226
|
+
var list = blockingPromisesWaiting;
|
227
|
+
blockingPromisesWaiting = [];
|
228
|
+
for (var i = 0; i < list.length; i++) {
|
229
|
+
list[i]();
|
230
|
+
}
|
231
|
+
}
|
232
|
+
});
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
221
236
|
function trackBlockingPromise(promise) {
|
222
237
|
switch (currentStatus) {
|
223
238
|
case "ready":
|
224
239
|
setStatus("prepare");
|
225
|
-
|
226
|
-
waitForBlockingPromises(function () {
|
227
|
-
return setStatus("ready");
|
228
|
-
});
|
229
|
-
return promise;
|
240
|
+
/* fallthrough */
|
230
241
|
case "prepare":
|
231
|
-
blockingPromises
|
242
|
+
blockingPromises++;
|
243
|
+
promise.then(unblock, unblock);
|
232
244
|
return promise;
|
233
245
|
default:
|
234
246
|
return promise;
|
@@ -236,11 +248,11 @@ module.exports = function () {
|
|
236
248
|
}
|
237
249
|
|
238
250
|
function waitForBlockingPromises(fn) {
|
239
|
-
if (blockingPromises
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
251
|
+
if (blockingPromises === 0) return fn();
|
252
|
+
return new Promise(function (resolve) {
|
253
|
+
blockingPromisesWaiting.push(function () {
|
254
|
+
resolve(fn());
|
255
|
+
});
|
244
256
|
});
|
245
257
|
}
|
246
258
|
|
@@ -261,7 +273,6 @@ module.exports = function () {
|
|
261
273
|
|
262
274
|
return setStatus("prepare").then(function () {
|
263
275
|
var updatedModules = [];
|
264
|
-
blockingPromises = [];
|
265
276
|
currentUpdateApplyHandlers = [];
|
266
277
|
|
267
278
|
return Promise.all(
|
@@ -298,7 +309,11 @@ module.exports = function () {
|
|
298
309
|
function hotApply(options) {
|
299
310
|
if (currentStatus !== "ready") {
|
300
311
|
return Promise.resolve().then(function () {
|
301
|
-
throw new Error(
|
312
|
+
throw new Error(
|
313
|
+
"apply() is only allowed in ready status (state: " +
|
314
|
+
currentStatus +
|
315
|
+
")"
|
316
|
+
);
|
302
317
|
});
|
303
318
|
}
|
304
319
|
return internalApply(options);
|
@@ -443,15 +443,16 @@ module.exports = function () {
|
|
443
443
|
) {
|
444
444
|
promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
|
445
445
|
currentUpdateChunks[chunkId] = true;
|
446
|
+
} else {
|
447
|
+
currentUpdateChunks[chunkId] = false;
|
446
448
|
}
|
447
449
|
});
|
448
450
|
if ($ensureChunkHandlers$) {
|
449
451
|
$ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
|
450
452
|
if (
|
451
453
|
currentUpdateChunks &&
|
452
|
-
|
453
|
-
|
454
|
-
$installedChunks$[chunkId] !== undefined
|
454
|
+
$hasOwnProperty$(currentUpdateChunks, chunkId) &&
|
455
|
+
!currentUpdateChunks[chunkId]
|
455
456
|
) {
|
456
457
|
promises.push($loadUpdateChunk$(chunkId));
|
457
458
|
currentUpdateChunks[chunkId] = true;
|
@@ -29,10 +29,17 @@ const { registerNotSerializable } = require("../util/serialization");
|
|
29
29
|
/** @typedef {import("../RequestShortener")} RequestShortener */
|
30
30
|
/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
|
31
31
|
/** @typedef {import("../WebpackError")} WebpackError */
|
32
|
+
/** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */
|
32
33
|
/** @typedef {import("../util/Hash")} Hash */
|
33
34
|
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
34
35
|
|
35
|
-
|
36
|
+
/**
|
37
|
+
* @typedef {Object} BackendApi
|
38
|
+
* @property {function(Error=): void} dispose
|
39
|
+
* @property {function(Module): { client: string, data: string, active: boolean }} module
|
40
|
+
*/
|
41
|
+
|
42
|
+
const HMR_DEPENDENCY_TYPES = new Set([
|
36
43
|
"import.meta.webpackHot.accept",
|
37
44
|
"import.meta.webpackHot.decline",
|
38
45
|
"module.hot.accept",
|
@@ -140,7 +147,7 @@ class LazyCompilationProxyModule extends Module {
|
|
140
147
|
|
141
148
|
/**
|
142
149
|
* @param {NeedBuildContext} context context info
|
143
|
-
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
150
|
+
* @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
144
151
|
* @returns {void}
|
145
152
|
*/
|
146
153
|
needBuild(context, callback) {
|
@@ -303,15 +310,13 @@ class LazyCompilationDependencyFactory extends ModuleFactory {
|
|
303
310
|
class LazyCompilationPlugin {
|
304
311
|
/**
|
305
312
|
* @param {Object} options options
|
306
|
-
* @param {(function(Compiler,
|
307
|
-
* @param {string} options.client the client reference
|
313
|
+
* @param {(function(Compiler, function(Error?, BackendApi?): void): void) | function(Compiler): Promise<BackendApi>} options.backend the backend
|
308
314
|
* @param {boolean} options.entries true, when entries are lazy compiled
|
309
315
|
* @param {boolean} options.imports true, when import() modules are lazy compiled
|
310
316
|
* @param {RegExp | string | (function(Module): boolean)} options.test additional filter for lazy compiled entrypoint modules
|
311
317
|
*/
|
312
|
-
constructor({ backend,
|
318
|
+
constructor({ backend, entries, imports, test }) {
|
313
319
|
this.backend = backend;
|
314
|
-
this.client = client;
|
315
320
|
this.entries = entries;
|
316
321
|
this.imports = imports;
|
317
322
|
this.test = test;
|
@@ -327,7 +332,7 @@ class LazyCompilationPlugin {
|
|
327
332
|
"LazyCompilationPlugin",
|
328
333
|
(params, callback) => {
|
329
334
|
if (backend !== undefined) return callback();
|
330
|
-
const promise = this.backend(compiler,
|
335
|
+
const promise = this.backend(compiler, (err, result) => {
|
331
336
|
if (err) return callback(err);
|
332
337
|
backend = result;
|
333
338
|
callback();
|
@@ -347,32 +352,55 @@ class LazyCompilationPlugin {
|
|
347
352
|
"LazyCompilationPlugin",
|
348
353
|
(originalModule, createData, resolveData) => {
|
349
354
|
if (
|
350
|
-
resolveData.dependencies.every(
|
355
|
+
resolveData.dependencies.every(dep =>
|
356
|
+
HMR_DEPENDENCY_TYPES.has(dep.type)
|
357
|
+
)
|
358
|
+
) {
|
359
|
+
// for HMR only resolving, try to determine if the HMR accept/decline refers to
|
360
|
+
// an import() or not
|
361
|
+
const hmrDep = resolveData.dependencies[0];
|
362
|
+
const originModule =
|
363
|
+
compilation.moduleGraph.getParentModule(hmrDep);
|
364
|
+
const isReferringToDynamicImport = originModule.blocks.some(
|
365
|
+
block =>
|
366
|
+
block.dependencies.some(
|
367
|
+
dep =>
|
368
|
+
dep.type === "import()" &&
|
369
|
+
/** @type {HarmonyImportDependency} */ (dep).request ===
|
370
|
+
hmrDep.request
|
371
|
+
)
|
372
|
+
);
|
373
|
+
if (!isReferringToDynamicImport) return;
|
374
|
+
} else if (
|
375
|
+
!resolveData.dependencies.every(
|
351
376
|
dep =>
|
352
|
-
|
377
|
+
HMR_DEPENDENCY_TYPES.has(dep.type) ||
|
353
378
|
(this.imports &&
|
354
379
|
(dep.type === "import()" ||
|
355
380
|
dep.type === "import() context element")) ||
|
356
381
|
(this.entries && dep.type === "entry")
|
357
|
-
)
|
358
|
-
|
382
|
+
)
|
383
|
+
)
|
384
|
+
return;
|
385
|
+
if (
|
386
|
+
/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client|webpack-hot-middleware[/\\]client/.test(
|
359
387
|
resolveData.request
|
360
|
-
)
|
361
|
-
checkTest(this.test, originalModule)
|
362
|
-
)
|
363
|
-
|
364
|
-
|
365
|
-
|
388
|
+
) ||
|
389
|
+
!checkTest(this.test, originalModule)
|
390
|
+
)
|
391
|
+
return;
|
392
|
+
const moduleInfo = backend.module(originalModule);
|
393
|
+
if (!moduleInfo) return;
|
394
|
+
const { client, data, active } = moduleInfo;
|
366
395
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
}
|
396
|
+
return new LazyCompilationProxyModule(
|
397
|
+
compiler.context,
|
398
|
+
originalModule,
|
399
|
+
resolveData.request,
|
400
|
+
client,
|
401
|
+
data,
|
402
|
+
active
|
403
|
+
);
|
376
404
|
}
|
377
405
|
);
|
378
406
|
compilation.dependencyFactories.set(
|
@@ -5,21 +5,51 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
/** @typedef {import("http").ServerOptions} HttpServerOptions */
|
9
|
+
/** @typedef {import("https").ServerOptions} HttpsServerOptions */
|
10
|
+
/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
|
10
11
|
/** @typedef {import("../Compiler")} Compiler */
|
11
12
|
|
12
13
|
/**
|
14
|
+
* @callback BackendHandler
|
13
15
|
* @param {Compiler} compiler compiler
|
14
|
-
* @param {
|
15
|
-
* @param {function(Error?, any?): void} callback callback
|
16
|
+
* @param {function((Error | null)=, any=): void} callback callback
|
16
17
|
* @returns {void}
|
17
18
|
*/
|
18
|
-
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @param {Omit<LazyCompilationDefaultBackendOptions, "client"> & { client: NonNullable<LazyCompilationDefaultBackendOptions["client"]>}} options additional options for the backend
|
22
|
+
* @returns {BackendHandler} backend
|
23
|
+
*/
|
24
|
+
module.exports = options => (compiler, callback) => {
|
19
25
|
const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
|
20
26
|
const activeModules = new Map();
|
21
27
|
const prefix = "/lazy-compilation-using-";
|
22
28
|
|
29
|
+
const isHttps =
|
30
|
+
options.protocol === "https" ||
|
31
|
+
(typeof options.server === "object" &&
|
32
|
+
("key" in options.server || "pfx" in options.server));
|
33
|
+
|
34
|
+
const createServer =
|
35
|
+
typeof options.server === "function"
|
36
|
+
? options.server
|
37
|
+
: (() => {
|
38
|
+
const http = isHttps ? require("https") : require("http");
|
39
|
+
return http.createServer.bind(http, options.server);
|
40
|
+
})();
|
41
|
+
const listen =
|
42
|
+
typeof options.listen === "function"
|
43
|
+
? options.listen
|
44
|
+
: server => {
|
45
|
+
let listen = options.listen;
|
46
|
+
if (typeof listen === "object" && !("port" in listen))
|
47
|
+
listen = { ...listen, port: undefined };
|
48
|
+
server.listen(listen);
|
49
|
+
};
|
50
|
+
|
51
|
+
const protocol = options.protocol || (isHttps ? "https" : "http");
|
52
|
+
|
23
53
|
const requestListener = (req, res) => {
|
24
54
|
const keys = req.url.slice(prefix.length).split("@");
|
25
55
|
req.socket.on("close", () => {
|
@@ -38,7 +68,9 @@ module.exports = (compiler, client, callback) => {
|
|
38
68
|
req.socket.setNoDelay(true);
|
39
69
|
res.writeHead(200, {
|
40
70
|
"content-type": "text/event-stream",
|
41
|
-
"Access-Control-Allow-Origin": "*"
|
71
|
+
"Access-Control-Allow-Origin": "*",
|
72
|
+
"Access-Control-Allow-Methods": "*",
|
73
|
+
"Access-Control-Allow-Headers": "*"
|
42
74
|
});
|
43
75
|
res.write("\n");
|
44
76
|
let moduleActivated = false;
|
@@ -52,7 +84,10 @@ module.exports = (compiler, client, callback) => {
|
|
52
84
|
}
|
53
85
|
if (moduleActivated && compiler.watching) compiler.watching.invalidate();
|
54
86
|
};
|
55
|
-
|
87
|
+
|
88
|
+
const server = /** @type {import("net").Server} */ (createServer());
|
89
|
+
server.on("request", requestListener);
|
90
|
+
|
56
91
|
let isClosing = false;
|
57
92
|
/** @type {Set<import("net").Socket>} */
|
58
93
|
const sockets = new Set();
|
@@ -63,16 +98,19 @@ module.exports = (compiler, client, callback) => {
|
|
63
98
|
});
|
64
99
|
if (isClosing) socket.destroy();
|
65
100
|
});
|
66
|
-
server.
|
101
|
+
server.on("clientError", e => {
|
102
|
+
if (e.message !== "Server is disposing") logger.warn(e);
|
103
|
+
});
|
104
|
+
server.on("listening", err => {
|
67
105
|
if (err) return callback(err);
|
68
106
|
const addr = server.address();
|
69
107
|
if (typeof addr === "string") throw new Error("addr must not be a string");
|
70
108
|
const urlBase =
|
71
109
|
addr.address === "::" || addr.address === "0.0.0.0"
|
72
|
-
?
|
110
|
+
? `${protocol}://localhost:${addr.port}`
|
73
111
|
: addr.family === "IPv6"
|
74
|
-
?
|
75
|
-
:
|
112
|
+
? `${protocol}://[${addr.address}]:${addr.port}`
|
113
|
+
: `${protocol}://${addr.address}:${addr.port}`;
|
76
114
|
logger.log(
|
77
115
|
`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
|
78
116
|
);
|
@@ -94,11 +132,12 @@ module.exports = (compiler, client, callback) => {
|
|
94
132
|
).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
|
95
133
|
const active = activeModules.get(key) > 0;
|
96
134
|
return {
|
97
|
-
client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
|
135
|
+
client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
|
98
136
|
data: key,
|
99
137
|
active
|
100
138
|
};
|
101
139
|
}
|
102
140
|
});
|
103
141
|
});
|
142
|
+
listen(server);
|
104
143
|
};
|
@@ -9,7 +9,7 @@ const {
|
|
9
9
|
compareModulesByPreOrderIndexOrIdentifier
|
10
10
|
} = require("../util/comparators");
|
11
11
|
const {
|
12
|
-
|
12
|
+
getUsedModuleIdsAndModules,
|
13
13
|
getFullModuleName,
|
14
14
|
assignDeterministicIds
|
15
15
|
} = require("./IdHelpers");
|
@@ -18,8 +18,17 @@ const {
|
|
18
18
|
/** @typedef {import("../Module")} Module */
|
19
19
|
|
20
20
|
class DeterministicModuleIdsPlugin {
|
21
|
-
|
22
|
-
|
21
|
+
/**
|
22
|
+
* @param {Object} options options
|
23
|
+
* @param {string=} options.context context relative to which module identifiers are computed
|
24
|
+
* @param {function(Module): boolean=} options.test selector function for modules
|
25
|
+
* @param {number=} options.maxLength maximum id length in digits (used as starting point)
|
26
|
+
* @param {number=} options.salt hash salt for ids
|
27
|
+
* @param {boolean=} options.fixedLength do not increase the maxLength to find an optimal id space size
|
28
|
+
* @param {boolean=} options.failOnConflict throw an error when id conflicts occur (instead of rehashing)
|
29
|
+
*/
|
30
|
+
constructor(options = {}) {
|
31
|
+
this.options = options;
|
23
32
|
}
|
24
33
|
|
25
34
|
/**
|
@@ -31,40 +40,51 @@ class DeterministicModuleIdsPlugin {
|
|
31
40
|
compiler.hooks.compilation.tap(
|
32
41
|
"DeterministicModuleIdsPlugin",
|
33
42
|
compilation => {
|
34
|
-
compilation.hooks.moduleIds.tap(
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
43
|
+
compilation.hooks.moduleIds.tap("DeterministicModuleIdsPlugin", () => {
|
44
|
+
const chunkGraph = compilation.chunkGraph;
|
45
|
+
const context = this.options.context
|
46
|
+
? this.options.context
|
47
|
+
: compiler.context;
|
48
|
+
const maxLength = this.options.maxLength || 3;
|
49
|
+
const failOnConflict = this.options.failOnConflict || false;
|
50
|
+
const fixedLength = this.options.fixedLength || false;
|
51
|
+
const salt = this.options.salt || 0;
|
52
|
+
let conflicts = 0;
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
compareModulesByPreOrderIndexOrIdentifier(
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return
|
61
|
-
}
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
const [usedIds, modules] = getUsedModuleIdsAndModules(
|
55
|
+
compilation,
|
56
|
+
this.options.test
|
57
|
+
);
|
58
|
+
assignDeterministicIds(
|
59
|
+
modules,
|
60
|
+
module => getFullModuleName(module, context, compiler.root),
|
61
|
+
failOnConflict
|
62
|
+
? () => 0
|
63
|
+
: compareModulesByPreOrderIndexOrIdentifier(
|
64
|
+
compilation.moduleGraph
|
65
|
+
),
|
66
|
+
(module, id) => {
|
67
|
+
const size = usedIds.size;
|
68
|
+
usedIds.add(`${id}`);
|
69
|
+
if (size === usedIds.size) {
|
70
|
+
conflicts++;
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
chunkGraph.setModuleId(module, id);
|
74
|
+
return true;
|
75
|
+
},
|
76
|
+
[Math.pow(10, maxLength)],
|
77
|
+
fixedLength ? 0 : 10,
|
78
|
+
usedIds.size,
|
79
|
+
salt
|
80
|
+
);
|
81
|
+
if (failOnConflict && conflicts)
|
82
|
+
throw new Error(
|
83
|
+
`Assigning deterministic module ids has lead to ${conflicts} conflict${
|
84
|
+
conflicts > 1 ? "s" : ""
|
85
|
+
}.\nIncrease the 'maxLength' to increase the id space and make conflicts less likely (recommended when there are many conflicts or application is expected to grow), or add an 'salt' number to try another hash starting value in the same id space (recommended when there is only a single conflict).`
|
65
86
|
);
|
66
|
-
|
67
|
-
);
|
87
|
+
});
|
68
88
|
}
|
69
89
|
);
|
70
90
|
}
|
@@ -10,7 +10,10 @@ const {
|
|
10
10
|
} = require("../util/comparators");
|
11
11
|
const createSchemaValidation = require("../util/create-schema-validation");
|
12
12
|
const createHash = require("../util/createHash");
|
13
|
-
const {
|
13
|
+
const {
|
14
|
+
getUsedModuleIdsAndModules,
|
15
|
+
getFullModuleName
|
16
|
+
} = require("./IdHelpers");
|
14
17
|
|
15
18
|
/** @typedef {import("../../declarations/plugins/HashedModuleIdsPlugin").HashedModuleIdsPluginOptions} HashedModuleIdsPluginOptions */
|
16
19
|
|
@@ -43,22 +46,16 @@ class HashedModuleIdsPlugin {
|
|
43
46
|
apply(compiler) {
|
44
47
|
const options = this.options;
|
45
48
|
compiler.hooks.compilation.tap("HashedModuleIdsPlugin", compilation => {
|
46
|
-
compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin",
|
49
|
+
compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin", () => {
|
47
50
|
const chunkGraph = compilation.chunkGraph;
|
48
51
|
const context = this.options.context
|
49
52
|
? this.options.context
|
50
53
|
: compiler.context;
|
51
54
|
|
52
|
-
const usedIds =
|
53
|
-
const modulesInNaturalOrder =
|
54
|
-
.
|
55
|
-
|
56
|
-
if (chunkGraph.getNumberOfModuleChunks(m) === 0) return false;
|
57
|
-
return chunkGraph.getModuleId(module) === null;
|
58
|
-
})
|
59
|
-
.sort(
|
60
|
-
compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
|
61
|
-
);
|
55
|
+
const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
|
56
|
+
const modulesInNaturalOrder = modules.sort(
|
57
|
+
compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph)
|
58
|
+
);
|
62
59
|
for (const module of modulesInNaturalOrder) {
|
63
60
|
const ident = getFullModuleName(module, context, compiler.root);
|
64
61
|
const hash = createHash(options.hashFunction);
|
@@ -67,8 +64,8 @@ class HashedModuleIdsPlugin {
|
|
67
64
|
hash.digest(options.hashDigest)
|
68
65
|
);
|
69
66
|
let len = options.hashDigestLength;
|
70
|
-
while (usedIds.has(hashId.
|
71
|
-
const moduleId = hashId.
|
67
|
+
while (usedIds.has(hashId.slice(0, len))) len++;
|
68
|
+
const moduleId = hashId.slice(0, len);
|
72
69
|
chunkGraph.setModuleId(module, moduleId);
|
73
70
|
usedIds.add(moduleId);
|
74
71
|
}
|
package/lib/ids/IdHelpers.js
CHANGED
@@ -25,7 +25,7 @@ const getHash = (str, len, hashFunction) => {
|
|
25
25
|
const hash = createHash(hashFunction);
|
26
26
|
hash.update(str);
|
27
27
|
const digest = /** @type {string} */ (hash.digest("hex"));
|
28
|
-
return digest.
|
28
|
+
return digest.slice(0, len);
|
29
29
|
};
|
30
30
|
|
31
31
|
/**
|
@@ -234,11 +234,14 @@ const addToMapOfItems = (map, key, value) => {
|
|
234
234
|
|
235
235
|
/**
|
236
236
|
* @param {Compilation} compilation the compilation
|
237
|
-
* @
|
237
|
+
* @param {function(Module): boolean=} filter filter modules
|
238
|
+
* @returns {[Set<string>, Module[]]} used module ids as strings and modules without id matching the filter
|
238
239
|
*/
|
239
|
-
const
|
240
|
+
const getUsedModuleIdsAndModules = (compilation, filter) => {
|
240
241
|
const chunkGraph = compilation.chunkGraph;
|
241
242
|
|
243
|
+
const modules = [];
|
244
|
+
|
242
245
|
/** @type {Set<string>} */
|
243
246
|
const usedIds = new Set();
|
244
247
|
if (compilation.usedModuleIds) {
|
@@ -248,15 +251,23 @@ const getUsedModuleIds = compilation => {
|
|
248
251
|
}
|
249
252
|
|
250
253
|
for (const module of compilation.modules) {
|
254
|
+
if (!module.needId) continue;
|
251
255
|
const moduleId = chunkGraph.getModuleId(module);
|
252
256
|
if (moduleId !== null) {
|
253
257
|
usedIds.add(moduleId + "");
|
258
|
+
} else {
|
259
|
+
if (
|
260
|
+
(!filter || filter(module)) &&
|
261
|
+
chunkGraph.getNumberOfModuleChunks(module) !== 0
|
262
|
+
) {
|
263
|
+
modules.push(module);
|
264
|
+
}
|
254
265
|
}
|
255
266
|
}
|
256
267
|
|
257
|
-
return usedIds;
|
268
|
+
return [usedIds, modules];
|
258
269
|
};
|
259
|
-
exports.
|
270
|
+
exports.getUsedModuleIdsAndModules = getUsedModuleIdsAndModules;
|
260
271
|
|
261
272
|
/**
|
262
273
|
* @param {Compilation} compilation the compilation
|
@@ -359,6 +370,7 @@ exports.assignNames = assignNames;
|
|
359
370
|
* @param {number[]} ranges usable ranges for ids
|
360
371
|
* @param {number} expandFactor factor to create more ranges
|
361
372
|
* @param {number} extraSpace extra space to allocate, i. e. when some ids are already used
|
373
|
+
* @param {number} salt salting number to initialize hashing
|
362
374
|
* @returns {void}
|
363
375
|
*/
|
364
376
|
const assignDeterministicIds = (
|
@@ -368,7 +380,8 @@ const assignDeterministicIds = (
|
|
368
380
|
assignId,
|
369
381
|
ranges = [10],
|
370
382
|
expandFactor = 10,
|
371
|
-
extraSpace = 0
|
383
|
+
extraSpace = 0,
|
384
|
+
salt = 0
|
372
385
|
) => {
|
373
386
|
items.sort(comparator);
|
374
387
|
|
@@ -384,15 +397,17 @@ const assignDeterministicIds = (
|
|
384
397
|
i++;
|
385
398
|
if (i < ranges.length) {
|
386
399
|
range = Math.min(ranges[i], Number.MAX_SAFE_INTEGER);
|
387
|
-
} else {
|
400
|
+
} else if (expandFactor) {
|
388
401
|
range = Math.min(range * expandFactor, Number.MAX_SAFE_INTEGER);
|
402
|
+
} else {
|
403
|
+
break;
|
389
404
|
}
|
390
405
|
}
|
391
406
|
|
392
407
|
for (const item of items) {
|
393
408
|
const ident = getName(item);
|
394
409
|
let id;
|
395
|
-
let i =
|
410
|
+
let i = salt;
|
396
411
|
do {
|
397
412
|
id = numberHash(ident + i++, range);
|
398
413
|
} while (!assignId(item, id));
|
@@ -401,15 +416,14 @@ const assignDeterministicIds = (
|
|
401
416
|
exports.assignDeterministicIds = assignDeterministicIds;
|
402
417
|
|
403
418
|
/**
|
419
|
+
* @param {Set<string>} usedIds used ids
|
404
420
|
* @param {Iterable<Module>} modules the modules
|
405
421
|
* @param {Compilation} compilation the compilation
|
406
422
|
* @returns {void}
|
407
423
|
*/
|
408
|
-
const assignAscendingModuleIds = (modules, compilation) => {
|
424
|
+
const assignAscendingModuleIds = (usedIds, modules, compilation) => {
|
409
425
|
const chunkGraph = compilation.chunkGraph;
|
410
426
|
|
411
|
-
const usedIds = getUsedModuleIds(compilation);
|
412
|
-
|
413
427
|
let nextId = 0;
|
414
428
|
let assignId;
|
415
429
|
if (usedIds.size > 0) {
|
@@ -10,7 +10,7 @@ const {
|
|
10
10
|
getShortModuleName,
|
11
11
|
getLongModuleName,
|
12
12
|
assignNames,
|
13
|
-
|
13
|
+
getUsedModuleIdsAndModules,
|
14
14
|
assignAscendingModuleIds
|
15
15
|
} = require("./IdHelpers");
|
16
16
|
|
@@ -31,27 +31,24 @@ class NamedModuleIdsPlugin {
|
|
31
31
|
const { root } = compiler;
|
32
32
|
compiler.hooks.compilation.tap("NamedModuleIdsPlugin", compilation => {
|
33
33
|
const { hashFunction } = compilation.outputOptions;
|
34
|
-
compilation.hooks.moduleIds.tap("NamedModuleIdsPlugin",
|
34
|
+
compilation.hooks.moduleIds.tap("NamedModuleIdsPlugin", () => {
|
35
35
|
const chunkGraph = compilation.chunkGraph;
|
36
36
|
const context = this.options.context
|
37
37
|
? this.options.context
|
38
38
|
: compiler.context;
|
39
39
|
|
40
|
+
const [usedIds, modules] = getUsedModuleIdsAndModules(compilation);
|
40
41
|
const unnamedModules = assignNames(
|
41
|
-
|
42
|
-
if (!module.needId) return false;
|
43
|
-
if (chunkGraph.getNumberOfModuleChunks(module) === 0) return false;
|
44
|
-
return chunkGraph.getModuleId(module) === null;
|
45
|
-
}),
|
42
|
+
modules,
|
46
43
|
m => getShortModuleName(m, context, root),
|
47
44
|
(m, shortName) =>
|
48
45
|
getLongModuleName(shortName, m, context, hashFunction, root),
|
49
46
|
compareModulesByIdentifier,
|
50
|
-
|
47
|
+
usedIds,
|
51
48
|
(m, name) => chunkGraph.setModuleId(m, name)
|
52
49
|
);
|
53
50
|
if (unnamedModules.length > 0) {
|
54
|
-
assignAscendingModuleIds(unnamedModules, compilation);
|
51
|
+
assignAscendingModuleIds(usedIds, unnamedModules, compilation);
|
55
52
|
}
|
56
53
|
});
|
57
54
|
});
|