@@ -44,7 +44,7 @@ const {
4444 loadSourceForCJSWithHooks,
4545 populateCJSExportsFromESM,
4646} = require ( 'internal/modules/cjs/loader' ) ;
47- const { fileURLToPath, pathToFileURL, URL } = require ( 'internal/url' ) ;
47+ const { fileURLToPath, pathToFileURL, URL , URLParse } = require ( 'internal/url' ) ;
4848let debug = require ( 'internal/util/debuglog' ) . debuglog ( 'esm' , ( fn ) => {
4949 debug = fn ;
5050} ) ;
@@ -184,6 +184,64 @@ function loadCJSModule(module, source, url, filename, isMain) {
184184// TODO: can we use a weak map instead?
185185const cjsCache = new SafeMap ( ) ;
186186
187+ /**
188+ * Resolve a file path for a file URL, stripping search/hash.
189+ * @param {string } url
190+ * @returns {string|null }
191+ */
192+ function getFilePathFromCjsCacheURL ( url ) {
193+ const parsedURL = URLParse ( url ) ;
194+ if ( ! parsedURL ) {
195+ return null ;
196+ }
197+ if ( parsedURL . protocol !== 'file:' ) {
198+ return null ;
199+ }
200+ if ( parsedURL . search !== '' || parsedURL . hash !== '' ) {
201+ parsedURL . search = '' ;
202+ parsedURL . hash = '' ;
203+ }
204+ try {
205+ return fileURLToPath ( parsedURL ) ;
206+ } catch {
207+ return null ;
208+ }
209+ }
210+
211+ /**
212+ * Remove cjsCache entries for a URL and its file-path variants.
213+ * @param {string } url
214+ * @returns {boolean } true if any entries were deleted.
215+ */
216+ function clearCjsCache ( url ) {
217+ let deleted = cjsCache . delete ( url ) ;
218+ const filename = getFilePathFromCjsCacheURL ( url ) ;
219+ if ( ! filename ) {
220+ return deleted ;
221+ }
222+
223+ const urls = [ ] ;
224+ for ( const entry of cjsCache ) {
225+ ArrayPrototypePush ( urls , entry [ 0 ] ) ;
226+ }
227+
228+ for ( let i = 0 ; i < urls . length ; i ++ ) {
229+ const cachedURL = urls [ i ] ;
230+ if ( cachedURL === url ) {
231+ continue ;
232+ }
233+ const cachedFilename = getFilePathFromCjsCacheURL ( cachedURL ) ;
234+ if ( cachedFilename === filename ) {
235+ cjsCache . delete ( cachedURL ) ;
236+ deleted = true ;
237+ }
238+ }
239+
240+ return deleted ;
241+ }
242+
243+ exports . clearCjsCache = clearCjsCache ;
244+
187245/**
188246 * Creates a ModuleWrap object for a CommonJS module.
189247 * @param {string } url - The URL of the module.
@@ -314,7 +372,9 @@ translators.set('require-commonjs-typescript', (url, translateContext, parentURL
314372
315373// This goes through Module._load to accommodate monkey-patchers.
316374function loadCJSModuleWithModuleLoad ( module , source , url , filename , isMain ) {
317- assert ( module === CJSModule . _cache [ filename ] ) ;
375+ if ( CJSModule . _cache [ filename ] !== module ) {
376+ CJSModule . _cache [ filename ] = module ;
377+ }
318378 // If it gets here in the translators, the hooks must have already been invoked
319379 // in the loader. Skip them in the synthetic module evaluation step.
320380 wrapModuleLoad ( filename , undefined , isMain , kShouldSkipModuleHooks ) ;
0 commit comments