webpack 5.68.0 → 5.70.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/lib/BannerPlugin.js +10 -4
- package/lib/ChunkGraph.js +1 -2
- package/lib/CleanPlugin.js +64 -18
- package/lib/Compilation.js +43 -17
- package/lib/ContextModule.js +90 -26
- package/lib/ContextModuleFactory.js +65 -21
- package/lib/EntryOptionPlugin.js +1 -0
- package/lib/ExportsInfo.js +4 -4
- package/lib/Generator.js +1 -0
- package/lib/ModuleHashingError.js +29 -0
- package/lib/NodeStuffPlugin.js +10 -0
- package/lib/NormalModule.js +21 -16
- package/lib/NormalModuleFactory.js +40 -35
- package/lib/ProgressPlugin.js +4 -5
- package/lib/RuntimeTemplate.js +1 -0
- package/lib/TemplatedPathPlugin.js +48 -23
- package/lib/WebpackOptionsApply.js +2 -0
- package/lib/asset/AssetGenerator.js +122 -33
- package/lib/buildChunkGraph.js +1 -1
- package/lib/cache/ResolverCachePlugin.js +89 -28
- package/lib/config/browserslistTargetHandler.js +3 -5
- package/lib/config/defaults.js +7 -2
- package/lib/config/normalization.js +1 -0
- package/lib/css/CssLoadingRuntimeModule.js +63 -70
- package/lib/css/CssModulesPlugin.js +2 -1
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/ContextDependencyHelpers.js +1 -1
- package/lib/dependencies/ContextElementDependency.js +8 -2
- package/lib/dependencies/ExportsInfoDependency.js +6 -0
- package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
- package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
- 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/LoaderPlugin.js +2 -0
- package/lib/dependencies/RequireContextDependency.js +0 -16
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
- package/lib/index.js +5 -0
- package/lib/javascript/JavascriptModulesPlugin.js +27 -2
- package/lib/javascript/StartupHelpers.js +3 -2
- package/lib/library/AssignLibraryPlugin.js +8 -2
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
- package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
- package/lib/optimize/ConcatenatedModule.js +10 -4
- package/lib/schemes/HttpUriPlugin.js +68 -6
- package/lib/serialization/FileMiddleware.js +44 -9
- package/lib/util/compileBooleanMatcher.js +1 -1
- package/lib/util/deterministicGrouping.js +1 -1
- package/lib/util/identifier.js +65 -44
- package/lib/util/internalSerializables.js +2 -0
- package/lib/util/nonNumericOnlyHash.js +22 -0
- package/lib/util/semver.js +17 -10
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +15 -5
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
- package/module.d.ts +15 -0
- package/package.json +13 -13
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +17 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
- package/types.d.ts +203 -91
package/lib/BannerPlugin.js
CHANGED
@@ -77,6 +77,7 @@ class BannerPlugin {
|
|
77
77
|
undefined,
|
78
78
|
options
|
79
79
|
);
|
80
|
+
const cache = new WeakMap();
|
80
81
|
|
81
82
|
compiler.hooks.compilation.tap("BannerPlugin", compilation => {
|
82
83
|
compilation.hooks.processAssets.tap(
|
@@ -102,10 +103,15 @@ class BannerPlugin {
|
|
102
103
|
|
103
104
|
const comment = compilation.getPath(banner, data);
|
104
105
|
|
105
|
-
compilation.updateAsset(
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
compilation.updateAsset(file, old => {
|
107
|
+
let cached = cache.get(old);
|
108
|
+
if (!cached || cached.comment !== comment) {
|
109
|
+
const source = new ConcatSource(comment, "\n", old);
|
110
|
+
cache.set(old, { source, comment });
|
111
|
+
return source;
|
112
|
+
}
|
113
|
+
return cached.source;
|
114
|
+
});
|
109
115
|
}
|
110
116
|
}
|
111
117
|
}
|
package/lib/ChunkGraph.js
CHANGED
@@ -46,6 +46,7 @@ const compareModuleIterables = compareIterables(compareModulesByIdentifier);
|
|
46
46
|
|
47
47
|
/** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */
|
48
48
|
/** @typedef {(m: Module) => boolean} ModuleFilterPredicate */
|
49
|
+
/** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
|
49
50
|
|
50
51
|
/**
|
51
52
|
* @typedef {Object} ChunkSizeOptions
|
@@ -1180,8 +1181,6 @@ class ChunkGraph {
|
|
1180
1181
|
return cgc.dependentHashModules;
|
1181
1182
|
}
|
1182
1183
|
|
1183
|
-
/** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
|
1184
|
-
|
1185
1184
|
/**
|
1186
1185
|
* @param {Chunk} chunk the chunk
|
1187
1186
|
* @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
|
package/lib/CleanPlugin.js
CHANGED
@@ -19,6 +19,7 @@ const processAsyncTree = require("./util/processAsyncTree");
|
|
19
19
|
/** @typedef {import("./util/fs").StatsCallback} StatsCallback */
|
20
20
|
|
21
21
|
/** @typedef {(function(string):boolean)|RegExp} IgnoreItem */
|
22
|
+
/** @typedef {Map<string, number>} Assets */
|
22
23
|
/** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */
|
23
24
|
|
24
25
|
/**
|
@@ -40,18 +41,32 @@ const validate = createSchemaValidation(
|
|
40
41
|
baseDataPath: "options"
|
41
42
|
}
|
42
43
|
);
|
44
|
+
const _10sec = 10 * 1000;
|
45
|
+
|
46
|
+
/**
|
47
|
+
* marge assets map 2 into map 1
|
48
|
+
* @param {Assets} as1 assets
|
49
|
+
* @param {Assets} as2 assets
|
50
|
+
* @returns {void}
|
51
|
+
*/
|
52
|
+
const mergeAssets = (as1, as2) => {
|
53
|
+
for (const [key, value1] of as2) {
|
54
|
+
const value2 = as1.get(key);
|
55
|
+
if (!value2 || value1 > value2) as1.set(key, value1);
|
56
|
+
}
|
57
|
+
};
|
43
58
|
|
44
59
|
/**
|
45
60
|
* @param {OutputFileSystem} fs filesystem
|
46
61
|
* @param {string} outputPath output path
|
47
|
-
* @param {
|
62
|
+
* @param {Map<string, number>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
|
48
63
|
* @param {function((Error | null)=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
|
49
64
|
* @returns {void}
|
50
65
|
*/
|
51
66
|
const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
|
52
67
|
const directories = new Set();
|
53
68
|
// get directories of assets
|
54
|
-
for (const asset of currentAssets) {
|
69
|
+
for (const [asset] of currentAssets) {
|
55
70
|
directories.add(asset.replace(/(^|\/)[^/]*$/, ""));
|
56
71
|
}
|
57
72
|
// and all parent directories
|
@@ -91,13 +106,15 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
|
|
91
106
|
};
|
92
107
|
|
93
108
|
/**
|
94
|
-
* @param {
|
95
|
-
* @param {
|
109
|
+
* @param {Assets} currentAssets assets list
|
110
|
+
* @param {Assets} oldAssets old assets list
|
96
111
|
* @returns {Set<string>} diff
|
97
112
|
*/
|
98
113
|
const getDiffToOldAssets = (currentAssets, oldAssets) => {
|
99
114
|
const diff = new Set();
|
100
|
-
|
115
|
+
const now = Date.now();
|
116
|
+
for (const [asset, ts] of oldAssets) {
|
117
|
+
if (ts >= now) continue;
|
101
118
|
if (!currentAssets.has(asset)) diff.add(asset);
|
102
119
|
}
|
103
120
|
return diff;
|
@@ -124,7 +141,7 @@ const doStat = (fs, filename, callback) => {
|
|
124
141
|
* @param {Logger} logger logger
|
125
142
|
* @param {Set<string>} diff filenames of the assets that shouldn't be there
|
126
143
|
* @param {function(string): boolean} isKept check if the entry is ignored
|
127
|
-
* @param {function(Error=): void} callback callback
|
144
|
+
* @param {function(Error=, Assets=): void} callback callback
|
128
145
|
* @returns {void}
|
129
146
|
*/
|
130
147
|
const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
|
@@ -137,11 +154,13 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
|
|
137
154
|
};
|
138
155
|
/** @typedef {{ type: "check" | "unlink" | "rmdir", filename: string, parent: { remaining: number, job: Job } | undefined }} Job */
|
139
156
|
/** @type {Job[]} */
|
140
|
-
const jobs = Array.from(diff, filename => ({
|
157
|
+
const jobs = Array.from(diff.keys(), filename => ({
|
141
158
|
type: "check",
|
142
159
|
filename,
|
143
160
|
parent: undefined
|
144
161
|
}));
|
162
|
+
/** @type {Assets} */
|
163
|
+
const keptAssets = new Map();
|
145
164
|
processAsyncTree(
|
146
165
|
jobs,
|
147
166
|
10,
|
@@ -161,6 +180,7 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
|
|
161
180
|
switch (type) {
|
162
181
|
case "check":
|
163
182
|
if (isKept(filename)) {
|
183
|
+
keptAssets.set(filename, 0);
|
164
184
|
// do not decrement parent entry as we don't want to delete the parent
|
165
185
|
log(`${filename} will be kept`);
|
166
186
|
return process.nextTick(callback);
|
@@ -247,7 +267,10 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
|
|
247
267
|
break;
|
248
268
|
}
|
249
269
|
},
|
250
|
-
|
270
|
+
err => {
|
271
|
+
if (err) return callback(err);
|
272
|
+
callback(undefined, keptAssets);
|
273
|
+
}
|
251
274
|
);
|
252
275
|
};
|
253
276
|
|
@@ -302,6 +325,7 @@ class CleanPlugin {
|
|
302
325
|
// We assume that no external modification happens while the compiler is active
|
303
326
|
// So we can store the old assets and only diff to them to avoid fs access on
|
304
327
|
// incremental builds
|
328
|
+
/** @type {undefined|Assets} */
|
305
329
|
let oldAssets;
|
306
330
|
|
307
331
|
compiler.hooks.emit.tapAsync(
|
@@ -322,7 +346,9 @@ class CleanPlugin {
|
|
322
346
|
);
|
323
347
|
}
|
324
348
|
|
325
|
-
|
349
|
+
/** @type {Assets} */
|
350
|
+
const currentAssets = new Map();
|
351
|
+
const now = Date.now();
|
326
352
|
for (const asset of Object.keys(compilation.assets)) {
|
327
353
|
if (/^[A-Za-z]:\\|^\/|^\\\\/.test(asset)) continue;
|
328
354
|
let normalizedAsset;
|
@@ -335,7 +361,12 @@ class CleanPlugin {
|
|
335
361
|
);
|
336
362
|
} while (newNormalizedAsset !== normalizedAsset);
|
337
363
|
if (normalizedAsset.startsWith("../")) continue;
|
338
|
-
|
364
|
+
const assetInfo = compilation.assetsInfo.get(asset);
|
365
|
+
if (assetInfo && assetInfo.hotModuleReplacement) {
|
366
|
+
currentAssets.set(normalizedAsset, now + _10sec);
|
367
|
+
} else {
|
368
|
+
currentAssets.set(normalizedAsset, 0);
|
369
|
+
}
|
339
370
|
}
|
340
371
|
|
341
372
|
const outputPath = compilation.getPath(compiler.outputPath, {});
|
@@ -346,19 +377,34 @@ class CleanPlugin {
|
|
346
377
|
return keepFn(path);
|
347
378
|
};
|
348
379
|
|
380
|
+
/**
|
381
|
+
* @param {Error=} err err
|
382
|
+
* @param {Set<string>=} diff diff
|
383
|
+
*/
|
349
384
|
const diffCallback = (err, diff) => {
|
350
385
|
if (err) {
|
351
386
|
oldAssets = undefined;
|
352
|
-
|
387
|
+
callback(err);
|
388
|
+
return;
|
353
389
|
}
|
354
|
-
applyDiff(
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
390
|
+
applyDiff(
|
391
|
+
fs,
|
392
|
+
outputPath,
|
393
|
+
dry,
|
394
|
+
logger,
|
395
|
+
diff,
|
396
|
+
isKept,
|
397
|
+
(err, keptAssets) => {
|
398
|
+
if (err) {
|
399
|
+
oldAssets = undefined;
|
400
|
+
} else {
|
401
|
+
if (oldAssets) mergeAssets(currentAssets, oldAssets);
|
402
|
+
oldAssets = currentAssets;
|
403
|
+
if (keptAssets) mergeAssets(oldAssets, keptAssets);
|
404
|
+
}
|
405
|
+
callback(err);
|
359
406
|
}
|
360
|
-
|
361
|
-
});
|
407
|
+
);
|
362
408
|
};
|
363
409
|
|
364
410
|
if (oldAssets) {
|
package/lib/Compilation.js
CHANGED
@@ -43,6 +43,7 @@ const Module = require("./Module");
|
|
43
43
|
const ModuleDependencyError = require("./ModuleDependencyError");
|
44
44
|
const ModuleDependencyWarning = require("./ModuleDependencyWarning");
|
45
45
|
const ModuleGraph = require("./ModuleGraph");
|
46
|
+
const ModuleHashingError = require("./ModuleHashingError");
|
46
47
|
const ModuleNotFoundError = require("./ModuleNotFoundError");
|
47
48
|
const ModuleProfile = require("./ModuleProfile");
|
48
49
|
const ModuleRestoreError = require("./ModuleRestoreError");
|
@@ -182,6 +183,7 @@ const { isSourceEqual } = require("./util/source");
|
|
182
183
|
|
183
184
|
/**
|
184
185
|
* @typedef {Object} ChunkHashContext
|
186
|
+
* @property {CodeGenerationResults} codeGenerationResults results of code generation
|
185
187
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
186
188
|
* @property {ModuleGraph} moduleGraph the module graph
|
187
189
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
@@ -3882,6 +3884,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3882
3884
|
let statModulesFromCache = 0;
|
3883
3885
|
const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this;
|
3884
3886
|
const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
|
3887
|
+
const errors = [];
|
3885
3888
|
for (const module of this.modules) {
|
3886
3889
|
const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
|
3887
3890
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
@@ -3906,13 +3909,20 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3906
3909
|
hashFunction,
|
3907
3910
|
runtimeTemplate,
|
3908
3911
|
hashDigest,
|
3909
|
-
hashDigestLength
|
3912
|
+
hashDigestLength,
|
3913
|
+
errors
|
3910
3914
|
);
|
3911
3915
|
if (memCache) {
|
3912
3916
|
memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest);
|
3913
3917
|
}
|
3914
3918
|
}
|
3915
3919
|
}
|
3920
|
+
if (errors.length > 0) {
|
3921
|
+
errors.sort(compareSelect(err => err.module, compareModulesByIdentifier));
|
3922
|
+
for (const error of errors) {
|
3923
|
+
this.errors.push(error);
|
3924
|
+
}
|
3925
|
+
}
|
3916
3926
|
this.logger.log(
|
3917
3927
|
`${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${
|
3918
3928
|
Math.round(
|
@@ -3929,17 +3939,22 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3929
3939
|
hashFunction,
|
3930
3940
|
runtimeTemplate,
|
3931
3941
|
hashDigest,
|
3932
|
-
hashDigestLength
|
3942
|
+
hashDigestLength,
|
3943
|
+
errors
|
3933
3944
|
) {
|
3934
|
-
|
3935
|
-
|
3936
|
-
|
3937
|
-
|
3938
|
-
|
3939
|
-
|
3940
|
-
|
3941
|
-
|
3942
|
-
|
3945
|
+
let moduleHashDigest;
|
3946
|
+
try {
|
3947
|
+
const moduleHash = createHash(hashFunction);
|
3948
|
+
module.updateHash(moduleHash, {
|
3949
|
+
chunkGraph,
|
3950
|
+
runtime,
|
3951
|
+
runtimeTemplate
|
3952
|
+
});
|
3953
|
+
moduleHashDigest = /** @type {string} */ (moduleHash.digest(hashDigest));
|
3954
|
+
} catch (err) {
|
3955
|
+
errors.push(new ModuleHashingError(module, err));
|
3956
|
+
moduleHashDigest = "XXXXXX";
|
3957
|
+
}
|
3943
3958
|
chunkGraph.setModuleHashes(
|
3944
3959
|
module,
|
3945
3960
|
runtime,
|
@@ -4090,6 +4105,7 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4090
4105
|
const codeGenerationJobs = [];
|
4091
4106
|
/** @type {Map<string, Map<Module, {module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}>>} */
|
4092
4107
|
const codeGenerationJobsMap = new Map();
|
4108
|
+
const errors = [];
|
4093
4109
|
|
4094
4110
|
const processChunk = chunk => {
|
4095
4111
|
// Last minute module hash generation for modules that depend on chunk hashes
|
@@ -4104,7 +4120,8 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4104
4120
|
hashFunction,
|
4105
4121
|
runtimeTemplate,
|
4106
4122
|
hashDigest,
|
4107
|
-
hashDigestLength
|
4123
|
+
hashDigestLength,
|
4124
|
+
errors
|
4108
4125
|
);
|
4109
4126
|
let hashMap = codeGenerationJobsMap.get(hash);
|
4110
4127
|
if (hashMap) {
|
@@ -4128,15 +4145,16 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4128
4145
|
}
|
4129
4146
|
}
|
4130
4147
|
this.logger.timeAggregate("hashing: hash runtime modules");
|
4131
|
-
this.logger.time("hashing: hash chunks");
|
4132
|
-
const chunkHash = createHash(hashFunction);
|
4133
4148
|
try {
|
4149
|
+
this.logger.time("hashing: hash chunks");
|
4150
|
+
const chunkHash = createHash(hashFunction);
|
4134
4151
|
if (outputOptions.hashSalt) {
|
4135
4152
|
chunkHash.update(outputOptions.hashSalt);
|
4136
4153
|
}
|
4137
4154
|
chunk.updateHash(chunkHash, chunkGraph);
|
4138
4155
|
this.hooks.chunkHash.call(chunk, chunkHash, {
|
4139
4156
|
chunkGraph,
|
4157
|
+
codeGenerationResults: this.codeGenerationResults,
|
4140
4158
|
moduleGraph: this.moduleGraph,
|
4141
4159
|
runtimeTemplate: this.runtimeTemplate
|
4142
4160
|
});
|
@@ -4160,6 +4178,12 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4160
4178
|
};
|
4161
4179
|
otherChunks.forEach(processChunk);
|
4162
4180
|
for (const chunk of runtimeChunks) processChunk(chunk);
|
4181
|
+
if (errors.length > 0) {
|
4182
|
+
errors.sort(compareSelect(err => err.module, compareModulesByIdentifier));
|
4183
|
+
for (const error of errors) {
|
4184
|
+
this.errors.push(error);
|
4185
|
+
}
|
4186
|
+
}
|
4163
4187
|
|
4164
4188
|
this.logger.timeAggregateEnd("hashing: hash runtime modules");
|
4165
4189
|
this.logger.timeAggregateEnd("hashing: hash chunks");
|
@@ -4799,6 +4823,9 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4799
4823
|
chunkGraph.connectChunkAndModule(chunk, module);
|
4800
4824
|
}
|
4801
4825
|
|
4826
|
+
/** @type {WebpackError[]} */
|
4827
|
+
const errors = [];
|
4828
|
+
|
4802
4829
|
// Hash modules
|
4803
4830
|
for (const module of modules) {
|
4804
4831
|
this._createModuleHash(
|
@@ -4808,15 +4835,14 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4808
4835
|
hashFunction,
|
4809
4836
|
runtimeTemplate,
|
4810
4837
|
hashDigest,
|
4811
|
-
hashDigestLength
|
4838
|
+
hashDigestLength,
|
4839
|
+
errors
|
4812
4840
|
);
|
4813
4841
|
}
|
4814
4842
|
|
4815
4843
|
const codeGenerationResults = new CodeGenerationResults(
|
4816
4844
|
this.outputOptions.hashFunction
|
4817
4845
|
);
|
4818
|
-
/** @type {WebpackError[]} */
|
4819
|
-
const errors = [];
|
4820
4846
|
/**
|
4821
4847
|
* @param {Module} module the module
|
4822
4848
|
* @param {Callback} callback callback
|
package/lib/ContextModule.js
CHANGED
@@ -61,7 +61,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|
61
61
|
|
62
62
|
/**
|
63
63
|
* @typedef {Object} ContextModuleOptionsExtras
|
64
|
-
* @property {string} resource
|
64
|
+
* @property {false|string|string[]} resource
|
65
65
|
* @property {string=} resourceQuery
|
66
66
|
* @property {string=} resourceFragment
|
67
67
|
* @property {TODO} resolveOptions
|
@@ -92,23 +92,36 @@ class ContextModule extends Module {
|
|
92
92
|
* @param {ContextModuleOptions} options options object
|
93
93
|
*/
|
94
94
|
constructor(resolveDependencies, options) {
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
95
|
+
if (!options || typeof options.resource === "string") {
|
96
|
+
const parsed = parseResource(
|
97
|
+
options ? /** @type {string} */ (options.resource) : ""
|
98
|
+
);
|
99
|
+
const resource = parsed.path;
|
100
|
+
const resourceQuery = (options && options.resourceQuery) || parsed.query;
|
101
|
+
const resourceFragment =
|
102
|
+
(options && options.resourceFragment) || parsed.fragment;
|
103
|
+
|
104
|
+
super("javascript/dynamic", resource);
|
105
|
+
/** @type {ContextModuleOptions} */
|
106
|
+
this.options = {
|
107
|
+
...options,
|
108
|
+
resource,
|
109
|
+
resourceQuery,
|
110
|
+
resourceFragment
|
111
|
+
};
|
112
|
+
} else {
|
113
|
+
super("javascript/dynamic");
|
114
|
+
/** @type {ContextModuleOptions} */
|
115
|
+
this.options = {
|
116
|
+
...options,
|
117
|
+
resource: options.resource,
|
118
|
+
resourceQuery: options.resourceQuery || "",
|
119
|
+
resourceFragment: options.resourceFragment || ""
|
120
|
+
};
|
121
|
+
}
|
102
122
|
|
103
123
|
// Info from Factory
|
104
124
|
this.resolveDependencies = resolveDependencies;
|
105
|
-
/** @type {ContextModuleOptions} */
|
106
|
-
this.options = {
|
107
|
-
...options,
|
108
|
-
resource,
|
109
|
-
resourceQuery,
|
110
|
-
resourceFragment
|
111
|
-
};
|
112
125
|
if (options && options.resolveOptions !== undefined) {
|
113
126
|
this.resolveOptions = options.resolveOptions;
|
114
127
|
}
|
@@ -155,7 +168,12 @@ class ContextModule extends Module {
|
|
155
168
|
}
|
156
169
|
|
157
170
|
_createIdentifier() {
|
158
|
-
let identifier =
|
171
|
+
let identifier =
|
172
|
+
this.context ||
|
173
|
+
(typeof this.options.resource === "string" ||
|
174
|
+
this.options.resource === false
|
175
|
+
? `${this.options.resource}`
|
176
|
+
: this.options.resource.join("|"));
|
159
177
|
if (this.options.resourceQuery) {
|
160
178
|
identifier += `|${this.options.resourceQuery}`;
|
161
179
|
}
|
@@ -220,7 +238,19 @@ class ContextModule extends Module {
|
|
220
238
|
* @returns {string} a user readable identifier of the module
|
221
239
|
*/
|
222
240
|
readableIdentifier(requestShortener) {
|
223
|
-
let identifier
|
241
|
+
let identifier;
|
242
|
+
if (this.context) {
|
243
|
+
identifier = requestShortener.shorten(this.context) + "/";
|
244
|
+
} else if (
|
245
|
+
typeof this.options.resource === "string" ||
|
246
|
+
this.options.resource === false
|
247
|
+
) {
|
248
|
+
identifier = requestShortener.shorten(`${this.options.resource}`) + "/";
|
249
|
+
} else {
|
250
|
+
identifier = this.options.resource
|
251
|
+
.map(r => requestShortener.shorten(r) + "/")
|
252
|
+
.join(" ");
|
253
|
+
}
|
224
254
|
if (this.options.resourceQuery) {
|
225
255
|
identifier += ` ${this.options.resourceQuery}`;
|
226
256
|
}
|
@@ -270,11 +300,30 @@ class ContextModule extends Module {
|
|
270
300
|
* @returns {string | null} an identifier for library inclusion
|
271
301
|
*/
|
272
302
|
libIdent(options) {
|
273
|
-
let identifier
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
303
|
+
let identifier;
|
304
|
+
|
305
|
+
if (this.context) {
|
306
|
+
identifier = contextify(
|
307
|
+
options.context,
|
308
|
+
this.context,
|
309
|
+
options.associatedObjectForCache
|
310
|
+
);
|
311
|
+
} else if (typeof this.options.resource === "string") {
|
312
|
+
identifier = contextify(
|
313
|
+
options.context,
|
314
|
+
this.options.resource,
|
315
|
+
options.associatedObjectForCache
|
316
|
+
);
|
317
|
+
} else if (this.options.resource === false) {
|
318
|
+
identifier = "false";
|
319
|
+
} else {
|
320
|
+
identifier = this.options.resource
|
321
|
+
.map(res =>
|
322
|
+
contextify(options.context, res, options.associatedObjectForCache)
|
323
|
+
)
|
324
|
+
.join(" ");
|
325
|
+
}
|
326
|
+
|
278
327
|
if (this.layer) identifier = `(${this.layer})/${identifier}`;
|
279
328
|
if (this.options.mode) {
|
280
329
|
identifier += ` ${this.options.mode}`;
|
@@ -323,8 +372,9 @@ class ContextModule extends Module {
|
|
323
372
|
// build if enforced
|
324
373
|
if (this._forceBuild) return callback(null, true);
|
325
374
|
|
326
|
-
// always build when we have no snapshot
|
327
|
-
if (!this.buildInfo.snapshot)
|
375
|
+
// always build when we have no snapshot and context
|
376
|
+
if (!this.buildInfo.snapshot)
|
377
|
+
return callback(null, Boolean(this.context || this.options.resource));
|
328
378
|
|
329
379
|
fileSystemInfo.checkSnapshotValid(this.buildInfo.snapshot, (err, valid) => {
|
330
380
|
callback(err, !valid);
|
@@ -439,10 +489,16 @@ class ContextModule extends Module {
|
|
439
489
|
);
|
440
490
|
return;
|
441
491
|
}
|
492
|
+
if (!this.context && !this.options.resource) return callback();
|
493
|
+
|
442
494
|
compilation.fileSystemInfo.createSnapshot(
|
443
495
|
startTime,
|
444
496
|
null,
|
445
|
-
|
497
|
+
this.context
|
498
|
+
? [this.context]
|
499
|
+
: typeof this.options.resource === "string"
|
500
|
+
? [this.options.resource]
|
501
|
+
: /** @type {string[]} */ (this.options.resource),
|
446
502
|
null,
|
447
503
|
SNAPSHOT_OPTIONS,
|
448
504
|
(err, snapshot) => {
|
@@ -466,7 +522,15 @@ class ContextModule extends Module {
|
|
466
522
|
missingDependencies,
|
467
523
|
buildDependencies
|
468
524
|
) {
|
469
|
-
|
525
|
+
if (this.context) {
|
526
|
+
contextDependencies.add(this.context);
|
527
|
+
} else if (typeof this.options.resource === "string") {
|
528
|
+
contextDependencies.add(this.options.resource);
|
529
|
+
} else if (this.options.resource === false) {
|
530
|
+
return;
|
531
|
+
} else {
|
532
|
+
for (const res of this.options.resource) contextDependencies.add(res);
|
533
|
+
}
|
470
534
|
}
|
471
535
|
|
472
536
|
/**
|