diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 3ca61f90d89d23..3dc748c175c844 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -6,11 +6,14 @@ require('internal/modules/cjs/loader'); const { ArrayPrototypeJoin, ArrayPrototypeMap, - encodeURI, + ArrayPrototypeReduce, FunctionPrototypeCall, JSONStringify, ObjectSetPrototypeOf, + RegExpPrototypeSymbolReplace, SafeWeakMap, + encodeURIComponent, + hardenRegExp, } = primordials; const { @@ -520,10 +523,18 @@ function createModuleLoader(useCustomLoadersIfPresent = true) { const userLoaderPaths = getOptionValue('--experimental-loader'); if (userLoaderPaths.length > 0) { if (!emittedLoaderFlagWarning) { + const readableURIEncode = (string) => ArrayPrototypeReduce( + [ + [/'/g, '%27'], // We need to URL-encode the single quote as it's the delimiter for the --import flag. + [/%22/g, '"'], // We can decode the double quotes to improve readability. + [/%2F/ig, '/'], // We can decode the slashes to improve readability. + ], + (str, { 0: regex, 1: replacement }) => RegExpPrototypeSymbolReplace(hardenRegExp(regex), str, replacement), + encodeURIComponent(string)); process.emitWarning( '`--experimental-loader` may be removed in the future; instead use `register()`:\n' + `--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; ${ArrayPrototypeJoin( - ArrayPrototypeMap(userLoaderPaths, (loader) => `register(${JSONStringify(encodeURI(loader))}, pathToFileURL("./"))`), + ArrayPrototypeMap(userLoaderPaths, (loader) => `register(${readableURIEncode(JSONStringify(loader))}, pathToFileURL("./"))`), '; ', )};'`, 'ExperimentalWarning',