Skip to content

Commit a5c5d33

Browse files
authored
feat: support resource data sideEffects: false (#403)
* fix: store hashes in module cache * fixup! fix: store hashes in module cache * fix: test side effect resource resolve data * feat: freeze and thaw enhanced-resolve resourceResolveData * fix: freeze and thaw module resolver resourceResolveData * chore: add serial.objectAssign * fixup! fix: test side effect resource resolve data * fixup! fix: test side effect resource resolve data * fixup! feat: freeze and thaw enhanced-resolve resourceResolveData * fixup! fix: freeze and thaw module resolver resourceResolveData * fixup! chore: add serial.objectAssign * fix: build RuleSet if normalModuleFactory is not available
1 parent 236b8a5 commit a5c5d33

27 files changed

+448
-56
lines changed

lib/CacheEnhancedResolve.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,25 @@ const nodeObjectHash = require('node-object-hash');
66
const pluginCompat = require('./util/plugin-compat');
77
const promisify = require('./util/promisify');
88
const relateContext = require('./util/relate-context');
9+
const serial = require('./util/serial');
910
const values = require('./util/Object.values');
1011
const bulkFsTask = require('./util/bulk-fs-task');
1112
const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');
1213
const parseJson = require('./util/parseJson');
1314

15+
const serialNormalResolved = serial.created({
16+
result: serial.path,
17+
resourceResolveData: serial.objectAssign({
18+
context: serial.created({
19+
issuer: serial.request,
20+
resolveOptions: serial.identity,
21+
}),
22+
path: serial.path,
23+
descriptionFilePath: serial.path,
24+
descriptionFileRoot: serial.path,
25+
}),
26+
});
27+
1428
class EnhancedResolveCache {
1529
apply(compiler) {
1630
let missingCacheSerializer;
@@ -106,8 +120,8 @@ class EnhancedResolveCache {
106120
}
107121

108122
function contextNormalResolved(compiler, resolved) {
109-
return Object.assign({}, resolved, {
110-
result: contextNormalPath(compiler, resolved.result),
123+
return serialNormalResolved.thaw(resolved, resolved, {
124+
compiler,
111125
});
112126
}
113127

@@ -267,14 +281,15 @@ class EnhancedResolveCache {
267281
return cb(
268282
null,
269283
[resolve.result].concat(request.split('?').slice(1)).join('?'),
284+
resolve.resourceResolveData,
270285
);
271286
} else {
272287
resolve.invalid = true;
273288
resolve.invalidReason = 'out of date';
274289
}
275290
}
276291
let localMissing = [];
277-
const callback = (err, result) => {
292+
const callback = (err, result, result2) => {
278293
if (result) {
279294
const inverseId = JSON.stringify([context, result.split('?')[0]]);
280295
const resolveId = JSON.stringify([context, request]);
@@ -293,7 +308,7 @@ class EnhancedResolveCache {
293308
// recorded and we get a new empty array of missing, keep the old
294309
// value.
295310
if (localMissing.length === 0 && missingCache[key][inverseId]) {
296-
return cb(err, result);
311+
return cb(err, result, result2);
297312
}
298313

299314
missingCache[key][inverseId] = localMissing
@@ -311,10 +326,11 @@ class EnhancedResolveCache {
311326
missingCache[key][inverseId].new = true;
312327
resolverCache[key][resolveId] = {
313328
result: result.split('?')[0],
329+
resourceResolveData: result2,
314330
new: true,
315331
};
316332
}
317-
cb(err, result);
333+
cb(err, result, result2);
318334
};
319335
const _missing =
320336
cb.missing || (resolveContext && resolveContext.missing);
@@ -459,8 +475,8 @@ class EnhancedResolveCache {
459475
}
460476

461477
function relateNormalResolved(compiler, resolved) {
462-
return Object.assign({}, resolved, {
463-
result: relateNormalPath(compiler, resolved.result),
478+
return serialNormalResolved.freeze(resolved, resolved, {
479+
compiler,
464480
});
465481
}
466482

lib/CacheModuleResolver.js

Lines changed: 123 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,129 @@
11
const nodeObjectHash = require('node-object-hash');
22

3+
const serial = require('./util/serial');
34
const pluginCompat = require('./util/plugin-compat');
45
const relateContext = require('./util/relate-context');
56
const parseJson = require('./util/parseJson');
67
const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');
78

9+
const serialJsonKey = {
10+
freeze(arg, value, extra) {
11+
return JSON.parse(arg);
12+
},
13+
thaw(arg, frozen, extra) {
14+
return JSON.stringify(arg);
15+
},
16+
};
17+
18+
const serialJson = {
19+
freeze(arg, value, extra) {
20+
return JSON.stringify(arg);
21+
},
22+
thaw(arg, frozen, extra) {
23+
return JSON.parse(arg);
24+
},
25+
};
26+
27+
const serialObjectAssign = serial.objectAssign;
28+
29+
const serialResolveOptionsKey = serialObjectAssign({
30+
context: serial.path,
31+
userRequest: serial.request,
32+
options: serialObjectAssign({
33+
request: serial.request,
34+
}),
35+
});
36+
37+
const serialResolveKey = serialObjectAssign({
38+
context: serial.path,
39+
request: serial.request,
40+
});
41+
42+
const serialNormalModuleResolveKey = serial.pipe(
43+
serialJsonKey,
44+
{
45+
freeze(arg, key, extra) {
46+
if (Array.isArray(arg)) {
47+
return [
48+
arg[0],
49+
serial.path.freeze(arg[1], arg[1], extra),
50+
serial.request.freeze(arg[2], arg[2], extra),
51+
];
52+
} else if (!arg.request) {
53+
return serialResolveOptionsKey.freeze(arg, arg, extra);
54+
} else {
55+
return serialResolveKey.freeze(arg, arg, extra);
56+
}
57+
},
58+
thaw(arg, frozen, extra) {
59+
if (Array.isArray(arg)) {
60+
return [
61+
arg[0],
62+
serial.path.thaw(arg[1], arg[1], extra),
63+
serial.request.thaw(arg[2], arg[2], extra),
64+
];
65+
} else if (!arg.request) {
66+
return serialResolveOptionsKey.thaw(arg, arg, extra);
67+
} else {
68+
return serialResolveKey.thaw(arg, arg, extra);
69+
}
70+
},
71+
},
72+
serialJson,
73+
);
74+
75+
const serialNormalModuleId = {
76+
freeze(arg, module, extra) {
77+
return (
78+
id.substring(0, 24) + serial.request.freeze(id.substring(24), id, extra)
79+
);
80+
},
81+
thaw(arg, frozen, extra) {
82+
return (
83+
id.substring(0, 24) + serial.request.thaw(id.substring(24), id, extra)
84+
);
85+
},
86+
};
87+
88+
const serialResolveContext = serialObjectAssign({
89+
identifier: serialNormalModuleId,
90+
resource: serialNormalModuleId,
91+
});
92+
93+
const serialResolveNormal = serialObjectAssign({
94+
context: serial.path,
95+
request: serial.request,
96+
userRequest: serial.request,
97+
rawRequest: serial.request,
98+
resource: serial.request,
99+
loaders: serial.loaders,
100+
resourceResolveData: serial.objectAssign({
101+
context: serial.created({
102+
issuer: serial.request,
103+
resolveOptions: serial.identity,
104+
}),
105+
path: serial.path,
106+
request: serial.request,
107+
descriptionFilePath: serial.path,
108+
descriptionFileRoot: serial.path,
109+
}),
110+
});
111+
112+
const serialResolve = {
113+
freeze(arg, module, extra) {
114+
if (arg.type === 'context') {
115+
return serialResolveContext.freeze(arg, arg, extra);
116+
}
117+
return serialResolveNormal.freeze(arg, arg, extra);
118+
},
119+
thaw(arg, frozen, extra) {
120+
if (arg.type === 'context') {
121+
return serialResolveContext.thaw(arg, arg, extra);
122+
}
123+
return serialResolveNormal.thaw(arg, arg, extra);
124+
},
125+
};
126+
8127
class ModuleResolverCache {
9128
apply(compiler) {
10129
let moduleResolveCache = {};
@@ -80,17 +199,8 @@ class ModuleResolverCache {
80199
resource: contextNormalRequest(compiler, resolved.resource),
81200
});
82201
}
83-
return Object.assign({}, resolved, {
84-
context: contextNormalRequest(compiler, resolved.context),
85-
request: contextNormalRequest(compiler, resolved.request),
86-
userRequest: contextNormalRequest(compiler, resolved.userRequest),
87-
rawRequest: contextNormalRequest(compiler, resolved.rawRequest),
88-
resource: contextNormalRequest(compiler, resolved.resource),
89-
loaders: resolved.loaders.map(loader =>
90-
Object.assign({}, loader, {
91-
loader: contextNormalPath(compiler, loader.loader),
92-
}),
93-
),
202+
return serialResolveNormal.thaw(resolved, resolved, {
203+
compiler,
94204
});
95205
}
96206

@@ -261,17 +371,8 @@ class ModuleResolverCache {
261371
resource: relateNormalRequest(compiler, resolved.resource),
262372
});
263373
}
264-
return Object.assign({}, resolved, {
265-
context: relateNormalRequest(compiler, resolved.context),
266-
request: relateNormalRequest(compiler, resolved.request),
267-
userRequest: relateNormalRequest(compiler, resolved.userRequest),
268-
rawRequest: relateNormalRequest(compiler, resolved.rawRequest),
269-
resource: relateNormalRequest(compiler, resolved.resource),
270-
loaders: resolved.loaders.map(loader =>
271-
Object.assign({}, loader, {
272-
loader: relateNormalPath(compiler, loader.loader),
273-
}),
274-
),
374+
return serialResolveNormal.freeze(resolved, resolved, {
375+
compiler,
275376
});
276377
}
277378

lib/TransformNormalModuleFactoryPlugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class NormalModuleFactoryPlugin {
131131
parserOptions: request.parser[`${NS}/parser-options`],
132132
type: request.settings && request.settings.type,
133133
settings: request.settings,
134+
resourceResolveData: request.resourceResolveData,
134135
dependencies: null,
135136
});
136137
}

lib/TransformNormalModulePlugin.js

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,28 @@ const serialResolved = serial.created({
2828
// loaders: serial.loaders,
2929
});
3030

31-
const serialResolvedMap = {
32-
freeze(arg, module, extra) {
33-
const resolved = [];
34-
for (const key in arg) {
35-
const thawedKey = JSON.parse(key);
36-
resolved.push([
37-
serialResolveRequest.freeze(thawedKey, thawedKey, extra),
38-
serialResolved.freeze(arg[key], arg[key], extra),
39-
]);
40-
}
41-
return resolved;
31+
const serialJson = {
32+
freeze(arg, value, extra) {
33+
return JSON.parse(arg);
4234
},
4335
thaw(arg, frozen, extra) {
44-
const resolved = {};
45-
for (const item of arg) {
46-
const key = serialResolveRequest.thaw(item[0], item[0], extra);
47-
const value = serialResolved.thaw(item[1], item[1], extra);
48-
resolved[JSON.stringify(key)] = value;
49-
}
50-
return resolved;
36+
return JSON.stringify(arg);
5137
},
5238
};
5339

40+
const serialMap = serial.map;
41+
42+
const serialResolvedMap = serial.map(
43+
serial.pipe(
44+
{ freeze: serialJson.freeze, thaw: serial.identity.thaw },
45+
serialResolveRequest,
46+
{ freeze: serial.identity.freeze, thaw: serialJson.thaw },
47+
),
48+
serialResolved,
49+
);
50+
51+
const serialResourceHashMap = serial.map(serial.request, serial.identity);
52+
5453
const serialNormalModule4 = serial.serial('NormalModule', {
5554
constructor: serial.constructed(NormalModule, {
5655
data: serial.pipe(
@@ -166,6 +165,25 @@ const serialNormalModule4 = serial.serial('NormalModule', {
166165
_lastSuccessfulBuildMeta: serial.identity,
167166

168167
__hardSource_resolved: serialResolvedMap,
168+
__hardSource_oldHashes: serial.pipe(
169+
{
170+
freeze(arg, module, extra) {
171+
const obj = {};
172+
const cachedMd5s = extra.compilation.__hardSourceCachedMd5s;
173+
174+
for (const file of module.buildInfo.fileDependencies) {
175+
obj[file] = cachedMd5s[file];
176+
}
177+
for (const dir of module.buildInfo.contextDependencies) {
178+
obj[dir] = cachedMd5s[dir];
179+
}
180+
181+
return obj;
182+
},
183+
thaw: serial.identity.thaw,
184+
},
185+
serialResourceHashMap,
186+
),
169187
}),
170188

171189
dependencyBlock: serial.dependencyBlock,
@@ -200,7 +218,7 @@ const needRebuild4 = function() {
200218
return true;
201219
}
202220
const fileHashes = this.__hardSourceFileMd5s;
203-
const cachedHashes = this.__hardSourceCachedMd5s;
221+
const cachedHashes = this.__hardSource_oldHashes;
204222
const resolvedLast = this.__hardSource_resolved;
205223
const missingCache = this.__hardSource_missingCache;
206224

@@ -348,6 +366,25 @@ const serialNormalModule3 = serial.serial('NormalModule', {
348366
_source: serial.source,
349367

350368
__hardSource_resolved: serialResolvedMap,
369+
__hardSource_oldHashes: serial.pipe(
370+
{
371+
freeze(arg, module, extra) {
372+
const obj = {};
373+
const cachedMd5s = extra.compilation.__hardSourceCachedMd5s;
374+
375+
for (const file of module.fileDependencies) {
376+
obj[file] = cachedMd5s[file];
377+
}
378+
for (const dir of module.contextDependencies) {
379+
obj[dir] = cachedMd5s[dir];
380+
}
381+
382+
return obj;
383+
},
384+
thaw: serial.identity.thaw,
385+
},
386+
serialResourceHashMap,
387+
),
351388
}),
352389

353390
hash: {
@@ -392,7 +429,7 @@ const needRebuild3 = function() {
392429
return true;
393430
}
394431
const fileHashes = this.__hardSourceFileMd5s;
395-
const cachedHashes = this.__hardSourceCachedMd5s;
432+
const cachedHashes = this.__hardSource_oldHashes;
396433
const resolvedLast = this.__hardSource_resolved;
397434
const missingCache = this.__hardSource_missingCache;
398435

@@ -557,6 +594,7 @@ class TransformNormalModulePlugin {
557594
module.cacheItem.invalid = false;
558595
module.cacheItem.invalidReason = null;
559596
}
597+
560598
const f = serialNormalModule.freeze(
561599
null,
562600
module,

0 commit comments

Comments
 (0)