webpack 5.17.0 → 5.18.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/bin/webpack.js +0 -0
- package/lib/CacheFacade.js +1 -0
- package/lib/ChunkGraph.js +132 -19
- package/lib/CodeGenerationResults.js +43 -8
- package/lib/Compilation.js +233 -134
- package/lib/Dependency.js +1 -7
- package/lib/ExportsInfo.js +23 -4
- package/lib/HotModuleReplacementPlugin.js +76 -29
- package/lib/Module.js +2 -3
- package/lib/Template.js +32 -23
- package/lib/dependencies/ExportsInfoDependency.js +0 -20
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +0 -29
- package/lib/dependencies/HarmonyImportDependency.js +0 -41
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +0 -19
- package/lib/dependencies/JsonExportsDependency.js +0 -1
- package/lib/dependencies/ModuleDecoratorDependency.js +0 -1
- package/lib/dependencies/NullDependency.js +0 -8
- package/lib/dependencies/ProvidedDependency.js +0 -1
- package/lib/dependencies/StaticExportsDependency.js +0 -12
- package/lib/optimize/ConcatenatedModule.js +0 -12
- package/lib/stats/DefaultStatsPresetPlugin.js +1 -0
- package/lib/util/MapHelpers.js +22 -0
- package/lib/util/createHash.js +13 -7
- package/lib/util/runtime.js +12 -1
- package/package.json +1 -1
- package/types.d.ts +26 -2
package/lib/Compilation.js
CHANGED
@@ -2173,77 +2173,83 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2173
2173
|
|
2174
2174
|
this.logger.time("hashing");
|
2175
2175
|
this.hooks.beforeHash.call();
|
2176
|
-
this.createHash();
|
2176
|
+
const codeGenerationJobs = this.createHash();
|
2177
2177
|
this.hooks.afterHash.call();
|
2178
2178
|
this.logger.timeEnd("hashing");
|
2179
2179
|
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
}
|
2185
|
-
|
2186
|
-
this.logger.time("module assets");
|
2187
|
-
this.clearAssets();
|
2180
|
+
this._runCodeGenerationJobs(codeGenerationJobs, err => {
|
2181
|
+
if (err) {
|
2182
|
+
return callback(err);
|
2183
|
+
}
|
2188
2184
|
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2185
|
+
if (shouldRecord) {
|
2186
|
+
this.logger.time("record hash");
|
2187
|
+
this.hooks.recordHash.call(this.records);
|
2188
|
+
this.logger.timeEnd("record hash");
|
2189
|
+
}
|
2192
2190
|
|
2193
|
-
|
2194
|
-
this.
|
2195
|
-
this.hooks.processAssets.callAsync(this.assets, err => {
|
2196
|
-
if (err) {
|
2197
|
-
return callback(
|
2198
|
-
makeWebpackError(err, "Compilation.hooks.processAssets")
|
2199
|
-
);
|
2200
|
-
}
|
2201
|
-
this.hooks.afterProcessAssets.call(this.assets);
|
2202
|
-
this.logger.timeEnd("process assets");
|
2203
|
-
this.assets = soonFrozenObjectDeprecation(
|
2204
|
-
this.assets,
|
2205
|
-
"Compilation.assets",
|
2206
|
-
"DEP_WEBPACK_COMPILATION_ASSETS",
|
2207
|
-
`BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
|
2208
|
-
Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
|
2209
|
-
Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
|
2210
|
-
);
|
2191
|
+
this.logger.time("module assets");
|
2192
|
+
this.clearAssets();
|
2211
2193
|
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
}
|
2194
|
+
this.hooks.beforeModuleAssets.call();
|
2195
|
+
this.createModuleAssets();
|
2196
|
+
this.logger.timeEnd("module assets");
|
2216
2197
|
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
}
|
2221
|
-
return this.hooks.afterSeal.callAsync(err => {
|
2198
|
+
const cont = () => {
|
2199
|
+
this.logger.time("process assets");
|
2200
|
+
this.hooks.processAssets.callAsync(this.assets, err => {
|
2222
2201
|
if (err) {
|
2223
2202
|
return callback(
|
2224
|
-
makeWebpackError(err, "Compilation.hooks.
|
2203
|
+
makeWebpackError(err, "Compilation.hooks.processAssets")
|
2225
2204
|
);
|
2226
2205
|
}
|
2227
|
-
this.
|
2228
|
-
|
2206
|
+
this.hooks.afterProcessAssets.call(this.assets);
|
2207
|
+
this.logger.timeEnd("process assets");
|
2208
|
+
this.assets = soonFrozenObjectDeprecation(
|
2209
|
+
this.assets,
|
2210
|
+
"Compilation.assets",
|
2211
|
+
"DEP_WEBPACK_COMPILATION_ASSETS",
|
2212
|
+
`BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
|
2213
|
+
Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
|
2214
|
+
Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
|
2215
|
+
);
|
2216
|
+
|
2217
|
+
this.summarizeDependencies();
|
2218
|
+
if (shouldRecord) {
|
2219
|
+
this.hooks.record.call(this, this.records);
|
2220
|
+
}
|
2221
|
+
|
2222
|
+
if (this.hooks.needAdditionalSeal.call()) {
|
2223
|
+
this.unseal();
|
2224
|
+
return this.seal(callback);
|
2225
|
+
}
|
2226
|
+
return this.hooks.afterSeal.callAsync(err => {
|
2227
|
+
if (err) {
|
2228
|
+
return callback(
|
2229
|
+
makeWebpackError(err, "Compilation.hooks.afterSeal")
|
2230
|
+
);
|
2231
|
+
}
|
2232
|
+
this.fileSystemInfo.logStatistics();
|
2233
|
+
callback();
|
2234
|
+
});
|
2229
2235
|
});
|
2230
|
-
}
|
2231
|
-
};
|
2236
|
+
};
|
2232
2237
|
|
2233
|
-
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2238
|
+
this.logger.time("create chunk assets");
|
2239
|
+
if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
|
2240
|
+
this.hooks.beforeChunkAssets.call();
|
2241
|
+
this.createChunkAssets(err => {
|
2242
|
+
this.logger.timeEnd("create chunk assets");
|
2243
|
+
if (err) {
|
2244
|
+
return callback(err);
|
2245
|
+
}
|
2246
|
+
cont();
|
2247
|
+
});
|
2248
|
+
} else {
|
2237
2249
|
this.logger.timeEnd("create chunk assets");
|
2238
|
-
if (err) {
|
2239
|
-
return callback(err);
|
2240
|
-
}
|
2241
2250
|
cont();
|
2242
|
-
}
|
2243
|
-
}
|
2244
|
-
this.logger.timeEnd("create chunk assets");
|
2245
|
-
cont();
|
2246
|
-
}
|
2251
|
+
}
|
2252
|
+
});
|
2247
2253
|
});
|
2248
2254
|
}
|
2249
2255
|
);
|
@@ -2288,16 +2294,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2288
2294
|
}
|
2289
2295
|
|
2290
2296
|
codeGeneration(callback) {
|
2291
|
-
|
2292
|
-
|
2293
|
-
const {
|
2294
|
-
chunkGraph,
|
2295
|
-
moduleGraph,
|
2296
|
-
dependencyTemplates,
|
2297
|
-
runtimeTemplate
|
2298
|
-
} = this;
|
2299
|
-
const results = (this.codeGenerationResults = new CodeGenerationResults());
|
2300
|
-
const errors = [];
|
2297
|
+
const { chunkGraph } = this;
|
2298
|
+
this.codeGenerationResults = new CodeGenerationResults();
|
2301
2299
|
/** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
|
2302
2300
|
const jobs = [];
|
2303
2301
|
for (const module of this.modules) {
|
@@ -2324,52 +2322,41 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2324
2322
|
}
|
2325
2323
|
}
|
2326
2324
|
|
2325
|
+
this._runCodeGenerationJobs(jobs, callback);
|
2326
|
+
}
|
2327
|
+
|
2328
|
+
_runCodeGenerationJobs(jobs, callback) {
|
2329
|
+
let statModulesFromCache = 0;
|
2330
|
+
let statModulesGenerated = 0;
|
2331
|
+
const {
|
2332
|
+
chunkGraph,
|
2333
|
+
moduleGraph,
|
2334
|
+
dependencyTemplates,
|
2335
|
+
runtimeTemplate
|
2336
|
+
} = this;
|
2337
|
+
const results = this.codeGenerationResults;
|
2338
|
+
const errors = [];
|
2327
2339
|
asyncLib.eachLimit(
|
2328
2340
|
jobs,
|
2329
2341
|
this.options.parallelism,
|
2330
2342
|
({ module, hash, runtime, runtimes }, callback) => {
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
statModulesGenerated++;
|
2344
|
-
|
2345
|
-
|
2346
|
-
result = module.codeGeneration({
|
2347
|
-
chunkGraph,
|
2348
|
-
moduleGraph,
|
2349
|
-
dependencyTemplates,
|
2350
|
-
runtimeTemplate,
|
2351
|
-
runtime
|
2352
|
-
});
|
2353
|
-
} catch (err) {
|
2354
|
-
errors.push(new CodeGenerationError(module, err));
|
2355
|
-
result = cachedResult = {
|
2356
|
-
sources: new Map(),
|
2357
|
-
runtimeRequirements: null
|
2358
|
-
};
|
2359
|
-
}
|
2360
|
-
} else {
|
2361
|
-
statModulesFromCache++;
|
2362
|
-
result = cachedResult;
|
2363
|
-
}
|
2364
|
-
for (const runtime of runtimes) {
|
2365
|
-
results.add(module, runtime, result);
|
2366
|
-
}
|
2367
|
-
if (!cachedResult) {
|
2368
|
-
cache.store(result, callback);
|
2369
|
-
} else {
|
2370
|
-
callback();
|
2343
|
+
this._codeGenerationModule(
|
2344
|
+
module,
|
2345
|
+
runtime,
|
2346
|
+
runtimes,
|
2347
|
+
hash,
|
2348
|
+
dependencyTemplates,
|
2349
|
+
chunkGraph,
|
2350
|
+
moduleGraph,
|
2351
|
+
runtimeTemplate,
|
2352
|
+
errors,
|
2353
|
+
results,
|
2354
|
+
(err, codeGenerated) => {
|
2355
|
+
if (codeGenerated) statModulesGenerated++;
|
2356
|
+
else statModulesFromCache++;
|
2357
|
+
callback(err);
|
2371
2358
|
}
|
2372
|
-
|
2359
|
+
);
|
2373
2360
|
},
|
2374
2361
|
err => {
|
2375
2362
|
if (err) return callback(err);
|
@@ -2392,6 +2379,76 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2392
2379
|
);
|
2393
2380
|
}
|
2394
2381
|
|
2382
|
+
/**
|
2383
|
+
* @param {Module} module module
|
2384
|
+
* @param {RuntimeSpec} runtime runtime
|
2385
|
+
* @param {RuntimeSpec[]} runtimes runtimes
|
2386
|
+
* @param {string} hash hash
|
2387
|
+
* @param {DependencyTemplates} dependencyTemplates dependencyTemplates
|
2388
|
+
* @param {ChunkGraph} chunkGraph chunkGraph
|
2389
|
+
* @param {ModuleGraph} moduleGraph moduleGraph
|
2390
|
+
* @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
|
2391
|
+
* @param {WebpackError[]} errors errors
|
2392
|
+
* @param {CodeGenerationResults} results results
|
2393
|
+
* @param {function(WebpackError=, boolean=): void} callback callback
|
2394
|
+
*/
|
2395
|
+
_codeGenerationModule(
|
2396
|
+
module,
|
2397
|
+
runtime,
|
2398
|
+
runtimes,
|
2399
|
+
hash,
|
2400
|
+
dependencyTemplates,
|
2401
|
+
chunkGraph,
|
2402
|
+
moduleGraph,
|
2403
|
+
runtimeTemplate,
|
2404
|
+
errors,
|
2405
|
+
results,
|
2406
|
+
callback
|
2407
|
+
) {
|
2408
|
+
let codeGenerated = false;
|
2409
|
+
const cache = new MultiItemCache(
|
2410
|
+
runtimes.map(runtime =>
|
2411
|
+
this._codeGenerationCache.getItemCache(
|
2412
|
+
`${module.identifier()}|${getRuntimeKey(runtime)}`,
|
2413
|
+
`${hash}|${dependencyTemplates.getHash()}`
|
2414
|
+
)
|
2415
|
+
)
|
2416
|
+
);
|
2417
|
+
cache.get((err, cachedResult) => {
|
2418
|
+
if (err) return callback(err);
|
2419
|
+
let result;
|
2420
|
+
if (!cachedResult) {
|
2421
|
+
try {
|
2422
|
+
codeGenerated = true;
|
2423
|
+
this.codeGeneratedModules.add(module);
|
2424
|
+
result = module.codeGeneration({
|
2425
|
+
chunkGraph,
|
2426
|
+
moduleGraph,
|
2427
|
+
dependencyTemplates,
|
2428
|
+
runtimeTemplate,
|
2429
|
+
runtime
|
2430
|
+
});
|
2431
|
+
} catch (err) {
|
2432
|
+
errors.push(new CodeGenerationError(module, err));
|
2433
|
+
result = cachedResult = {
|
2434
|
+
sources: new Map(),
|
2435
|
+
runtimeRequirements: null
|
2436
|
+
};
|
2437
|
+
}
|
2438
|
+
} else {
|
2439
|
+
result = cachedResult;
|
2440
|
+
}
|
2441
|
+
for (const runtime of runtimes) {
|
2442
|
+
results.add(module, runtime, result);
|
2443
|
+
}
|
2444
|
+
if (!cachedResult) {
|
2445
|
+
cache.store(result, err => callback(err, codeGenerated));
|
2446
|
+
} else {
|
2447
|
+
callback(null, codeGenerated);
|
2448
|
+
}
|
2449
|
+
});
|
2450
|
+
}
|
2451
|
+
|
2395
2452
|
/**
|
2396
2453
|
* @returns {void}
|
2397
2454
|
*/
|
@@ -2818,20 +2875,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2818
2875
|
for (const module of this.modules) {
|
2819
2876
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
2820
2877
|
statModulesHashed++;
|
2821
|
-
|
2822
|
-
module.updateHash(moduleHash, {
|
2823
|
-
chunkGraph,
|
2824
|
-
runtime,
|
2825
|
-
runtimeTemplate
|
2826
|
-
});
|
2827
|
-
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2828
|
-
hashDigest
|
2829
|
-
));
|
2830
|
-
chunkGraph.setModuleHashes(
|
2878
|
+
this._createModuleHash(
|
2831
2879
|
module,
|
2880
|
+
chunkGraph,
|
2832
2881
|
runtime,
|
2833
|
-
|
2834
|
-
|
2882
|
+
hashFunction,
|
2883
|
+
runtimeTemplate,
|
2884
|
+
hashDigest,
|
2885
|
+
hashDigestLength
|
2835
2886
|
);
|
2836
2887
|
}
|
2837
2888
|
}
|
@@ -2842,6 +2893,33 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2842
2893
|
);
|
2843
2894
|
}
|
2844
2895
|
|
2896
|
+
_createModuleHash(
|
2897
|
+
module,
|
2898
|
+
chunkGraph,
|
2899
|
+
runtime,
|
2900
|
+
hashFunction,
|
2901
|
+
runtimeTemplate,
|
2902
|
+
hashDigest,
|
2903
|
+
hashDigestLength
|
2904
|
+
) {
|
2905
|
+
const moduleHash = createHash(hashFunction);
|
2906
|
+
module.updateHash(moduleHash, {
|
2907
|
+
chunkGraph,
|
2908
|
+
runtime,
|
2909
|
+
runtimeTemplate
|
2910
|
+
});
|
2911
|
+
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2912
|
+
hashDigest
|
2913
|
+
));
|
2914
|
+
chunkGraph.setModuleHashes(
|
2915
|
+
module,
|
2916
|
+
runtime,
|
2917
|
+
moduleHashDigest,
|
2918
|
+
moduleHashDigest.substr(0, hashDigestLength)
|
2919
|
+
);
|
2920
|
+
return moduleHashDigest;
|
2921
|
+
}
|
2922
|
+
|
2845
2923
|
createHash() {
|
2846
2924
|
this.logger.time("hashing: initialize hash");
|
2847
2925
|
const chunkGraph = this.chunkGraph;
|
@@ -2922,31 +3000,49 @@ This prevents using hashes of each other and should be avoided.`
|
|
2922
3000
|
});
|
2923
3001
|
this.logger.timeEnd("hashing: sort chunks");
|
2924
3002
|
const fullHashChunks = new Set();
|
3003
|
+
/** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
|
3004
|
+
const codeGenerationJobs = [];
|
3005
|
+
/** @type {Map<string, Map<Module, {module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}>>} */
|
3006
|
+
const codeGenerationJobsMap = new Map();
|
2925
3007
|
const processChunk = chunk => {
|
2926
3008
|
// Last minute module hash generation for modules that depend on chunk hashes
|
2927
3009
|
this.logger.time("hashing: hash runtime modules");
|
3010
|
+
const runtime = chunk.runtime;
|
2928
3011
|
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
2929
|
-
if (!chunkGraph.hasModuleHashes(module,
|
2930
|
-
const
|
2931
|
-
module.updateHash(moduleHash, {
|
2932
|
-
chunkGraph,
|
2933
|
-
runtime: chunk.runtime,
|
2934
|
-
runtimeTemplate
|
2935
|
-
});
|
2936
|
-
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
2937
|
-
hashDigest
|
2938
|
-
));
|
2939
|
-
chunkGraph.setModuleHashes(
|
3012
|
+
if (!chunkGraph.hasModuleHashes(module, runtime)) {
|
3013
|
+
const hash = this._createModuleHash(
|
2940
3014
|
module,
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
3015
|
+
chunkGraph,
|
3016
|
+
runtime,
|
3017
|
+
hashFunction,
|
3018
|
+
runtimeTemplate,
|
3019
|
+
hashDigest,
|
3020
|
+
hashDigestLength
|
2944
3021
|
);
|
3022
|
+
let hashMap = codeGenerationJobsMap.get(hash);
|
3023
|
+
if (hashMap) {
|
3024
|
+
const moduleJob = hashMap.get(module);
|
3025
|
+
if (moduleJob) {
|
3026
|
+
moduleJob.runtimes.push(runtime);
|
3027
|
+
continue;
|
3028
|
+
}
|
3029
|
+
} else {
|
3030
|
+
hashMap = new Map();
|
3031
|
+
codeGenerationJobsMap.set(hash, hashMap);
|
3032
|
+
}
|
3033
|
+
const job = {
|
3034
|
+
module,
|
3035
|
+
hash,
|
3036
|
+
runtime,
|
3037
|
+
runtimes: [runtime]
|
3038
|
+
};
|
3039
|
+
hashMap.set(module, job);
|
3040
|
+
codeGenerationJobs.push(job);
|
2945
3041
|
}
|
2946
3042
|
}
|
2947
3043
|
this.logger.timeAggregate("hashing: hash runtime modules");
|
2948
|
-
const chunkHash = createHash(hashFunction);
|
2949
3044
|
this.logger.time("hashing: hash chunks");
|
3045
|
+
const chunkHash = createHash(hashFunction);
|
2950
3046
|
try {
|
2951
3047
|
if (outputOptions.hashSalt) {
|
2952
3048
|
chunkHash.update(outputOptions.hashSalt);
|
@@ -2999,12 +3095,14 @@ This prevents using hashes of each other and should be avoided.`
|
|
2999
3095
|
const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
|
3000
3096
|
hashDigest
|
3001
3097
|
));
|
3098
|
+
const oldHash = chunkGraph.getModuleHash(module, chunk.runtime);
|
3002
3099
|
chunkGraph.setModuleHashes(
|
3003
3100
|
module,
|
3004
3101
|
chunk.runtime,
|
3005
3102
|
moduleHashDigest,
|
3006
3103
|
moduleHashDigest.substr(0, hashDigestLength)
|
3007
3104
|
);
|
3105
|
+
codeGenerationJobsMap.get(oldHash).get(module).hash = moduleHashDigest;
|
3008
3106
|
}
|
3009
3107
|
const chunkHash = createHash(hashFunction);
|
3010
3108
|
chunkHash.update(chunk.hash);
|
@@ -3017,6 +3115,7 @@ This prevents using hashes of each other and should be avoided.`
|
|
3017
3115
|
this.hooks.contentHash.call(chunk);
|
3018
3116
|
}
|
3019
3117
|
this.logger.timeEnd("hashing: process full hash modules");
|
3118
|
+
return codeGenerationJobs;
|
3020
3119
|
}
|
3021
3120
|
|
3022
3121
|
/**
|
package/lib/Dependency.js
CHANGED
@@ -167,13 +167,7 @@ class Dependency {
|
|
167
167
|
* @param {UpdateHashContext} context context
|
168
168
|
* @returns {void}
|
169
169
|
*/
|
170
|
-
updateHash(hash, context) {
|
171
|
-
const { chunkGraph } = context;
|
172
|
-
const module = chunkGraph.moduleGraph.getModule(this);
|
173
|
-
if (module) {
|
174
|
-
hash.update(chunkGraph.getModuleId(module) + "");
|
175
|
-
}
|
176
|
-
}
|
170
|
+
updateHash(hash, context) {}
|
177
171
|
|
178
172
|
/**
|
179
173
|
* implement this method to allow the occurrence order plugin to count correctly
|
package/lib/ExportsInfo.js
CHANGED
@@ -684,15 +684,27 @@ class ExportsInfo {
|
|
684
684
|
* @returns {void}
|
685
685
|
*/
|
686
686
|
updateHash(hash, runtime) {
|
687
|
+
this._updateHash(hash, runtime, new Set());
|
688
|
+
}
|
689
|
+
|
690
|
+
/**
|
691
|
+
* @param {Hash} hash the hash
|
692
|
+
* @param {RuntimeSpec} runtime the runtime
|
693
|
+
* @param {Set<ExportsInfo>} alreadyVisitedExportsInfo for circular references
|
694
|
+
* @returns {void}
|
695
|
+
*/
|
696
|
+
_updateHash(hash, runtime, alreadyVisitedExportsInfo) {
|
697
|
+
const set = new Set(alreadyVisitedExportsInfo);
|
698
|
+
set.add(this);
|
687
699
|
for (const exportInfo of this.orderedExports) {
|
688
700
|
if (exportInfo.hasInfo(this._otherExportsInfo, runtime)) {
|
689
|
-
exportInfo.
|
701
|
+
exportInfo._updateHash(hash, runtime, set);
|
690
702
|
}
|
691
703
|
}
|
692
|
-
this._sideEffectsOnlyInfo.
|
693
|
-
this._otherExportsInfo.
|
704
|
+
this._sideEffectsOnlyInfo._updateHash(hash, runtime, set);
|
705
|
+
this._otherExportsInfo._updateHash(hash, runtime, set);
|
694
706
|
if (this._redirectTo !== undefined) {
|
695
|
-
this._redirectTo.
|
707
|
+
this._redirectTo._updateHash(hash, runtime, set);
|
696
708
|
}
|
697
709
|
}
|
698
710
|
|
@@ -1338,10 +1350,17 @@ class ExportInfo {
|
|
1338
1350
|
}
|
1339
1351
|
|
1340
1352
|
updateHash(hash, runtime) {
|
1353
|
+
this._updateHash(hash, runtime, new Set());
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
_updateHash(hash, runtime, alreadyVisitedExportsInfo) {
|
1341
1357
|
hash.update(`${this._usedName || this.name}`);
|
1342
1358
|
hash.update(`${this.getUsed(runtime)}`);
|
1343
1359
|
hash.update(`${this.provided}`);
|
1344
1360
|
hash.update(`${this.terminalBinding}`);
|
1361
|
+
if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) {
|
1362
|
+
this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo);
|
1363
|
+
}
|
1345
1364
|
}
|
1346
1365
|
|
1347
1366
|
getUsedInfo() {
|
@@ -39,6 +39,7 @@ const {
|
|
39
39
|
/** @typedef {import("./Compiler")} Compiler */
|
40
40
|
/** @typedef {import("./Module")} Module */
|
41
41
|
/** @typedef {import("./RuntimeModule")} RuntimeModule */
|
42
|
+
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
|
42
43
|
|
43
44
|
/**
|
44
45
|
* @typedef {Object} HMRJavascriptParserHooks
|
@@ -316,37 +317,61 @@ class HotModuleReplacementPlugin {
|
|
316
317
|
/** @type {TupleSet<[Module, Chunk]>} */
|
317
318
|
const updatedModules = new TupleSet();
|
318
319
|
/** @type {TupleSet<[Module, Chunk]>} */
|
319
|
-
const
|
320
|
+
const fullHashModules = new TupleSet();
|
321
|
+
/** @type {TupleSet<[Module, RuntimeSpec]>} */
|
322
|
+
const nonCodeGeneratedModules = new TupleSet();
|
320
323
|
compilation.hooks.fullHash.tap("HotModuleReplacementPlugin", hash => {
|
321
324
|
const chunkGraph = compilation.chunkGraph;
|
322
325
|
const records = compilation.records;
|
323
326
|
for (const chunk of compilation.chunks) {
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
+
const getModuleHash = module => {
|
328
|
+
if (
|
329
|
+
compilation.codeGenerationResults.has(module, chunk.runtime)
|
330
|
+
) {
|
331
|
+
return compilation.codeGenerationResults.getHash(
|
332
|
+
module,
|
333
|
+
chunk.runtime
|
334
|
+
);
|
335
|
+
} else {
|
336
|
+
nonCodeGeneratedModules.add(module, chunk.runtime);
|
337
|
+
return chunkGraph.getModuleHash(module, chunk.runtime);
|
338
|
+
}
|
339
|
+
};
|
340
|
+
const fullHashModulesInThisChunk = chunkGraph.getChunkFullHashModulesSet(
|
327
341
|
chunk
|
328
342
|
);
|
329
|
-
if (
|
330
|
-
for (const module of
|
331
|
-
|
332
|
-
lazyHashedModulesInThisChunk.add(module);
|
343
|
+
if (fullHashModulesInThisChunk !== undefined) {
|
344
|
+
for (const module of fullHashModulesInThisChunk) {
|
345
|
+
fullHashModules.add(module, chunk);
|
333
346
|
}
|
334
347
|
}
|
335
348
|
const modules = chunkGraph.getChunkModulesIterable(chunk);
|
336
349
|
if (modules !== undefined) {
|
337
|
-
if (
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
350
|
+
if (records.chunkModuleHashes) {
|
351
|
+
if (fullHashModulesInThisChunk !== undefined) {
|
352
|
+
for (const module of modules) {
|
353
|
+
const key = `${chunk.id}|${module.identifier()}`;
|
354
|
+
const hash = getModuleHash(module);
|
355
|
+
if (
|
356
|
+
fullHashModulesInThisChunk.has(
|
357
|
+
/** @type {RuntimeModule} */ (module)
|
358
|
+
)
|
359
|
+
) {
|
360
|
+
if (records.fullHashChunkModuleHashes[key] !== hash) {
|
361
|
+
updatedModules.add(module, chunk);
|
362
|
+
}
|
363
|
+
fullHashChunkModuleHashes[key] = hash;
|
364
|
+
} else {
|
365
|
+
if (records.chunkModuleHashes[key] !== hash) {
|
366
|
+
updatedModules.add(module, chunk);
|
367
|
+
}
|
368
|
+
chunkModuleHashes[key] = hash;
|
347
369
|
}
|
348
|
-
|
349
|
-
|
370
|
+
}
|
371
|
+
} else {
|
372
|
+
for (const module of modules) {
|
373
|
+
const key = `${chunk.id}|${module.identifier()}`;
|
374
|
+
const hash = getModuleHash(module);
|
350
375
|
if (records.chunkModuleHashes[key] !== hash) {
|
351
376
|
updatedModules.add(module, chunk);
|
352
377
|
}
|
@@ -354,12 +379,24 @@ class HotModuleReplacementPlugin {
|
|
354
379
|
}
|
355
380
|
}
|
356
381
|
} else {
|
357
|
-
|
358
|
-
const
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
382
|
+
if (fullHashModulesInThisChunk !== undefined) {
|
383
|
+
for (const module of modules) {
|
384
|
+
const key = `${chunk.id}|${module.identifier()}`;
|
385
|
+
const hash = getModuleHash(module);
|
386
|
+
if (
|
387
|
+
fullHashModulesInThisChunk.has(
|
388
|
+
/** @type {RuntimeModule} */ (module)
|
389
|
+
)
|
390
|
+
) {
|
391
|
+
fullHashChunkModuleHashes[key] = hash;
|
392
|
+
} else {
|
393
|
+
chunkModuleHashes[key] = hash;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
} else {
|
397
|
+
for (const module of modules) {
|
398
|
+
const key = `${chunk.id}|${module.identifier()}`;
|
399
|
+
const hash = getModuleHash(module);
|
363
400
|
chunkModuleHashes[key] = hash;
|
364
401
|
}
|
365
402
|
}
|
@@ -388,9 +425,14 @@ class HotModuleReplacementPlugin {
|
|
388
425
|
) {
|
389
426
|
return;
|
390
427
|
}
|
391
|
-
for (const [module, chunk] of
|
428
|
+
for (const [module, chunk] of fullHashModules) {
|
392
429
|
const key = `${chunk.id}|${module.identifier()}`;
|
393
|
-
const hash =
|
430
|
+
const hash = nonCodeGeneratedModules.has(module, chunk.runtime)
|
431
|
+
? chunkGraph.getModuleHash(module, chunk.runtime)
|
432
|
+
: compilation.codeGenerationResults.getHash(
|
433
|
+
module,
|
434
|
+
chunk.runtime
|
435
|
+
);
|
394
436
|
if (records.chunkModuleHashes[key] !== hash) {
|
395
437
|
updatedModules.add(module, chunk);
|
396
438
|
}
|
@@ -500,7 +542,12 @@ class HotModuleReplacementPlugin {
|
|
500
542
|
const runtimes = chunkGraph.getModuleRuntimes(module);
|
501
543
|
if (oldRuntime === newRuntime && runtimes.has(newRuntime)) {
|
502
544
|
// Module is still in the same runtime combination
|
503
|
-
const hash =
|
545
|
+
const hash = nonCodeGeneratedModules.has(module, newRuntime)
|
546
|
+
? chunkGraph.getModuleHash(module, newRuntime)
|
547
|
+
: compilation.codeGenerationResults.getHash(
|
548
|
+
module,
|
549
|
+
newRuntime
|
550
|
+
);
|
504
551
|
if (hash !== oldHash) {
|
505
552
|
if (module.type === "runtime") {
|
506
553
|
newRuntimeModules = newRuntimeModules || [];
|