@@ -22,7 +22,7 @@ const { validateString } = require('internal/validators');
2222const fs = require ( 'fs' ) ; // Import all of `fs` so that it can be monkey-patched.
2323const internalFS = require ( 'internal/fs/utils' ) ;
2424const path = require ( 'path' ) ;
25- const { pathToFileURL, fileURLToPath } = require ( 'internal/url' ) ;
25+ const { pathToFileURL, fileURLToPath, URL } = require ( 'internal/url' ) ;
2626const assert = require ( 'internal/assert' ) ;
2727
2828const { getOptionValue } = require ( 'internal/options' ) ;
@@ -295,13 +295,32 @@ function normalizeReferrerURL(referrerName) {
295295}
296296
297297/**
298+ * Coerce a URL string to a filename. This is used by the ESM loader
299+ * to map ESM URLs to entries in the CJS module cache on a best-effort basis.
300+ * TODO(joyeecheung): this can be rather expensive, cache the result on the
301+ * ModuleWrap wherever we can.
298302 * @param {string|undefined } url URL to convert to filename
299303 * @returns {string|undefined }
300304 */
301305function urlToFilename ( url ) {
302306 if ( url && StringPrototypeStartsWith ( url , 'file://' ) ) {
303- return fileURLToPath ( url ) ;
307+ let urlObj ;
308+ try {
309+ urlObj = new URL ( url ) ;
310+ } catch {
311+ // Not a proper URL, return as-is as the cache key.
312+ return url ;
313+ }
314+ try {
315+ return fileURLToPath ( urlObj ) ;
316+ } catch {
317+ // This is generally only possible when the URL is provided by a custom loader.
318+ // Just use the path and ignore whether it's absolute or not as there's no such
319+ // requirement for CJS cache.
320+ return urlObj . pathname ;
321+ }
304322 }
323+ // Not a file URL, return as-is.
305324 return url ;
306325}
307326
0 commit comments