From 16119f206fe2875d242a6c42d41fc75009b5054b Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 18 Oct 2024 16:48:19 +0200 Subject: [PATCH] module: trim off internal stack frames for require(esm) warnings Trim off irrelevant internal stack frames for require(esm) warnings so it's easier to locate where the call comes from when --trace-warnings is used. PR-URL: https://github.com/nodejs/node/pull/55496 Backport-PR-URL: https://github.com/nodejs/node/pull/55217 Reviewed-By: Marco Ippolito Reviewed-By: Paolo Insogna Refs: https://github.com/nodejs/node/issues/52697 --- lib/internal/modules/cjs/loader.js | 5 ++- lib/internal/util.js | 10 ++++-- test/es-module/test-require-module-warning.js | 35 +++++++++++++++++++ test/fixtures/es-modules/require-module.js | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/es-module/test-require-module-warning.js create mode 100644 test/fixtures/es-modules/require-module.js diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index fef17d95b4b08f..5af29ef56acaac 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1394,7 +1394,10 @@ function loadESMFromCJS(mod, filename) { messagePrefix = `${from} is loading ES Module ${to} using require().\n`; } } - emitExperimentalWarning('Support for loading ES Module in require()', messagePrefix); + emitExperimentalWarning('Support for loading ES Module in require()', + messagePrefix, + undefined, + parent?.require); const { wrap, namespace, diff --git a/lib/internal/util.js b/lib/internal/util.js index de05bb76c5c7a5..3fc0dc9c207fb5 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -256,14 +256,20 @@ function slowCases(enc) { } } -function emitExperimentalWarning(feature, messagePrefix) { +/** + * @param {string} feature Feature name used in the warning message + * @param {string} messagePrefix Prefix of the warning message + * @param {string} code See documentation of process.emitWarning + * @param {string} ctor See documentation of process.emitWarning + */ +function emitExperimentalWarning(feature, messagePrefix, code, ctor) { if (experimentalWarnings.has(feature)) return; experimentalWarnings.add(feature); let msg = `${feature} is an experimental feature and might change at any time`; if (messagePrefix) { msg = messagePrefix + msg; } - process.emitWarning(msg, 'ExperimentalWarning'); + process.emitWarning(msg, 'ExperimentalWarning', code, ctor); } function filterDuplicateStrings(items, low) { diff --git a/test/es-module/test-require-module-warning.js b/test/es-module/test-require-module-warning.js new file mode 100644 index 00000000000000..d5be2fc6da8755 --- /dev/null +++ b/test/es-module/test-require-module-warning.js @@ -0,0 +1,35 @@ +'use strict'; + +// This checks the warning and the stack trace emitted by the require(esm) +// experimental warning. It can get removed when `require(esm)` becomes stable. + +require('../common'); +const { spawnSyncAndAssert } = require('../common/child_process'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); + +spawnSyncAndAssert(process.execPath, [ + '--trace-warnings', + fixtures.path('es-modules', 'require-module.js'), +], { + trim: true, + stderr(output) { + const lines = output.split('\n'); + assert.match( + lines[0], + /ExperimentalWarning: CommonJS module .*require-module\.js is loading ES Module .*message\.mjs/ + ); + assert.strictEqual( + lines[1], + 'Support for loading ES Module in require() is an experimental feature and might change at any time' + ); + assert.match( + lines[2], + /at require \(.*modules\/helpers:\d+:\d+\)/ + ); + assert.match( + lines[3], + /at Object\. \(.*require-module\.js:1:1\)/ + ); + } +}); diff --git a/test/fixtures/es-modules/require-module.js b/test/fixtures/es-modules/require-module.js new file mode 100644 index 00000000000000..5a36590fc6171f --- /dev/null +++ b/test/fixtures/es-modules/require-module.js @@ -0,0 +1 @@ +require('./message.mjs');