Skip to content

Commit be1f4a5

Browse files
committed
fixup! module: add clearCache for CJS and ESM
1 parent ddde84e commit be1f4a5

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ module.exports = {
122122
initializeCJS,
123123
Module,
124124
clearCJSResolutionCaches,
125-
relativeResolveCache,
126125
findLongestRegisteredExtension,
127126
resolveForCJSWithHooks,
128127
loadSourceForCJSWithHooks: loadSource,

lib/internal/modules/clear.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const {
1414
Module,
1515
resolveForCJSWithHooks,
1616
clearCJSResolutionCaches,
17-
relativeResolveCache,
1817
} = require('internal/modules/cjs/loader');
1918
const { fileURLToPath, isURL, URLParse, pathToFileURL } = require('internal/url');
2019
const { emitExperimentalWarning, kEmptyObject, isWindows } = require('internal/util');
@@ -76,20 +75,37 @@ function createParentModuleForClearCache(parentPath) {
7675
/**
7776
* Resolve a cache filename for CommonJS.
7877
* Always goes through resolveForCJSWithHooks so that registered hooks
79-
* are respected. CJS operates on file paths and bare specifiers; URL
80-
* objects are not valid require() arguments so they are not supported.
81-
* @param {string} specifier
78+
* are respected. CJS operates on file paths and bare specifiers. file:
79+
* URL objects or strings are converted to paths; non-file URLs are not
80+
* supported and will return null.
81+
* @param {string|URL} specifier
8282
* @param {string|undefined} parentPath
8383
* @returns {string|null}
8484
*/
8585
function resolveClearCacheFilename(specifier, parentPath) {
86-
if (!parentPath && typeof specifier === 'string' && isRelative(specifier)) {
86+
let request;
87+
if (isURL(specifier)) {
88+
if (specifier.protocol !== 'file:') {
89+
return null;
90+
}
91+
request = fileURLToPath(specifier);
92+
} else if (typeof specifier === 'string' && StringPrototypeStartsWith(specifier, 'file:')) {
93+
const parsed = URLParse(specifier);
94+
if (!parsed || parsed.protocol !== 'file:') {
95+
return null;
96+
}
97+
request = fileURLToPath(parsed);
98+
} else {
99+
request = specifier;
100+
}
101+
102+
if (!parentPath && isRelative(request)) {
87103
return null;
88104
}
89105

90106
const parent = parentPath ? createParentModuleForClearCache(parentPath) : null;
91107
try {
92-
const { filename, format } = resolveForCJSWithHooks(specifier, parent, false, false);
108+
const { filename, format } = resolveForCJSWithHooks(request, parent, false, false);
93109
if (format === 'builtin') {
94110
return null;
95111
}
@@ -284,10 +300,11 @@ function clearCache(specifier, options) {
284300
}
285301

286302
// CJS has relativeResolveCache and Module._pathCache that map
287-
// specifiers to filenames. Only clear the exact entry for this request.
288-
if (resolver === 'require') {
289-
const request = isSpecifierURL ? specifier.href : specifier;
290-
delete relativeResolveCache[`${parentPath}\x00${request}`];
303+
// specifiers to filenames. Clear all entries pointing to the resolved
304+
// file. Module._pathCache keys are not easily reconstructable so a
305+
// value-scan is required.
306+
if (resolver === 'require' && resolvedFilename) {
307+
clearCJSResolutionCaches(resolvedFilename);
291308
}
292309

293310
if (resolvedFilename) {

0 commit comments

Comments
 (0)