@@ -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} ) ;
@@ -193,6 +193,64 @@ function loadCJSModule(module, source, url, filename, isMain) {
193193// TODO: can we use a weak map instead?
194194const cjsCache = new SafeMap ( ) ;
195195
196+ /**
197+ * Resolve a file path for a file URL, stripping search/hash.
198+ * @param {string } url
199+ * @returns {string|null }
200+ */
201+ function getFilePathFromCjsCacheURL ( url ) {
202+ const parsedURL = URLParse ( url ) ;
203+ if ( ! parsedURL ) {
204+ return null ;
205+ }
206+ if ( parsedURL . protocol !== 'file:' ) {
207+ return null ;
208+ }
209+ if ( parsedURL . search !== '' || parsedURL . hash !== '' ) {
210+ parsedURL . search = '' ;
211+ parsedURL . hash = '' ;
212+ }
213+ try {
214+ return fileURLToPath ( parsedURL ) ;
215+ } catch {
216+ return null ;
217+ }
218+ }
219+
220+ /**
221+ * Remove cjsCache entries for a URL and its file-path variants.
222+ * @param {string } url
223+ * @returns {boolean } true if any entries were deleted.
224+ */
225+ function clearCjsCache ( url ) {
226+ let deleted = cjsCache . delete ( url ) ;
227+ const filename = getFilePathFromCjsCacheURL ( url ) ;
228+ if ( ! filename ) {
229+ return deleted ;
230+ }
231+
232+ const urls = [ ] ;
233+ for ( const entry of cjsCache ) {
234+ ArrayPrototypePush ( urls , entry [ 0 ] ) ;
235+ }
236+
237+ for ( let i = 0 ; i < urls . length ; i ++ ) {
238+ const cachedURL = urls [ i ] ;
239+ if ( cachedURL === url ) {
240+ continue ;
241+ }
242+ const cachedFilename = getFilePathFromCjsCacheURL ( cachedURL ) ;
243+ if ( cachedFilename === filename ) {
244+ cjsCache . delete ( cachedURL ) ;
245+ deleted = true ;
246+ }
247+ }
248+
249+ return deleted ;
250+ }
251+
252+ exports . clearCjsCache = clearCjsCache ;
253+
196254/**
197255 * Creates a ModuleWrap object for a CommonJS module.
198256 * @param {string } url - The URL of the module.
@@ -323,7 +381,9 @@ translators.set('require-commonjs-typescript', (url, translateContext, parentURL
323381
324382// This goes through Module._load to accommodate monkey-patchers.
325383function loadCJSModuleWithModuleLoad ( module , source , url , filename , isMain ) {
326- assert ( module === CJSModule . _cache [ filename ] ) ;
384+ if ( CJSModule . _cache [ filename ] !== module ) {
385+ CJSModule . _cache [ filename ] = module ;
386+ }
327387 // If it gets here in the translators, the hooks must have already been invoked
328388 // in the loader. Skip them in the synthetic module evaluation step.
329389 wrapModuleLoad ( filename , undefined , isMain , kShouldSkipModuleHooks ) ;
0 commit comments