@@ -14,11 +14,10 @@ const {
1414 Module,
1515 resolveForCJSWithHooks,
1616 clearCJSResolutionCaches,
17- deleteCJSRelativeResolveCacheEntry,
1817} = require ( 'internal/modules/cjs/loader' ) ;
1918const { getFilePathFromFileURL } = require ( 'internal/modules/helpers' ) ;
2019const { fileURLToPath, isURL, URLParse, pathToFileURL } = require ( 'internal/url' ) ;
21- const { emitExperimentalWarning, isWindows } = require ( 'internal/util' ) ;
20+ const { emitExperimentalWarning, kEmptyObject , isWindows } = require ( 'internal/util' ) ;
2221const { validateObject, validateOneOf, validateString } = require ( 'internal/validators' ) ;
2322const {
2423 codes : {
@@ -204,12 +203,12 @@ function isRelative(pathToCheck) {
204203}
205204
206205/**
207- * Clear module resolution and/or module caches.
206+ * Clear module resolution and module caches.
208207 * @param {string|URL } specifier What would've been passed into import() or require().
209208 * @param {{
210209 * parentURL: string|URL,
210+ * importAttributes?: Record<string, string>,
211211 * resolver: 'import'|'require',
212- * caches: 'resolution'|'module'|'all',
213212 * }} options
214213 */
215214function clearCache ( specifier , options ) {
@@ -223,89 +222,65 @@ function clearCache(specifier, options) {
223222 validateObject ( options , 'options' ) ;
224223 const { parentURL, parentPath } = normalizeClearCacheParent ( options . parentURL ) ;
225224
226- const { resolver, caches } = options ;
225+ const { resolver } = options ;
227226 validateOneOf ( resolver , 'options.resolver' , [ 'import' , 'require' ] ) ;
228- validateOneOf ( caches , 'options.caches' , [ 'resolution' , 'module' , 'all' ] ) ;
229227
230- const clearResolution = caches === 'resolution' || caches === 'all' ;
231- const clearModule = caches === 'module' || caches === 'all' ;
228+ const importAttributes = options . importAttributes ?? kEmptyObject ;
229+ if ( options . importAttributes !== undefined ) {
230+ validateObject ( options . importAttributes , 'options.importAttributes' ) ;
231+ }
232232
233- // Resolve the specifier when module or resolution cache clearing is needed.
234- // Must be done BEFORE clearing resolution caches since resolution
235- // may rely on the resolve cache.
233+ // Resolve before clearing so resolution-cache entries are still available.
236234 let resolvedFilename = null ;
237235 let resolvedURL = null ;
238236
239- if ( clearModule || clearResolution ) {
240- if ( resolver === 'require' ) {
241- resolvedFilename = resolveClearCacheFilename ( specifier , parentPath ) ;
242- if ( resolvedFilename ) {
243- resolvedURL = pathToFileURL ( resolvedFilename ) . href ;
244- }
245- } else {
246- resolvedURL = resolveClearCacheURL ( specifier , parentURL ) ;
247- if ( resolvedURL ) {
248- resolvedFilename = getFilePathFromFileURL ( resolvedURL ) ;
249- }
237+ if ( resolver === 'require' ) {
238+ resolvedFilename = resolveClearCacheFilename ( specifier , parentPath ) ;
239+ if ( resolvedFilename ) {
240+ resolvedURL = pathToFileURL ( resolvedFilename ) . href ;
250241 }
251- }
252-
253- // Clear resolution caches.
254- if ( clearResolution ) {
255- // ESM has a structured resolution cache keyed by (specifier, parentURL,
256- // importAttributes). Clear all attribute variants for the given
257- // (specifier, parentURL) pair since attributes don't affect resolution
258- // per spec and it avoids partial-clear surprises.
259- if ( resolver === 'import' ) {
260- const specifierStr = isSpecifierURL ? specifier . href : specifier ;
261- const cascadedLoader =
262- require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
263- cascadedLoader . deleteAllResolveCacheEntries ( specifierStr , parentURL ) ;
242+ } else {
243+ resolvedURL = resolveClearCacheURL ( specifier , parentURL ) ;
244+ if ( resolvedURL ) {
245+ resolvedFilename = getFilePathFromFileURL ( resolvedURL ) ;
264246 }
247+ }
265248
266- // CJS resolution caches are only relevant when the resolver is 'require'.
267- if ( resolver === 'require' && parentPath ) {
268- // Delete the specific relativeResolveCache entry for this
269- // (parent-dir, request) pair. More targeted than a full value-scan.
270- const requestStr = isSpecifierURL ? specifier . href : specifier ;
271- deleteCJSRelativeResolveCacheEntry ( path . dirname ( parentPath ) , requestStr ) ;
249+ // ESM resolution cache entries are keyed by
250+ // (specifier, parentURL, importAttributes).
251+ if ( resolver === 'import' ) {
252+ const specifierStr = isSpecifierURL ? specifier . href : specifier ;
253+ const cascadedLoader =
254+ require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
255+ cascadedLoader . deleteResolveCacheEntry ( specifierStr , parentURL , importAttributes ) ;
256+ }
272257
273- // Clear package.json caches for the resolved module's package so that
274- // updated exports/imports conditions are picked up on re-resolution.
275- if ( resolvedFilename ) {
276- const { getNearestParentPackageJSON, clearPackageJSONCache } =
277- require ( 'internal/modules/package_json_reader' ) ;
278- const pkg = getNearestParentPackageJSON ( resolvedFilename ) ;
279- if ( pkg ?. path ) {
280- clearPackageJSONCache ( pkg . path ) ;
281- }
282- }
258+ if ( resolver === 'require' && resolvedFilename ) {
259+ const { getNearestParentPackageJSON, clearPackageJSONCache } =
260+ require ( 'internal/modules/package_json_reader' ) ;
261+ const pkg = getNearestParentPackageJSON ( resolvedFilename ) ;
262+ if ( pkg ?. path ) {
263+ clearPackageJSONCache ( pkg . path ) ;
283264 }
284265 }
285266
286267 // Clear module caches everywhere in Node.js.
287- if ( clearModule ) {
288- // CJS Module._cache
289- if ( resolvedFilename ) {
290- const cachedModule = Module . _cache [ resolvedFilename ] ;
291- if ( cachedModule !== undefined ) {
292- delete Module . _cache [ resolvedFilename ] ;
293- deleteModuleFromParents ( cachedModule ) ;
294- }
295- // Also clear CJS resolution caches that point to this filename,
296- // even if only 'module' was requested, to avoid stale resolution
297- // results pointing to a purged module.
298- clearCJSResolutionCaches ( resolvedFilename ) ;
268+ if ( resolvedFilename ) {
269+ const cachedModule = Module . _cache [ resolvedFilename ] ;
270+ if ( cachedModule !== undefined ) {
271+ delete Module . _cache [ resolvedFilename ] ;
272+ deleteModuleFromParents ( cachedModule ) ;
299273 }
274+ // Also clear CJS resolution caches that point to this filename.
275+ clearCJSResolutionCaches ( resolvedFilename ) ;
276+ }
300277
301- // ESM load cache and translators cjsCache
302- if ( resolvedURL ) {
303- const cascadedLoader =
304- require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
305- deleteLoadCacheEntries ( cascadedLoader . loadCache , resolvedURL ) ;
306- const { clearCjsCache } = require ( 'internal/modules/esm/translators' ) ;
307- clearCjsCache ( resolvedURL ) ;
308- }
278+ if ( resolvedURL ) {
279+ const cascadedLoader =
280+ require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
281+ deleteLoadCacheEntries ( cascadedLoader . loadCache , resolvedURL ) ;
282+ const { clearCjsCache } = require ( 'internal/modules/esm/translators' ) ;
283+ clearCjsCache ( resolvedURL ) ;
309284 }
310285}
311286
0 commit comments