From f471450eddd7c2a91aa53910c9f560d06b158cf7 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Tue, 12 Sep 2023 21:55:21 -0700 Subject: [PATCH 1/7] esm: update loaders warning --- lib/internal/modules/esm/loader.js | 5 ----- test/es-module/test-esm-experimental-warnings.mjs | 1 - 2 files changed, 6 deletions(-) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 5d1307565885de..65e74c1b05847e 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -499,7 +499,6 @@ class CustomizedModuleLoader { } } -let emittedExperimentalWarning = false; /** * A loader instance is used as the main entry point for loading ES modules. Currently, this is a singleton; there is * only one used for loading the main module and everything in its dependency graph, though separate instances of this @@ -515,10 +514,6 @@ function createModuleLoader(useCustomLoadersIfPresent = true) { !require('internal/modules/esm/utils').isLoaderWorker()) { const userLoaderPaths = getOptionValue('--experimental-loader'); if (userLoaderPaths.length > 0) { - if (!emittedExperimentalWarning) { - emitExperimentalWarning('Custom ESM Loaders'); - emittedExperimentalWarning = true; - } customizations = new CustomizedModuleLoader(); } } diff --git a/test/es-module/test-esm-experimental-warnings.mjs b/test/es-module/test-esm-experimental-warnings.mjs index 85b458258b6134..ece788b75f3a3d 100644 --- a/test/es-module/test-esm-experimental-warnings.mjs +++ b/test/es-module/test-esm-experimental-warnings.mjs @@ -25,7 +25,6 @@ describe('ESM: warn for obsolete hooks provided', { concurrency: true }, () => { describe('experimental warnings for enabled experimental feature', () => { for ( const [experiment, arg] of [ - [/Custom ESM Loaders/, `--experimental-loader=${fileURL('es-module-loaders', 'hooks-custom.mjs')}`], [/Network Imports/, '--experimental-network-imports'], ] ) { From 69371c996241138f21c8a793ae62bd9966cc0cec Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Wed, 13 Sep 2023 16:58:52 -0700 Subject: [PATCH 2/7] Change warning to be specific to --experimental-loader --- lib/internal/modules/esm/loader.js | 8 ++++++++ test/es-module/test-esm-experimental-warnings.mjs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 65e74c1b05847e..672046db21cecf 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -499,6 +499,7 @@ class CustomizedModuleLoader { } } +let emittedLoaderFlagWarning = false; /** * A loader instance is used as the main entry point for loading ES modules. Currently, this is a singleton; there is * only one used for loading the main module and everything in its dependency graph, though separate instances of this @@ -514,6 +515,13 @@ function createModuleLoader(useCustomLoadersIfPresent = true) { !require('internal/modules/esm/utils').isLoaderWorker()) { const userLoaderPaths = getOptionValue('--experimental-loader'); if (userLoaderPaths.length > 0) { + if (!emittedLoaderFlagWarning) { + process.emitWarning( + '`--experimental-loader` may be removed in the future; instead use `--import` to reference a file that calls `register()`', + 'ExperimentalWarning', + ); + emittedLoaderFlagWarning = true; + } customizations = new CustomizedModuleLoader(); } } diff --git a/test/es-module/test-esm-experimental-warnings.mjs b/test/es-module/test-esm-experimental-warnings.mjs index ece788b75f3a3d..c9082f3ea9dfac 100644 --- a/test/es-module/test-esm-experimental-warnings.mjs +++ b/test/es-module/test-esm-experimental-warnings.mjs @@ -25,6 +25,10 @@ describe('ESM: warn for obsolete hooks provided', { concurrency: true }, () => { describe('experimental warnings for enabled experimental feature', () => { for ( const [experiment, arg] of [ + [ + /`--experimental-loader` may be removed in the future/, + `--experimental-loader=${fileURL('es-module-loaders', 'hooks-custom.mjs')}` + ], [/Network Imports/, '--experimental-network-imports'], ] ) { From cf082a90867c1666e013112755a78e4bfd498bdf Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2023 08:47:14 -0700 Subject: [PATCH 3/7] Update test/es-module/test-esm-experimental-warnings.mjs Co-authored-by: Antoine du Hamel --- test/es-module/test-esm-experimental-warnings.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/es-module/test-esm-experimental-warnings.mjs b/test/es-module/test-esm-experimental-warnings.mjs index c9082f3ea9dfac..a1583b75c5ec31 100644 --- a/test/es-module/test-esm-experimental-warnings.mjs +++ b/test/es-module/test-esm-experimental-warnings.mjs @@ -27,7 +27,8 @@ describe('ESM: warn for obsolete hooks provided', { concurrency: true }, () => { const [experiment, arg] of [ [ /`--experimental-loader` may be removed in the future/, - `--experimental-loader=${fileURL('es-module-loaders', 'hooks-custom.mjs')}` + '--experimental-loader', + fileURL('es-module-loaders', 'hooks-custom.mjs'), ], [/Network Imports/, '--experimental-network-imports'], ] From 42077e5d59f418d565fb48fe95d67dd7e4647fb8 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2023 09:14:11 -0700 Subject: [PATCH 4/7] Update test/es-module/test-esm-experimental-warnings.mjs Co-authored-by: Antoine du Hamel --- test/es-module/test-esm-experimental-warnings.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/es-module/test-esm-experimental-warnings.mjs b/test/es-module/test-esm-experimental-warnings.mjs index a1583b75c5ec31..0672fb0b6f6f6a 100644 --- a/test/es-module/test-esm-experimental-warnings.mjs +++ b/test/es-module/test-esm-experimental-warnings.mjs @@ -24,7 +24,7 @@ describe('ESM: warn for obsolete hooks provided', { concurrency: true }, () => { describe('experimental warnings for enabled experimental feature', () => { for ( - const [experiment, arg] of [ + const [experiment, ...args] of [ [ /`--experimental-loader` may be removed in the future/, '--experimental-loader', From edc985e7ac1eeafb0cc57444a40e497cd6b6a96e Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2023 14:55:43 -0700 Subject: [PATCH 5/7] Improve warning --- lib/internal/modules/esm/loader.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 672046db21cecf..1946cff3ae8578 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -4,7 +4,10 @@ require('internal/modules/cjs/loader'); const { + ArrayPrototypeJoin, + ArrayPrototypeMap, FunctionPrototypeCall, + JSONStringify, ObjectSetPrototypeOf, SafeWeakMap, } = primordials; @@ -517,7 +520,11 @@ function createModuleLoader(useCustomLoadersIfPresent = true) { if (userLoaderPaths.length > 0) { if (!emittedLoaderFlagWarning) { process.emitWarning( - '`--experimental-loader` may be removed in the future; instead use `--import` to reference a file that calls `register()`', + '`--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("./"))`), + "; ", + )};'`, 'ExperimentalWarning', ); emittedLoaderFlagWarning = true; From 27c14d7ef62e3ac53e9aab9c10ca15cd3477df4a Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2023 16:05:14 -0700 Subject: [PATCH 6/7] lint --- lib/internal/modules/esm/loader.js | 3 ++- test/es-module/test-esm-experimental-warnings.mjs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 1946cff3ae8578..3ca61f90d89d23 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -6,6 +6,7 @@ require('internal/modules/cjs/loader'); const { ArrayPrototypeJoin, ArrayPrototypeMap, + encodeURI, FunctionPrototypeCall, JSONStringify, ObjectSetPrototypeOf, @@ -523,7 +524,7 @@ function createModuleLoader(useCustomLoadersIfPresent = true) { '`--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("./"))`), - "; ", + '; ', )};'`, 'ExperimentalWarning', ); diff --git a/test/es-module/test-esm-experimental-warnings.mjs b/test/es-module/test-esm-experimental-warnings.mjs index 0672fb0b6f6f6a..d499aae0afc1cd 100644 --- a/test/es-module/test-esm-experimental-warnings.mjs +++ b/test/es-module/test-esm-experimental-warnings.mjs @@ -35,7 +35,7 @@ describe('ESM: warn for obsolete hooks provided', { concurrency: true }, () => { ) { it(`should print for ${experiment.toString().replaceAll('/', '')}`, async () => { const { code, signal, stderr } = await spawnPromisified(execPath, [ - arg, + ...args, '--input-type=module', '--eval', `import ${JSON.stringify(fileURL('es-module-loaders', 'module-named-exports.mjs'))}`, From 45d517d0fa1deb2db075e89dc8a0201ff397d15e Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 16 Sep 2023 23:27:39 +0200 Subject: [PATCH 7/7] `readableURIEncode` --- lib/internal/modules/esm/loader.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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',