Skip to content

Commit f0850a3

Browse files
pd4d10MylesBorins
authored andcommitted
module: add warnings for experimental flags
PR-URL: #30617 Fixes: #30600 Reviewed-By: Guy Bedford <[email protected]>
1 parent 0a4cfef commit f0850a3

13 files changed

+139
-8
lines changed

lib/internal/modules/cjs/loader.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const {
3636
rekeySourceMap
3737
} = require('internal/source_map/source_map_cache');
3838
const { pathToFileURL, fileURLToPath, URL } = require('internal/url');
39-
const { deprecate } = require('internal/util');
39+
const { deprecate, emitExperimentalWarning } = require('internal/util');
4040
const vm = require('vm');
4141
const assert = require('internal/assert');
4242
const fs = require('fs');
@@ -576,17 +576,21 @@ function resolveExportsTarget(pkgPath, target, subpath, basePath, mappingKey) {
576576
if (experimentalConditionalExports &&
577577
ObjectPrototype.hasOwnProperty(target, 'require')) {
578578
try {
579-
return resolveExportsTarget(pkgPath, target.require, subpath,
580-
basePath, mappingKey);
579+
const result = resolveExportsTarget(pkgPath, target.require, subpath,
580+
basePath, mappingKey);
581+
emitExperimentalWarning('Conditional exports');
582+
return result;
581583
} catch (e) {
582584
if (e.code !== 'MODULE_NOT_FOUND') throw e;
583585
}
584586
}
585587
if (experimentalConditionalExports &&
586588
ObjectPrototype.hasOwnProperty(target, 'node')) {
587589
try {
588-
return resolveExportsTarget(pkgPath, target.node, subpath,
589-
basePath, mappingKey);
590+
const result = resolveExportsTarget(pkgPath, target.node, subpath,
591+
basePath, mappingKey);
592+
emitExperimentalWarning('Conditional exports');
593+
return result;
590594
} catch (e) {
591595
if (e.code !== 'MODULE_NOT_FOUND') throw e;
592596
}
@@ -689,6 +693,7 @@ Module._findPath = function(request, paths, isMain) {
689693

690694
const selfFilename = trySelf(paths, exts, isMain, trailingSlash, request);
691695
if (selfFilename) {
696+
emitExperimentalWarning('Package name self resolution');
692697
Module._pathCache[cacheKey] = selfFilename;
693698
return selfFilename;
694699
}

lib/internal/modules/esm/translators.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const createDynamicModule = require(
2222
const fs = require('fs');
2323
const { fileURLToPath, URL } = require('url');
2424
const { debuglog } = require('internal/util/debuglog');
25-
const { promisify } = require('internal/util');
25+
const { promisify, emitExperimentalWarning } = require('internal/util');
2626
const {
2727
ERR_INVALID_URL,
2828
ERR_INVALID_URL_SCHEME,
@@ -134,6 +134,7 @@ translators.set('builtin', async function builtinStrategy(url) {
134134

135135
// Strategy for loading a JSON file
136136
translators.set('json', async function jsonStrategy(url) {
137+
emitExperimentalWarning('Importing JSON modules');
137138
debug(`Translating JSONModule ${url}`);
138139
debug(`Loading JSONModule ${url}`);
139140
const pathname = url.startsWith('file:') ? fileURLToPath(url) : null;
@@ -188,6 +189,7 @@ translators.set('json', async function jsonStrategy(url) {
188189

189190
// Strategy for loading a wasm module
190191
translators.set('wasm', async function(url) {
192+
emitExperimentalWarning('Importing Web Assembly modules');
191193
const buffer = await getSource(url);
192194
debug(`Translating WASMModule ${url}`);
193195
let compiled;

src/module_wrap.cc

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "util-inl.h"
88
#include "node_contextify.h"
99
#include "node_watchdog.h"
10+
#include "node_process.h"
1011

1112
#include <sys/stat.h> // S_IFDIR
1213

@@ -962,6 +963,7 @@ Maybe<URL> ResolveExportsTarget(Environment* env,
962963
Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url,
963964
conditionalTarget, subpath, pkg_subpath, base, false);
964965
if (!resolved.IsNothing()) {
966+
ProcessEmitExperimentalWarning(env, "Conditional exports");
965967
return resolved;
966968
}
967969
}
@@ -1267,6 +1269,7 @@ Maybe<URL> PackageResolve(Environment* env,
12671269

12681270
Maybe<URL> self_url = ResolveSelf(env, specifier, base);
12691271
if (self_url.IsJust()) {
1272+
ProcessEmitExperimentalWarning(env, "Package name self resolution");
12701273
return self_url;
12711274
}
12721275

src/node_process.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ v8::Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
2727
const char* code = nullptr);
2828

2929
v8::Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...);
30+
v8::Maybe<bool> ProcessEmitExperimentalWarning(Environment* env,
31+
const char* warning);
3032
v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
3133
const char* warning,
3234
const char* deprecation_code);

src/node_process_events.cc

+16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cstdarg>
2+
#include <set>
23

34
#include "env-inl.h"
45
#include "node_process.h"
@@ -93,6 +94,21 @@ Maybe<bool> ProcessEmitWarning(Environment* env, const char* fmt, ...) {
9394
return ProcessEmitWarningGeneric(env, warning);
9495
}
9596

97+
98+
std::set<std::string> experimental_warnings;
99+
100+
Maybe<bool> ProcessEmitExperimentalWarning(Environment* env,
101+
const char* warning) {
102+
if (experimental_warnings.find(warning) != experimental_warnings.end())
103+
return Nothing<bool>();
104+
105+
experimental_warnings.insert(warning);
106+
std::string message(warning);
107+
message.append(
108+
" is an experimental feature. This feature could change at any time");
109+
return ProcessEmitWarningGeneric(env, message.c_str(), "ExperimentalWarning");
110+
}
111+
96112
Maybe<bool> ProcessEmitDeprecationWarning(Environment* env,
97113
const char* warning,
98114
const char* deprecation_code) {

test/common/fixtures.mjs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* eslint-disable node-core/require-common-first, node-core/required-modules */
2+
import fixtures from './fixtures.js';
3+
4+
const {
5+
fixturesDir,
6+
path,
7+
readSync,
8+
readKey,
9+
} = fixtures;
10+
11+
export {
12+
fixturesDir,
13+
path,
14+
readSync,
15+
readKey,
16+
};

test/es-module/test-esm-exports.mjs

+36
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Flags: --experimental-modules --experimental-resolve-self --experimental-conditional-exports
22

33
import { mustCall } from '../common/index.mjs';
4+
import { path } from '../common/fixtures.mjs';
45
import { ok, deepStrictEqual, strictEqual } from 'assert';
6+
import { spawn } from 'child_process';
57

68
import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs';
79
import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js';
@@ -150,3 +152,37 @@ function assertIncludes(actual, expected) {
150152
ok(actual.toString().indexOf(expected) !== -1,
151153
`${JSON.stringify(actual)} includes ${JSON.stringify(expected)}`);
152154
}
155+
156+
// Test warning message
157+
[
158+
[
159+
'--experimental-conditional-exports',
160+
'/es-modules/conditional-exports.js',
161+
'Conditional exports',
162+
],
163+
[
164+
'--experimental-resolve-self',
165+
'/node_modules/pkgexports/resolve-self.js',
166+
'Package name self resolution',
167+
],
168+
].forEach(([flag, file, message]) => {
169+
const child = spawn(process.execPath, [
170+
'--experimental-modules',
171+
flag,
172+
path(file)
173+
]);
174+
175+
let stderr = '';
176+
child.stderr.setEncoding('utf8');
177+
child.stderr.on('data', (data) => {
178+
stderr += data;
179+
});
180+
child.on('close', (code, signal) => {
181+
strictEqual(code, 0);
182+
strictEqual(signal, null);
183+
ok(stderr.toString().includes(
184+
`ExperimentalWarning: ${message} is an experimental feature. ` +
185+
'This feature could change at any time'
186+
));
187+
});
188+
});

test/es-module/test-esm-json.mjs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
// Flags: --experimental-modules --experimental-json-modules
22
import '../common/index.mjs';
3-
import { strictEqual } from 'assert';
3+
import { path } from '../common/fixtures.mjs';
4+
import { strictEqual, ok } from 'assert';
5+
import { spawn } from 'child_process';
46

57
import secret from '../fixtures/experimental.json';
68

79
strictEqual(secret.ofLife, 42);
10+
11+
// Test warning message
12+
const child = spawn(process.execPath, [
13+
'--experimental-modules',
14+
'--experimental-json-modules',
15+
path('/es-modules/json-modules.mjs')
16+
]);
17+
18+
let stderr = '';
19+
child.stderr.setEncoding('utf8');
20+
child.stderr.on('data', (data) => {
21+
stderr += data;
22+
});
23+
child.on('close', (code, signal) => {
24+
strictEqual(code, 0);
25+
strictEqual(signal, null);
26+
ok(stderr.toString().includes(
27+
'ExperimentalWarning: Importing JSON modules is an experimental feature. ' +
28+
'This feature could change at any time'
29+
));
30+
});

test/es-module/test-esm-wasm.mjs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Flags: --experimental-modules --experimental-wasm-modules
22
import '../common/index.mjs';
3+
import { path } from '../common/fixtures.mjs';
34
import { add, addImported } from '../fixtures/es-modules/simple.wasm';
45
import { state } from '../fixtures/es-modules/wasm-dep.mjs';
5-
import { strictEqual } from 'assert';
6+
import { strictEqual, ok } from 'assert';
7+
import { spawn } from 'child_process';
68

79
strictEqual(state, 'WASM Start Executed');
810

@@ -13,3 +15,24 @@ strictEqual(addImported(0), 42);
1315
strictEqual(state, 'WASM JS Function Executed');
1416

1517
strictEqual(addImported(1), 43);
18+
19+
// Test warning message
20+
const child = spawn(process.execPath, [
21+
'--experimental-modules',
22+
'--experimental-wasm-modules',
23+
path('/es-modules/wasm-modules.mjs')
24+
]);
25+
26+
let stderr = '';
27+
child.stderr.setEncoding('utf8');
28+
child.stderr.on('data', (data) => {
29+
stderr += data;
30+
});
31+
child.on('close', (code, signal) => {
32+
strictEqual(code, 0);
33+
strictEqual(signal, null);
34+
ok(stderr.toString().includes(
35+
'ExperimentalWarning: Importing Web Assembly modules is ' +
36+
'an experimental feature. This feature could change at any time'
37+
));
38+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('pkgexports/condition')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import secret from '../experimental.json';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { add, addImported } from './simple.wasm';
2+
import { state } from './wasm-dep.mjs';

test/fixtures/node_modules/pkgexports/resolve-self.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)