Skip to content

Commit 7cbe3de

Browse files
joyeecheungruyadorno
authored andcommitted
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: #56194Fixes: #55417 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Marco Ippolito <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]>
1 parent bfd11d7 commit 7cbe3de

File tree

11 files changed

+83
-49
lines changed

11 files changed

+83
-49
lines changed

‎doc/api/cli.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,6 +2669,18 @@ added:
26692669
Prints a stack trace whenever an environment is exited proactively,
26702670
i.e. invoking `process.exit()`.
26712671

2672+
### `--trace-require-module=mode`
2673+
2674+
<!-- YAML
2675+
added:
2676+
- REPLACEME
2677+
-->
2678+
2679+
Prints information about usage of [Loading ECMAScript modules using `require()`][].
2680+
2681+
When `mode` is `all`, all usage is printed. When `mode` is `no-node-modules`, usage
2682+
from the `node_modules` folder is excluded.
2683+
26722684
### `--trace-sigint`
26732685

26742686
<!-- YAML
@@ -3180,6 +3192,7 @@ one is included in the list below.
31803192
*`--trace-event-file-pattern`
31813193
*`--trace-events-enabled`
31823194
*`--trace-exit`
3195+
*`--trace-require-module`
31833196
*`--trace-sigint`
31843197
*`--trace-sync-io`
31853198
*`--trace-tls`

‎doc/api/modules.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,15 @@ relative, and based on the real path of the files making the calls to
174174
added:
175175
- v22.0.0
176176
changes:
177-
- version: v22.12.0
177+
- version:
178+
- v23.0.0
179+
- v22.12.0
178180
pr-url: https://github.com/nodejs/node/pull/55085
179181
description: This feature is no longer behind the `--experimental-require-module` CLI flag.
182+
- version: REPLACEME
183+
pr-url: https://github.com/nodejs/node/pull/56194
184+
description: This feature no longer emits an experimental warning by default,
185+
though the warning can still be emitted by --trace-require-module.
180186
- version: v22.12.0
181187
pr-url: https://github.com/nodejs/node/pull/54563
182188
description: Support `'module.exports'` interop export in `require(esm)`.
@@ -314,9 +320,8 @@ help users fix them.
314320

315321
Support for loading ES modules using `require()` is currently
316322
experimental and can be disabled using `--no-experimental-require-module`.
317-
When `require()` actually encounters an ES module for the
318-
first time in the process, it will emit an experimental warning. The
319-
warning is expected to be removed when this feature stablizes.
323+
To print where this feature is used, use [`--trace-require-module`][].
324+
320325
This feature can be detected by checking if
321326
[`process.features.require_module`][] is `true`.
322327

@@ -1266,6 +1271,7 @@ This section was moved to
12661271
[GLOBAL_FOLDERS]: #loading-from-the-global-folders
12671272
[`"main"`]: packages.md#main
12681273
[`"type"`]: packages.md#type
1274+
[`--trace-require-module`]: cli.md#--trace-require-modulemode
12691275
[`ERR_REQUIRE_ASYNC_MODULE`]: errors.md#err_require_async_module
12701276
[`ERR_UNSUPPORTED_DIR_IMPORT`]: errors.md#err_unsupported_dir_import
12711277
[`MODULE_NOT_FOUND`]: errors.md#module_not_found

‎lib/internal/modules/cjs/loader.js‎

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ Module.prototype.require = function(id){
13381338
}
13391339
};
13401340

