mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
module: only emit require(esm) warning under --trace-require-module
require(esm) is relatively stable now and the experimental warning has run its course - it's now more troublesome than useful. This patch changes it to no longer emit a warning unless `--trace-require-module` is explicitly used. The flag supports two modes: - `--trace-require-module=all`: emit warnings for all usages - `--trace-require-module=no-node-modules`: emit warnings for usages that do not come from a `node_modules` folder. PR-URL: https://github.com/nodejs/node/pull/56194 Fixes: https://github.com/nodejs/node/issues/55417 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
This commit is contained in:
committed by
Node.js GitHub Bot
parent
586814bcd9
commit
b6c9dbe7e1
@@ -2616,6 +2616,18 @@ added:
|
||||
Prints a stack trace whenever an environment is exited proactively,
|
||||
i.e. invoking `process.exit()`.
|
||||
|
||||
### `--trace-require-module=mode`
|
||||
|
||||
<!-- YAML
|
||||
added:
|
||||
- REPLACEME
|
||||
-->
|
||||
|
||||
Prints information about usage of [Loading ECMAScript modules using `require()`][].
|
||||
|
||||
When `mode` is `all`, all usage is printed. When `mode` is `no-node-modules`, usage
|
||||
from the `node_modules` folder is excluded.
|
||||
|
||||
### `--trace-sigint`
|
||||
|
||||
<!-- YAML
|
||||
@@ -3126,6 +3138,7 @@ one is included in the list below.
|
||||
* `--trace-event-file-pattern`
|
||||
* `--trace-events-enabled`
|
||||
* `--trace-exit`
|
||||
* `--trace-require-module`
|
||||
* `--trace-sigint`
|
||||
* `--trace-sync-io`
|
||||
* `--trace-tls`
|
||||
|
||||
@@ -175,6 +175,11 @@ added:
|
||||
- v22.0.0
|
||||
- v20.17.0
|
||||
changes:
|
||||
- version:
|
||||
- REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/56194
|
||||
description: This feature no longer emits an experimental warning by default,
|
||||
though the warning can still be emitted by --trace-require-module.
|
||||
- version:
|
||||
- v23.0.0
|
||||
- v22.12.0
|
||||
@@ -319,9 +324,8 @@ help users fix them.
|
||||
|
||||
Support for loading ES modules using `require()` is currently
|
||||
experimental and can be disabled using `--no-experimental-require-module`.
|
||||
When `require()` actually encounters an ES module for the
|
||||
first time in the process, it will emit an experimental warning. The
|
||||
warning is expected to be removed when this feature stablizes.
|
||||
To print where this feature is used, use [`--trace-require-module`][].
|
||||
|
||||
This feature can be detected by checking if
|
||||
[`process.features.require_module`][] is `true`.
|
||||
|
||||
@@ -1271,6 +1275,7 @@ This section was moved to
|
||||
[GLOBAL_FOLDERS]: #loading-from-the-global-folders
|
||||
[`"main"`]: packages.md#main
|
||||
[`"type"`]: packages.md#type
|
||||
[`--trace-require-module`]: cli.md#--trace-require-modulemode
|
||||
[`ERR_REQUIRE_ASYNC_MODULE`]: errors.md#err_require_async_module
|
||||
[`ERR_UNSUPPORTED_DIR_IMPORT`]: errors.md#err_unsupported_dir_import
|
||||
[`MODULE_NOT_FOUND`]: errors.md#module_not_found
|
||||
|
||||
@@ -1499,7 +1499,7 @@ Module.prototype.require = function(id) {
|
||||
}
|
||||
};
|
||||
|
||||
let emittedRequireModuleWarning = false;
|
||||
let requireModuleWarningMode;
|
||||
/**
|
||||
* Resolve and evaluate it synchronously as ESM if it's ESM.
|
||||
* @param {Module} mod CJS module instance
|
||||
@@ -1520,17 +1520,22 @@ function loadESMFromCJS(mod, filename, format, source) {
|
||||
} else {
|
||||
const parent = mod[kModuleParent];
|
||||
|
||||
if (!emittedRequireModuleWarning) {
|
||||
requireModuleWarningMode ??= getOptionValue('--trace-require-module');
|
||||
if (requireModuleWarningMode) {
|
||||
let shouldEmitWarning = false;
|
||||
// Check if the require() comes from node_modules.
|
||||
if (parent) {
|
||||
shouldEmitWarning = !isUnderNodeModules(parent.filename);
|
||||
} else if (mod[kIsCachedByESMLoader]) {
|
||||
// It comes from the require() built for `import cjs` and doesn't have a parent recorded
|
||||
// in the CJS module instance. Inspect the stack trace to see if the require()
|
||||
// comes from node_modules and reduce the noise. If there are more than 100 frames,
|
||||
// just give up and assume it is under node_modules.
|
||||
shouldEmitWarning = !isInsideNodeModules(100, true);
|
||||
if (requireModuleWarningMode === 'no-node-modules') {
|
||||
// Check if the require() comes from node_modules.
|
||||
if (parent) {
|
||||
shouldEmitWarning = !isUnderNodeModules(parent.filename);
|
||||
} else if (mod[kIsCachedByESMLoader]) {
|
||||
// It comes from the require() built for `import cjs` and doesn't have a parent recorded
|
||||
// in the CJS module instance. Inspect the stack trace to see if the require()
|
||||
// comes from node_modules and reduce the noise. If there are more than 100 frames,
|
||||
// just give up and assume it is under node_modules.
|
||||
shouldEmitWarning = !isInsideNodeModules(100, true);
|
||||
}
|
||||
} else {
|
||||
shouldEmitWarning = true;
|
||||
}
|
||||
if (shouldEmitWarning) {
|
||||
let messagePrefix;
|
||||
@@ -1556,7 +1561,7 @@ function loadESMFromCJS(mod, filename, format, source) {
|
||||
messagePrefix,
|
||||
undefined,
|
||||
parent?.require);
|
||||
emittedRequireModuleWarning = true;
|
||||
requireModuleWarningMode = true;
|
||||
}
|
||||
}
|
||||
const {
|
||||
|
||||
@@ -135,6 +135,11 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors,
|
||||
errors->push_back("--heapsnapshot-near-heap-limit must not be negative");
|
||||
}
|
||||
|
||||
if (!trace_require_module.empty() && trace_require_module != "all" &&
|
||||
trace_require_module != "no-node-modules") {
|
||||
errors->push_back("invalid value for --trace-require-module");
|
||||
}
|
||||
|
||||
if (test_runner) {
|
||||
if (test_isolation == "none") {
|
||||
debug_options_.allow_attaching_debugger = true;
|
||||
@@ -771,6 +776,13 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
|
||||
&EnvironmentOptions::trace_env_native_stack,
|
||||
kAllowedInEnvvar);
|
||||
|
||||
AddOption(
|
||||
"--trace-require-module",
|
||||
"Print access to require(esm). Options are 'all' (print all usage) and "
|
||||
"'no-node-modules' (excluding usage from the node_modules folder)",
|
||||
&EnvironmentOptions::trace_require_module,
|
||||
kAllowedInEnvvar);
|
||||
|
||||
AddOption("--extra-info-on-fatal-exception",
|
||||
"hide extra information on fatal exception that causes exit",
|
||||
&EnvironmentOptions::extra_info_on_fatal_exception,
|
||||
|
||||
@@ -210,6 +210,7 @@ class EnvironmentOptions : public Options {
|
||||
bool trace_env = false;
|
||||
bool trace_env_js_stack = false;
|
||||
bool trace_env_native_stack = false;
|
||||
std::string trace_require_module;
|
||||
bool extra_info_on_fatal_exception = true;
|
||||
std::string unhandled_rejections;
|
||||
std::vector<std::string> userland_loaders;
|
||||
|
||||
@@ -5,8 +5,6 @@ const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const { fixturesDir } = require('../common/fixtures');
|
||||
|
||||
function testPreload(preloadFlag) {
|
||||
// The warning is only emitted when ESM is loaded by --require.
|
||||
const isRequire = preloadFlag === '--require';
|
||||
// Test named exports.
|
||||
{
|
||||
spawnSyncAndAssert(
|
||||
@@ -22,8 +20,6 @@ function testPreload(preloadFlag) {
|
||||
},
|
||||
{
|
||||
stdout: 'A',
|
||||
stderr: isRequire ?
|
||||
/ExperimentalWarning: --require is loading ES Module .*module-named-exports\.mjs using require/ : undefined,
|
||||
trim: true,
|
||||
}
|
||||
);
|
||||
@@ -43,8 +39,6 @@ function testPreload(preloadFlag) {
|
||||
cwd: fixturesDir
|
||||
},
|
||||
{
|
||||
stderr: isRequire ?
|
||||
/ExperimentalWarning: --require is loading ES Module .*import-esm\.mjs using require/ : undefined,
|
||||
stdout: /^world\s+A$/,
|
||||
trim: true,
|
||||
}
|
||||
@@ -66,8 +60,6 @@ function testPreload(preloadFlag) {
|
||||
},
|
||||
{
|
||||
stdout: /^ok\s+A$/,
|
||||
stderr: isRequire ?
|
||||
/ExperimentalWarning: --require is loading ES Module .*cjs-exports\.mjs using require/ : undefined,
|
||||
trim: true,
|
||||
}
|
||||
);
|
||||
@@ -90,8 +82,6 @@ function testPreload(preloadFlag) {
|
||||
},
|
||||
{
|
||||
stdout: /^world\s+A$/,
|
||||
stderr: isRequire ?
|
||||
/ExperimentalWarning: --require is loading ES Module .*require-cjs\.mjs using require/ : undefined,
|
||||
trim: true,
|
||||
}
|
||||
);
|
||||
@@ -117,7 +107,6 @@ testPreload('--import');
|
||||
},
|
||||
{
|
||||
stdout: /^package-type-module\s+A$/,
|
||||
stderr: /ExperimentalWarning: --require is loading ES Module .*package-type-module[\\/]index\.js using require/,
|
||||
trim: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
'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.
|
||||
|
||||
// This checks the warning and the stack trace emitted by --trace-require-module=all.
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const fixtures = require('../common/fixtures');
|
||||
@@ -10,6 +8,7 @@ const assert = require('assert');
|
||||
|
||||
spawnSyncAndAssert(process.execPath, [
|
||||
'--trace-warnings',
|
||||
'--trace-require-module=all',
|
||||
fixtures.path('es-modules', 'require-module.js'),
|
||||
], {
|
||||
trim: true,
|
||||
@@ -33,3 +32,12 @@ spawnSyncAndAssert(process.execPath, [
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
spawnSyncAndAssert(process.execPath, [
|
||||
'--trace-require-module=1',
|
||||
fixtures.path('es-modules', 'require-module.js'),
|
||||
], {
|
||||
status: 9,
|
||||
trim: true,
|
||||
stderr: /invalid value for --trace-require-module/
|
||||
});
|
||||
|
||||
@@ -3,16 +3,6 @@
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
|
||||
// Only the first load will trigger the warning.
|
||||
common.expectWarning(
|
||||
'ExperimentalWarning',
|
||||
`CommonJS module ${__filename} is loading ES Module ` +
|
||||
`${path.resolve(__dirname, '../fixtures/es-module-loaders/module-named-exports.mjs')} using require().\n` +
|
||||
'Support for loading ES Module in require() is an experimental feature ' +
|
||||
'and might change at any time'
|
||||
);
|
||||
|
||||
// Test named exports.
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
// This checks the experimental warning for require(esm) is disabled when the
|
||||
// require() comes from node_modules.
|
||||
// This checks the warning and the stack trace emitted by
|
||||
// --trace-require-module=no-node-modules.
|
||||
require('../common');
|
||||
const { spawnSyncAndAssert } = require('../common/child_process');
|
||||
const fixtures = require('../common/fixtures');
|
||||
@@ -14,7 +14,10 @@ const warningRE = /Support for loading ES Module in require\(\)/;
|
||||
// require() in non-node_modules -> esm in node_modules should warn.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[fixtures.path('es-modules', 'test_node_modules', 'require-esm.js')],
|
||||
[
|
||||
'--trace-require-module=no-node-modules',
|
||||
fixtures.path('es-modules', 'test_node_modules', 'require-esm.js'),
|
||||
],
|
||||
{
|
||||
trim: true,
|
||||
stderr: warningRE,
|
||||
@@ -26,7 +29,10 @@ spawnSyncAndAssert(
|
||||
// should not warn.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[fixtures.path('es-modules', 'test_node_modules', 'require-require-esm.js')],
|
||||
[
|
||||
'--trace-require-module=no-node-modules',
|
||||
fixtures.path('es-modules', 'test_node_modules', 'require-require-esm.js'),
|
||||
],
|
||||
{
|
||||
trim: true,
|
||||
stderr: '',
|
||||
@@ -38,7 +44,10 @@ spawnSyncAndAssert(
|
||||
// should not warn.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[fixtures.path('es-modules', 'test_node_modules', 'import-require-esm.mjs')],
|
||||
[
|
||||
'--trace-require-module=no-node-modules',
|
||||
fixtures.path('es-modules', 'test_node_modules', 'import-require-esm.mjs'),
|
||||
],
|
||||
{
|
||||
trim: true,
|
||||
stderr: '',
|
||||
@@ -50,7 +59,10 @@ spawnSyncAndAssert(
|
||||
// require() in node_modules -> esm in node_modules should not warn.
|
||||
spawnSyncAndAssert(
|
||||
process.execPath,
|
||||
[fixtures.path('es-modules', 'test_node_modules', 'import-import-require-esm.mjs')],
|
||||
[
|
||||
'--trace-require-module=no-node-modules',
|
||||
fixtures.path('es-modules', 'test_node_modules', 'import-import-require-esm.mjs'),
|
||||
],
|
||||
{
|
||||
trim: true,
|
||||
stderr: '',
|
||||
|
||||
@@ -116,7 +116,6 @@ test('execute a .cts file importing a .mts file export', async () => {
|
||||
fixtures.path('typescript/cts/test-require-mts-module.cts'),
|
||||
]);
|
||||
|
||||
match(result.stderr, /Support for loading ES Module in require\(\) is an experimental feature and might change at any time/);
|
||||
match(result.stdout, /Hello, TypeScript!/);
|
||||
strictEqual(result.code, 0);
|
||||
});
|
||||
|
||||
@@ -175,7 +175,6 @@ test('expect failure of a TypeScript file requiring ES module syntax', async ()
|
||||
fixtures.path('typescript/ts/test-require-module.ts'),
|
||||
]);
|
||||
|
||||
match(result.stderr, /Support for loading ES Module in require\(\) is an experimental feature and might change at any time/);
|
||||
match(result.stdout, /Hello, TypeScript!/);
|
||||
strictEqual(result.code, 0);
|
||||
});
|
||||
@@ -231,7 +230,6 @@ test('execute a TypeScript file with CommonJS syntax requiring .mts using requir
|
||||
fixtures.path('typescript/ts/test-require-mts.ts'),
|
||||
]);
|
||||
|
||||
match(result.stderr, /Support for loading ES Module in require\(\) is an experimental feature and might change at any time/);
|
||||
match(result.stdout, /Hello, TypeScript!/);
|
||||
strictEqual(result.code, 0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user