Skip to content

Commit 9137c56

Browse files
committed
module: add extra caching layer
This adds an extra modules caching layer that operates on the parent's `path` property and the current require argument. That together can be used as unique identifier to speed up loading the same module more than once. It is a cache on top of the current modules cache. It has the nice feature that this cache does not only work in the same file but it works for the whole current directory. So if the same file is loaded in any other file from the same directory, it will also hit this cache instead of having to resolve the file again. To keep it backwards compatible with the old modules cache, it detects invalidation of that cache.
1 parent 538f745 commit 9137c56

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

lib/internal/modules/cjs/loader.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ const {
8585

8686
const isWindows = process.platform === 'win32';
8787

88+
const relativeResolveCache = Object.create(null);
89+
8890
let requireDepth = 0;
8991
let statCache = new Map();
9092
function stat(filename) {
@@ -598,14 +600,28 @@ Module._resolveLookupPaths = function(request, parent, newReturn) {
598600
// Then have it load the file contents before returning its exports
599601
// object.
600602
Module._load = function(request, parent, isMain) {
603+
let relResolveCacheIdentifier;
601604
if (parent) {
602605
debug('Module._load REQUEST %s parent: %s', request, parent.id);
606+
// Fast path for (lazy loaded) modules in the same directory. The indirect
607+
// caching is required to allow cache invalidation without changing the old
608+
// cache key names.
609+
relResolveCacheIdentifier = `${parent.path}\x00${request}`;
610+
const filename = relativeResolveCache[relResolveCacheIdentifier];
611+
if (filename !== undefined) {
612+
const cachedModule = Module._cache[filename];
613+
if (cachedModule !== undefined) {
614+
updateChildren(parent, cachedModule, true);
615+
return cachedModule.exports;
616+
}
617+
delete relativeResolveCache[relResolveCacheIdentifier];
618+
}
603619
}
604620

605621
const filename = Module._resolveFilename(request, parent, isMain);
606622

607623
const cachedModule = Module._cache[filename];
608-
if (cachedModule) {
624+
if (cachedModule !== undefined) {
609625
updateChildren(parent, cachedModule, true);
610626
return cachedModule.exports;
611627
}
@@ -625,6 +641,9 @@ Module._load = function(request, parent, isMain) {
625641
}
626642

627643
Module._cache[filename] = module;
644+
if (parent !== undefined) {
645+
relativeResolveCache[relResolveCacheIdentifier] = filename;
646+
}
628647

629648
let threw = true;
630649
try {
@@ -633,6 +652,9 @@ Module._load = function(request, parent, isMain) {
633652
} finally {
634653
if (threw) {
635654
delete Module._cache[filename];
655+
if (parent !== undefined) {
656+
delete relativeResolveCache[relResolveCacheIdentifier];
657+
}
636658
}
637659
}
638660

0 commit comments

Comments
 (0)