1341-
letemittedRequireModuleWarning=false;
1341+
letrequireModuleWarningMode;
13421342
/**
13431343
* Resolve and evaluate it synchronously as ESM if it's ESM.
13441344
* @param{Module} mod CJS module instance
@@ -1361,17 +1361,22 @@ function loadESMFromCJS(mod, filename){
13611361
}else{
13621362
constparent=mod[kModuleParent];
13631363

1364-
if(!emittedRequireModuleWarning){
1364+
requireModuleWarningMode??=getOptionValue('--trace-require-module');
1365+
if(requireModuleWarningMode){
13651366
letshouldEmitWarning=false;
1366-
// Check if the require() comes from node_modules.
1367-
if(parent){
1368-
shouldEmitWarning=!isUnderNodeModules(parent.filename);
1369-
}elseif(mod[kIsCachedByESMLoader]){
1370-
// It comes from the require() built for `import cjs` and doesn't have a parent recorded
1371-
// in the CJS module instance. Inspect the stack trace to see if the require()
1372-
// comes from node_modules and reduce the noise. If there are more than 100 frames,
1373-
// just give up and assume it is under node_modules.
1374-
shouldEmitWarning=!isInsideNodeModules(100,true);
1367+
if(requireModuleWarningMode==='no-node-modules'){
1368+
// Check if the require() comes from node_modules.
1369+
if(parent){
1370+
shouldEmitWarning=!isUnderNodeModules(parent.filename);
1371+
}elseif(mod[kIsCachedByESMLoader]){
1372+
// It comes from the require() built for `import cjs` and doesn't have a parent recorded
1373+
// in the CJS module instance. Inspect the stack trace to see if the require()
1374+
// comes from node_modules and reduce the noise. If there are more than 100 frames,
1375+
// just give up and assume it is under node_modules.
1376+
shouldEmitWarning=!isInsideNodeModules(100,true);
1377+
}
1378+
}else{
1379+
shouldEmitWarning=true;
13751380
}
13761381
if(shouldEmitWarning){
13771382
letmessagePrefix;
@@ -1397,7 +1402,7 @@ function loadESMFromCJS(mod, filename){
13971402
messagePrefix,
13981403
undefined,
13991404
parent?.require);
1400-
emittedRequireModuleWarning=true;
1405+
requireModuleWarningMode=true;
14011406
}
14021407
}
14031408
const{

‎src/node_options.cc‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors,
142142
errors->push_back("--heapsnapshot-near-heap-limit must not be negative");
143143
}
144144

145+
if (!trace_require_module.empty() && trace_require_module != "all" &&
146+
trace_require_module != "no-node-modules"){
147+
errors->push_back("invalid value for --trace-require-module");
148+
}
149+
145150
if (test_runner){
146151
if (test_isolation == "none"){
147152
debug_options_.allow_attaching_debugger = true;
@@ -797,6 +802,14 @@ EnvironmentOptionsParser::EnvironmentOptionsParser(){
797802
"set module system to use by default",
798803
&EnvironmentOptions::type,
799804
kAllowedInEnvvar);
805+
806+
AddOption(
807+
"--trace-require-module",
808+
"Print access to require(esm). Options are 'all' (print all usage) and "
809+
"'no-node-modules' (excluding usage from the node_modules folder)",
810+
&EnvironmentOptions::trace_require_module,
811+
kAllowedInEnvvar);
812+
800813
AddOption("--extra-info-on-fatal-exception",
801814
"hide extra information on fatal exception that causes exit",
802815
&EnvironmentOptions::extra_info_on_fatal_exception,

‎src/node_options.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ class EnvironmentOptions : public Options{
213213
bool trace_env = false;
214214
bool trace_env_js_stack = false;
215215
bool trace_env_native_stack = false;
216+
std::string trace_require_module;
216217
bool extra_info_on_fatal_exception = true;
217218
std::string unhandled_rejections;
218219
std::vector<std::string> userland_loaders;

‎test/es-module/test-require-module-preload.js‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ const{spawnSyncAndAssert } = require('../common/child_process');
55
const{ fixturesDir }=require('../common/fixtures');
66

77
functiontestPreload(preloadFlag){
8-
// The warning is only emitted when ESM is loaded by --require.
9-
constisRequire=preloadFlag==='--require';
108
// Test named exports.
119
{
1210
spawnSyncAndAssert(
@@ -22,8 +20,6 @@ function testPreload(preloadFlag){
2220
},
2321
{
2422
stdout: 'A',
25-
stderr: isRequire ?
26-
/ExperimentalWarning:--requireisloadingESModule.*module-named-exports\.mjsusingrequire/ : undefined,
2723
trim: true,
2824
}
2925
);
@@ -43,8 +39,6 @@ function testPreload(preloadFlag){
4339
cwd: fixturesDir
4440
},
4541
{
46-
stderr: isRequire ?
47-
/ExperimentalWarning:--requireisloadingESModule.*import-esm\.mjsusingrequire/ : undefined,
4842
stdout: /^world\s+A$/,
4943
trim: true,
5044
}
@@ -66,8 +60,6 @@ function testPreload(preloadFlag){
6660
},
6761
{
6862
stdout: /^ok\s+A$/,
69-
stderr: isRequire ?
70-
/ExperimentalWarning:--requireisloadingESModule.*cjs-exports\.mjsusingrequire/ : undefined,
7163
trim: true,
7264
}
7365
);
@@ -90,8 +82,6 @@ function testPreload(preloadFlag){
9082
},
9183
{
9284
stdout: /^world\s+A$/,
93-
stderr: isRequire ?
94-
/ExperimentalWarning:--requireisloadingESModule.*require-cjs\.mjsusingrequire/ : undefined,
9585
trim: true,
9686
}
9787
);
@@ -117,7 +107,6 @@ testPreload('--import');
117107
},
118108
{
119109
stdout: /^package-type-module\s+A$/,
120-
stderr: /ExperimentalWarning:--requireisloadingESModule.*package-type-module[\\/]index\.jsusingrequire/,
121110
trim: true,
122111
}
123112
);

‎test/es-module/test-require-module-warning.js‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
'use strict';
22

3-
// This checks the warning and the stack trace emitted by the require(esm)
4-
// experimental warning. It can get removed when `require(esm)` becomes stable.
5-
3+
// This checks the warning and the stack trace emitted by --trace-require-module=all.
64
require('../common');
75
const{ spawnSyncAndAssert }=require('../common/child_process');
86
constfixtures=require('../common/fixtures');
97
constassert=require('assert');
108

119
spawnSyncAndAssert(process.execPath,[
1210
'--trace-warnings',
11+
'--trace-require-module=all',
1312
fixtures.path('es-modules','require-module.js'),
1413
],{
1514
trim: true,
@@ -33,3 +32,12 @@ spawnSyncAndAssert(process.execPath, [
3332
);
3433
}
3534
});
35+
36+
spawnSyncAndAssert(process.execPath,[
37+
'--trace-require-module=1',
38+
fixtures.path('es-modules','require-module.js'),
39+
],{
40+
status: 9,
41+
trim: true,
42+
stderr: /invalidvaluefor--trace-require-module/
43+
});

‎test/es-module/test-require-module.js‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,6 @@
33

44
constcommon=require('../common');
55
constassert=require('assert');
6-
constpath=require('path');
7-
8-
// Only the first load will trigger the warning.
9-
common.expectWarning(
10-
'ExperimentalWarning',
11-
`CommonJS module ${__filename} is loading ES Module `+
12-
`${path.resolve(__dirname,'../fixtures/es-module-loaders/module-named-exports.mjs')} using require().\n`+
13-
'Support for loading ES Module in require() is an experimental feature '+
14-
'and might change at any time'
15-
);
166

177
// Test named exports.
188
{

‎test/es-module/test-require-node-modules-warning.js‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

3-
// This checks the experimental warning for require(esm) is disabled when the
4-
// require() comes from node_modules.
3+
// This checks the warning and the stack trace emitted by
4+
// --trace-require-module=no-node-modules.
55
require('../common');
66
const{ spawnSyncAndAssert }=require('../common/child_process');
77
constfixtures=require('../common/fixtures');
@@ -14,7 +14,10 @@ const warningRE = /Support for loading ES Module in require\(\)/;
1414
// require() in non-node_modules -> esm in node_modules should warn.
1515
spawnSyncAndAssert(
1616
process.execPath,
17-
[fixtures.path('es-modules','test_node_modules','require-esm.js')],
17+
[
18+
'--trace-require-module=no-node-modules',
19+
fixtures.path('es-modules','test_node_modules','require-esm.js'),
20+
],
1821
{
1922
trim: true,
2023
stderr: warningRE,
@@ -26,7 +29,10 @@ spawnSyncAndAssert(
2629
// should not warn.
2730
spawnSyncAndAssert(
2831
process.execPath,
29-
[fixtures.path('es-modules','test_node_modules','require-require-esm.js')],
32+
[
33+
'--trace-require-module=no-node-modules',
34+
fixtures.path('es-modules','test_node_modules','require-require-esm.js'),
35+
],
3036
{
3137
trim: true,
3238
stderr: '',
@@ -38,7 +44,10 @@ spawnSyncAndAssert(
3844
// should not warn.
3945
spawnSyncAndAssert(
4046
process.execPath,
41-
[fixtures.path('es-modules','test_node_modules','import-require-esm.mjs')],
47+
[
48+
'--trace-require-module=no-node-modules',
49+
fixtures.path('es-modules','test_node_modules','import-require-esm.mjs'),
50+
],
4251
{
4352
trim: true,
4453
stderr: '',
@@ -50,7 +59,10 @@ spawnSyncAndAssert(
5059
// require() in node_modules -> esm in node_modules should not warn.
5160
spawnSyncAndAssert(
5261
process.execPath,
53-
[fixtures.path('es-modules','test_node_modules','import-import-require-esm.mjs')],
62+
[
63+
'--trace-require-module=no-node-modules',
64+
fixtures.path('es-modules','test_node_modules','import-import-require-esm.mjs'),
65+
],
5466
{
5567
trim: true,
5668
stderr: '',

‎test/es-module/test-typescript-commonjs.mjs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ test('execute a .cts file importing a .mts file export', async () =>{
116116
fixtures.path('typescript/cts/test-require-mts-module.cts'),
117117
]);
118118

119-
match(result.stderr,/SupportforloadingESModuleinrequire\(\)isanexperimentalfeatureandmightchangeatanytime/);
120119
match(result.stdout,/Hello,TypeScript!/);
121120
strictEqual(result.code,0);
122121
});

0 commit comments

Comments
(0)