Skip to content

Commit

Permalink
feat: support resource data sideEffects: false (#403)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mzgoddard authored Jul 7, 2018
1 parent 236b8a5 commit a5c5d33
Show file tree
Hide file tree
Showing 27 changed files with 448 additions and 56 deletions.
30 changes: 23 additions & 7 deletions lib/CacheEnhancedResolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,25 @@ const nodeObjectHash = require('node-object-hash');
const pluginCompat = require('./util/plugin-compat');
const promisify = require('./util/promisify');
const relateContext = require('./util/relate-context');
const serial = require('./util/serial');
const values = require('./util/Object.values');
const bulkFsTask = require('./util/bulk-fs-task');
const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');
const parseJson = require('./util/parseJson');

const serialNormalResolved = serial.created({
result: serial.path,
resourceResolveData: serial.objectAssign({
context: serial.created({
issuer: serial.request,
resolveOptions: serial.identity,
}),
path: serial.path,
descriptionFilePath: serial.path,
descriptionFileRoot: serial.path,
}),
});

class EnhancedResolveCache {
apply(compiler) {
let missingCacheSerializer;
Expand Down Expand Up @@ -106,8 +120,8 @@ class EnhancedResolveCache {
}

function contextNormalResolved(compiler, resolved) {
return Object.assign({}, resolved, {
result: contextNormalPath(compiler, resolved.result),
return serialNormalResolved.thaw(resolved, resolved, {
compiler,
});
}

Expand Down Expand Up @@ -267,14 +281,15 @@ class EnhancedResolveCache {
return cb(
null,
[resolve.result].concat(request.split('?').slice(1)).join('?'),
resolve.resourceResolveData,
);
} else {
resolve.invalid = true;
resolve.invalidReason = 'out of date';
}
}
let localMissing = [];
const callback = (err, result) => {
const callback = (err, result, result2) => {
if (result) {
const inverseId = JSON.stringify([context, result.split('?')[0]]);
const resolveId = JSON.stringify([context, request]);
Expand All @@ -293,7 +308,7 @@ class EnhancedResolveCache {
// recorded and we get a new empty array of missing, keep the old
// value.
if (localMissing.length === 0 && missingCache[key][inverseId]) {
return cb(err, result);
return cb(err, result, result2);
}

missingCache[key][inverseId] = localMissing
Expand All @@ -311,10 +326,11 @@ class EnhancedResolveCache {
missingCache[key][inverseId].new = true;
resolverCache[key][resolveId] = {
result: result.split('?')[0],
resourceResolveData: result2,
new: true,
};
}
cb(err, result);
cb(err, result, result2);
};
const _missing =
cb.missing || (resolveContext && resolveContext.missing);
Expand Down Expand Up @@ -459,8 +475,8 @@ class EnhancedResolveCache {
}

function relateNormalResolved(compiler, resolved) {
return Object.assign({}, resolved, {
result: relateNormalPath(compiler, resolved.result),
return serialNormalResolved.freeze(resolved, resolved, {
compiler,
});
}

Expand Down
145 changes: 123 additions & 22 deletions lib/CacheModuleResolver.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,129 @@
const nodeObjectHash = require('node-object-hash');

const serial = require('./util/serial');
const pluginCompat = require('./util/plugin-compat');
const relateContext = require('./util/relate-context');
const parseJson = require('./util/parseJson');
const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');

const serialJsonKey = {
freeze(arg, value, extra) {
return JSON.parse(arg);
},
thaw(arg, frozen, extra) {
return JSON.stringify(arg);
},
};

const serialJson = {
freeze(arg, value, extra) {
return JSON.stringify(arg);
},
thaw(arg, frozen, extra) {
return JSON.parse(arg);
},
};

const serialObjectAssign = serial.objectAssign;

const serialResolveOptionsKey = serialObjectAssign({
context: serial.path,
userRequest: serial.request,
options: serialObjectAssign({
request: serial.request,
}),
});

const serialResolveKey = serialObjectAssign({
context: serial.path,
request: serial.request,
});

const serialNormalModuleResolveKey = serial.pipe(
serialJsonKey,
{
freeze(arg, key, extra) {
if (Array.isArray(arg)) {
return [
arg[0],
serial.path.freeze(arg[1], arg[1], extra),
serial.request.freeze(arg[2], arg[2], extra),
];
} else if (!arg.request) {
return serialResolveOptionsKey.freeze(arg, arg, extra);
} else {
return serialResolveKey.freeze(arg, arg, extra);
}
},
thaw(arg, frozen, extra) {
if (Array.isArray(arg)) {
return [
arg[0],
serial.path.thaw(arg[1], arg[1], extra),
serial.request.thaw(arg[2], arg[2], extra),
];
} else if (!arg.request) {
return serialResolveOptionsKey.thaw(arg, arg, extra);
} else {
return serialResolveKey.thaw(arg, arg, extra);
}
},
},
serialJson,
);

const serialNormalModuleId = {
freeze(arg, module, extra) {
return (
id.substring(0, 24) + serial.request.freeze(id.substring(24), id, extra)
);
},
thaw(arg, frozen, extra) {
return (
id.substring(0, 24) + serial.request.thaw(id.substring(24), id, extra)
);
},
};

const serialResolveContext = serialObjectAssign({
identifier: serialNormalModuleId,
resource: serialNormalModuleId,
});

const serialResolveNormal = serialObjectAssign({
context: serial.path,
request: serial.request,
userRequest: serial.request,
rawRequest: serial.request,
resource: serial.request,
loaders: serial.loaders,
resourceResolveData: serial.objectAssign({
context: serial.created({
issuer: serial.request,
resolveOptions: serial.identity,
}),
path: serial.path,
request: serial.request,
descriptionFilePath: serial.path,
descriptionFileRoot: serial.path,
}),
});

const serialResolve = {
freeze(arg, module, extra) {
if (arg.type === 'context') {
return serialResolveContext.freeze(arg, arg, extra);
}
return serialResolveNormal.freeze(arg, arg, extra);
},
thaw(arg, frozen, extra) {
if (arg.type === 'context') {
return serialResolveContext.thaw(arg, arg, extra);
}
return serialResolveNormal.thaw(arg, arg, extra);
},
};

class ModuleResolverCache {
apply(compiler) {
let moduleResolveCache = {};
Expand Down Expand Up @@ -80,17 +199,8 @@ class ModuleResolverCache {
resource: contextNormalRequest(compiler, resolved.resource),
});
}
return Object.assign({}, resolved, {
context: contextNormalRequest(compiler, resolved.context),
request: contextNormalRequest(compiler, resolved.request),
userRequest: contextNormalRequest(compiler, resolved.userRequest),
rawRequest: contextNormalRequest(compiler, resolved.rawRequest),
resource: contextNormalRequest(compiler, resolved.resource),
loaders: resolved.loaders.map(loader =>
Object.assign({}, loader, {
loader: contextNormalPath(compiler, loader.loader),
}),
),
return serialResolveNormal.thaw(resolved, resolved, {
compiler,
});
}

Expand Down Expand Up @@ -261,17 +371,8 @@ class ModuleResolverCache {
resource: relateNormalRequest(compiler, resolved.resource),
});
}
return Object.assign({}, resolved, {
context: relateNormalRequest(compiler, resolved.context),
request: relateNormalRequest(compiler, resolved.request),
userRequest: relateNormalRequest(compiler, resolved.userRequest),
rawRequest: relateNormalRequest(compiler, resolved.rawRequest),
resource: relateNormalRequest(compiler, resolved.resource),
loaders: resolved.loaders.map(loader =>
Object.assign({}, loader, {
loader: relateNormalPath(compiler, loader.loader),
}),
),
return serialResolveNormal.freeze(resolved, resolved, {
compiler,
});
}

Expand Down
1 change: 1 addition & 0 deletions lib/TransformNormalModuleFactoryPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class NormalModuleFactoryPlugin {
parserOptions: request.parser[`${NS}/parser-options`],
type: request.settings && request.settings.type,
settings: request.settings,
resourceResolveData: request.resourceResolveData,
dependencies: null,
});
}
Expand Down
78 changes: 58 additions & 20 deletions lib/TransformNormalModulePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,28 @@ const serialResolved = serial.created({
// loaders: serial.loaders,
});

const serialResolvedMap = {
freeze(arg, module, extra) {
const resolved = [];
for (const key in arg) {
const thawedKey = JSON.parse(key);
resolved.push([
serialResolveRequest.freeze(thawedKey, thawedKey, extra),
serialResolved.freeze(arg[key], arg[key], extra),
]);
}
return resolved;
const serialJson = {
freeze(arg, value, extra) {
return JSON.parse(arg);
},
thaw(arg, frozen, extra) {
const resolved = {};
for (const item of arg) {
const key = serialResolveRequest.thaw(item[0], item[0], extra);
const value = serialResolved.thaw(item[1], item[1], extra);
resolved[JSON.stringify(key)] = value;
}
return resolved;
return JSON.stringify(arg);
},
};

const serialMap = serial.map;

const serialResolvedMap = serial.map(
serial.pipe(
{ freeze: serialJson.freeze, thaw: serial.identity.thaw },
serialResolveRequest,
{ freeze: serial.identity.freeze, thaw: serialJson.thaw },
),
serialResolved,
);

const serialResourceHashMap = serial.map(serial.request, serial.identity);

const serialNormalModule4 = serial.serial('NormalModule', {
constructor: serial.constructed(NormalModule, {
data: serial.pipe(
Expand Down Expand Up @@ -166,6 +165,25 @@ const serialNormalModule4 = serial.serial('NormalModule', {
_lastSuccessfulBuildMeta: serial.identity,

__hardSource_resolved: serialResolvedMap,
__hardSource_oldHashes: serial.pipe(
{
freeze(arg, module, extra) {
const obj = {};
const cachedMd5s = extra.compilation.__hardSourceCachedMd5s;

for (const file of module.buildInfo.fileDependencies) {
obj[file] = cachedMd5s[file];
}
for (const dir of module.buildInfo.contextDependencies) {
obj[dir] = cachedMd5s[dir];
}

return obj;
},
thaw: serial.identity.thaw,
},
serialResourceHashMap,
),
}),

dependencyBlock: serial.dependencyBlock,
Expand Down Expand Up @@ -200,7 +218,7 @@ const needRebuild4 = function() {
return true;
}
const fileHashes = this.__hardSourceFileMd5s;
const cachedHashes = this.__hardSourceCachedMd5s;
const cachedHashes = this.__hardSource_oldHashes;
const resolvedLast = this.__hardSource_resolved;
const missingCache = this.__hardSource_missingCache;

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

__hardSource_resolved: serialResolvedMap,
__hardSource_oldHashes: serial.pipe(
{
freeze(arg, module, extra) {
const obj = {};
const cachedMd5s = extra.compilation.__hardSourceCachedMd5s;

for (const file of module.fileDependencies) {
obj[file] = cachedMd5s[file];
}
for (const dir of module.contextDependencies) {
obj[dir] = cachedMd5s[dir];
}

return obj;
},
thaw: serial.identity.thaw,
},
serialResourceHashMap,
),
}),

hash: {
Expand Down Expand Up @@ -392,7 +429,7 @@ const needRebuild3 = function() {
return true;
}
const fileHashes = this.__hardSourceFileMd5s;
const cachedHashes = this.__hardSourceCachedMd5s;
const cachedHashes = this.__hardSource_oldHashes;
const resolvedLast = this.__hardSource_resolved;
const missingCache = this.__hardSource_missingCache;

Expand Down Expand Up @@ -557,6 +594,7 @@ class TransformNormalModulePlugin {
module.cacheItem.invalid = false;
module.cacheItem.invalidReason = null;
}

const f = serialNormalModule.freeze(
null,
module,
Expand Down
Loading

0 comments on commit a5c5d33

Please sign in to comment.