@@ -75,50 +75,62 @@ added: REPLACEME
7575> Stability: 1.0 - Early development
7676
7777* ` specifier` {string|URL} The module specifier, as it would have been passed to
78- ` import ()` or ` require ()` .
79- * ` options` {Object}
80- * ` parentURL` {string|URL} The parent URL used to resolve the specifier. Parent identity
81- is part of the resolution cache key. For CommonJS, pass ` pathToFileURL (__filename )` .
82- For ES modules, pass ` import .meta.url` .
83- * ` resolver` {string} Specifies how resolution should be performed. Must be either
84- ` ' import' ` or ` ' require' ` .
78+ ` import ()` or ` require ()` . When ` resolver` is ` ' require' ` , this must be a
79+ string (the same kind of path or identifier ` require ()` accepts). Passing a
80+ ` URL ` object with ` resolver: ' require' ` throws ` ERR_INVALID_ARG_TYPE ` .
81+ * ` options` {Object} Required.
82+ * ` parentURL` {string|URL} Required. The parent URL used to resolve the
83+ specifier. Parent identity is part of the resolution cache key. For
84+ CommonJS, pass ` pathToFileURL (__filename )` . For ES modules, pass
85+ ` import .meta.url` .
86+ * ` resolver` {string} Required. How resolution should be performed. Must be
87+ either ` ' import' ` or ` ' require' ` .
8588 * ` importAttributes` {Object} Optional import attributes. Only meaningful when
8689 ` resolver` is ` ' import' ` .
8790
8891Clears the module resolution and module caches for a module. This enables
89- reload patterns similar to deleting from ` require.cache` in CommonJS, and is useful for
90- hot module reload.
91-
92- The specifier is resolved using the chosen ` resolver` , then the resolved module is removed
93- from all internal caches (CommonJS ` require` cache, CommonJS resolution caches, ESM resolve
94- cache, ESM load cache, and ESM translators cache). When ` resolver` is ` ' import' ` ,
95- ` importAttributes` are part of the ESM resolve-cache key, so only the exact
96- ` (specifier, parentURL, importAttributes)` resolution entry is removed. When a ` file:` URL is
97- resolved, cached module jobs for the same file path are cleared even if they differ by search
98- or hash. This means clearing ` ' ./mod.mjs?v=1' ` will also clear ` ' ./mod.mjs?v=2' ` and any
92+ reload patterns similar to deleting from ` require.cache` in CommonJS, and is
93+ useful for hot module reload.
94+
95+ Both ` options.parentURL` and ` options.resolver` are required. There is no
96+ recursive option: ` clearCache` invalidates only the resolved module, not its
97+ dependencies. Callers that need to reload a graph must track and clear each
98+ module themselves.
99+
100+ The specifier is resolved using the chosen ` resolver` , then the resolved module
101+ is removed from all Node.js internal caches (CommonJS ` require` cache, CommonJS
102+ resolution caches, ESM resolve cache, ESM load cache, and ESM translators
103+ cache). When ` resolver` is ` ' import' ` , ` importAttributes` are part of the ESM
104+ resolve-cache key, so only the exact ` (specifier, parentURL, importAttributes)`
105+ resolution entry is removed. When a ` file:` URL is resolved, cached module jobs
106+ for the same file path are cleared even if they differ by search or hash. This
107+ means clearing ` ' ./mod.mjs?v=1' ` will also clear ` ' ./mod.mjs?v=2' ` and any
99108other query/hash variants that resolve to the same file.
100109
101- When ` resolver` is ` ' require' ` , cached ` package.json` data for the resolved module's package
102- is also cleared so that updated exports/imports conditions are picked up on the next
103- resolution.
110+ When ` resolver` is ` ' require' ` , cached ` package.json` data for the resolved
111+ module's package is also cleared so that updated exports/imports conditions are
112+ picked up on the next resolution.
104113
105114Clearing a module does not clear cached entries for its dependencies. When using
106- ` resolver: ' import' ` , resolution cache entries for other specifiers that resolve to the
107- same target are not cleared — only the exact ` (specifier, parentURL, importAttributes)`
108- entry is removed. The module cache itself is cleared by resolved file path, so all
109- specifiers pointing to the same file will see a fresh execution on next import.
115+ ` resolver: ' import' ` , resolution cache entries for other specifiers that resolve
116+ to the same target are not cleared — only the exact
117+ ` (specifier, parentURL, importAttributes)` entry is removed. The module cache
118+ itself is cleared by resolved file path, so all specifiers pointing to the same
119+ file will see a fresh execution on next import.
110120
111121#### Memory retention and static imports
112122
113- ` clearCache ` only removes references from the Node.js **JavaScript-level** caches
114- (the ESM load cache, resolve cache, CJS ` require.cache` , and related structures).
115- It does **not** affect V8-internal module graph references.
123+ ` clearCache ` only removes references from the Node.js internal caches (the ESM
124+ load cache, resolve cache, CJS ` require.cache` , and related structures). It does
125+ **not** affect references created by user modules, for example through a static
126+ ` import` . If one module imports another, ` clearCache` will not clean up that
127+ link. It only clears references from Node.js internal caches to user modules.
116128
117- When a module M is **statically imported** by a live parent module P
118- (i.e., via a top-level ` import … from ' …' ` statement that has already been
119- evaluated), V8's module instantiation creates a permanent internal strong
120- reference from P's compiled module record to M's module record. Calling
121- ` clearCache(M) ` cannot sever that link. Consequences:
129+ When a module M is **statically imported** by a live parent module P (via a
130+ top-level ` import … from ' …' ` statement that has already been evaluated), the
131+ engine keeps a permanent internal strong reference from P's compiled module
132+ record to M's module record. Calling ` clearCache(M) ` cannot sever that link.
133+ Consequences:
122134
123135* The old instance of M **stays alive in memory** for as long as P is alive,
124136 regardless of how many times M is cleared and re-imported.
@@ -130,12 +142,13 @@ reference from P's compiled module record to M's module record. Calling
130142 cycles.
131143
132144For **dynamically imported** modules (` await import(' ./M.mjs' )` with no live
133- static parent holding the result), the old ` ModuleWrap ` becomes eligible for
145+ static parent holding the result), the old module becomes eligible for
134146garbage collection once ` clearCache ` removes it from Node.js caches and all
135- JS-land references (e.g. , stored namespace objects) are dropped.
147+ JavaScript references (for example , stored namespace objects) are dropped.
136148
137149The safest pattern for hot-reload of ES modules is to use cache-busting search
138- parameters (so each version is a distinct module URL) and use dynamic imports for modules that need to be reloaded:
150+ parameters (so each version is a distinct module URL) and use dynamic imports
151+ for modules that need to be reloaded:
139152
140153#### ECMA-262 spec considerations
141154
@@ -169,11 +182,14 @@ watch(base, async () => {
169182
170183#### Examples
171184
185+ Relative specifiers are resolved against ` parentURL` , not against the process
186+ working directory:
187+
172188` ` ` mjs
173189import { clearCache } from ' node:module' ;
174190
191+ // Resolves to the `mod.mjs` sibling of *this* module, then clears it.
175192await import (' ./mod.mjs' );
176-
177193clearCache (' ./mod.mjs' , {
178194 parentURL: import .meta.url,
179195 resolver: ' import' ,
@@ -195,6 +211,56 @@ require('./mod.js'); // eslint-disable-line node-core/no-duplicate-requires
195211// re-executes the module
196212` ` `
197213
214+ Bare specifiers are resolved the same way ` import ` /` require` would resolve them
215+ from ` parentURL` (including ` node_modules` lookup and ` package.json` ` " exports" ` ):
216+
217+ ` ` ` mjs
218+ import { clearCache } from ' node:module' ;
219+
220+ await import (' some-package' );
221+ clearCache (' some-package' , {
222+ parentURL: import .meta.url,
223+ resolver: ' import' ,
224+ });
225+ await import (' some-package' ); // re-executes the package entry point
226+ ` ` `
227+
228+ An absolute ` file: ` URL still requires ` parentURL` and ` resolver` . The URL is
229+ the cache key; ` parentURL` is used if the loader needs to resolve it again
230+ (for example, through customization hooks):
231+
232+ ` ` ` mjs
233+ import { clearCache } from ' node:module' ;
234+
235+ const url = new URL (' ./mod.mjs' , import .meta.url);
236+ await import (url);
237+ clearCache (url, {
238+ parentURL: import .meta.url,
239+ resolver: ' import' ,
240+ });
241+ await import (url); // re-executes the module
242+ ` ` `
243+
244+ Reloading a CommonJS module between tests (the ESM equivalent should use
245+ cache-busting search parameters; see [ECMA-262 spec considerations][]):
246+
247+ ` ` ` cjs
248+ const { clearCache } = require (' node:module' );
249+ const { pathToFileURL } = require (' node:url' );
250+
251+ function loadFresh () {
252+ clearCache (' ./app.js' , {
253+ parentURL: pathToFileURL (__filename ),
254+ resolver: ' require' ,
255+ });
256+ return require (' ./app.js' ); // eslint-disable-line node-core/no-duplicate-requires
257+ }
258+
259+ const first = loadFresh ();
260+ const second = loadFresh ();
261+ // `first` and `second` are independently evaluated copies.
262+ ` ` `
263+
198264### ` module .findPackageJSON (specifier[, base])`
199265
200266<!-- YAML
@@ -2173,6 +2239,7 @@ returned object contains the following keys:
21732239* ` columnNumber` {number} The 1-indexed columnNumber of the
21742240 corresponding call site in the original source
21752241
2242+ [ECMA-262 spec considerations]: #ecma-262-spec-considerations
21762243[CommonJS]: modules.md
21772244[Conditional exports]: packages.md#conditional-exports
21782245[Customization hooks]: #customization-hooks
0 commit comments