Skip to content

Commit 4829a10

Browse files
GeoffreyBoothbengl
authored andcommitted
esm: add runtime warning for specifier resolution flag
PR-URL: #42252 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Jacob Smith <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 88dee3c commit 4829a10

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

doc/api/esm.md

+12-7
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ of Node.js applications.
672672
673673
> Stability: 1 - Experimental
674674
675-
**Note: This API is currently being redesigned and will still change.**
675+
> This API is currently being redesigned and will still change.
676676
677677
<!-- type=misc -->
678678
@@ -693,7 +693,7 @@ changes:
693693
description: Add support for import assertions.
694694
-->
695695
696-
> Note: The loaders API is being redesigned. This hook may disappear or its
696+
> The loaders API is being redesigned. This hook may disappear or its
697697
> signature may change. Do not rely on the API described below.
698698
699699
* `specifier` {string}
@@ -766,10 +766,10 @@ export async function resolve(specifier, context, defaultResolve) {
766766

767767
#### `load(url, context, defaultLoad)`
768768

769-
> Note: The loaders API is being redesigned. This hook may disappear or its
769+
> The loaders API is being redesigned. This hook may disappear or its
770770
> signature may change. Do not rely on the API described below.
771771

772-
> Note: In a previous version of this API, this was split across 3 separate, now
772+
> In a previous version of this API, this was split across 3 separate, now
773773
> deprecated, hooks (`getFormat`, `getSource`, and `transformSource`).
774774

775775
* `url` {string}
@@ -807,7 +807,7 @@ overcome in the future.
807807
> are incompatible. Attempting to use them together will result in an empty
808808
> object from the import. This may be addressed in the future.
809809

810-
> Note: These types all correspond to classes defined in ECMAScript.
810+
> These types all correspond to classes defined in ECMAScript.
811811

812812
* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][].
813813
* The specific [`TypedArray`][] object is a [`Uint8Array`][].
@@ -857,10 +857,10 @@ source to a supported one (see [Examples](#examples) below).
857857

858858
#### `globalPreload()`
859859

860-
> Note: The loaders API is being redesigned. This hook may disappear or its
860+
> The loaders API is being redesigned. This hook may disappear or its
861861
> signature may change. Do not rely on the API described below.
862862

863-
> Note: In a previous version of this API, this hook was named
863+
> In a previous version of this API, this hook was named
864864
> `getGlobalPreloadCode`.
865865

866866
* Returns: {string}
@@ -1449,6 +1449,10 @@ _internal_, _conditions_)
14491449

14501450
> Stability: 1 - Experimental
14511451

1452+
> Do not rely on this flag. We plan to remove it once the
1453+
> [Loaders API][] has advanced to the point that equivalent functionality can
1454+
> be achieved via custom loaders.
1455+
14521456
The current specifier resolution does not support all default behavior of
14531457
the CommonJS loader. One of the behavior differences is automatic resolution
14541458
of file extensions and the ability to import directories that have an index
@@ -1481,6 +1485,7 @@ success!
14811485
[Import Assertions]: #import-assertions
14821486
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
14831487
[JSON modules]: #json-modules
1488+
[Loaders API]: #loaders
14841489
[Node.js Module Resolution Algorithm]: #resolver-algorithm-specification
14851490
[Terminology]: #terminology
14861491
[URL]: https://url.spec.whatwg.org/

lib/internal/modules/esm/formats.js

-12
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ const { getOptionValue } = require('internal/options');
77

88

99
const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
10-
const experimentalSpecifierResolution =
11-
getOptionValue('--experimental-specifier-resolution');
1210

1311
const extensionFormatMap = {
1412
'__proto__': null,
@@ -43,17 +41,7 @@ function mimeToFormat(mime) {
4341
return null;
4442
}
4543

46-
let experimentalSpecifierResolutionWarned = false;
4744
function getLegacyExtensionFormat(ext) {
48-
if (
49-
experimentalSpecifierResolution === 'node' &&
50-
!experimentalSpecifierResolutionWarned
51-
) {
52-
process.emitWarning(
53-
'The Node.js specifier resolution in ESM is experimental.',
54-
'ExperimentalWarning');
55-
experimentalSpecifierResolutionWarned = true;
56-
}
5745
return legacyExtensionFormatMap[ext];
5846
}
5947

lib/internal/modules/esm/resolve.js

+8
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ function resolveDirectoryEntry(search) {
362362
}
363363

364364
const encodedSepRegEx = /%2F|%5C/i;
365+
let experimentalSpecifierResolutionWarned = false;
365366
/**
366367
* @param {URL} resolved
367368
* @param {string | URL | undefined} base
@@ -376,6 +377,13 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
376377

377378
let path = fileURLToPath(resolved);
378379
if (getOptionValue('--experimental-specifier-resolution') === 'node') {
380+
if (!experimentalSpecifierResolutionWarned) {
381+
process.emitWarning(
382+
'The Node.js specifier resolution flag is experimental. It could change or be removed at any time.',
383+
'ExperimentalWarning');
384+
experimentalSpecifierResolutionWarned = true;
385+
}
386+
379387
let file = resolveExtensionsWithTryExactName(resolved);
380388

381389
// Directory
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { mustCall } from '../common/index.mjs';
2+
import { fileURL } from '../common/fixtures.mjs';
3+
import { match, strictEqual } from 'assert';
4+
import { spawn } from 'child_process';
5+
import { execPath } from 'process';
6+
7+
// Verify experimental warning is printed
8+
const child = spawn(execPath, [
9+
'--experimental-specifier-resolution=node',
10+
'--input-type=module',
11+
'--eval',
12+
`import ${JSON.stringify(fileURL('es-module-specifiers', 'package-type-module'))}`,
13+
]);
14+
15+
let stderr = '';
16+
child.stderr.setEncoding('utf8');
17+
child.stderr.on('data', (data) => {
18+
stderr += data;
19+
});
20+
child.on('close', mustCall((code, signal) => {
21+
strictEqual(code, 0);
22+
strictEqual(signal, null);
23+
match(stderr, /ExperimentalWarning: The Node\.js specifier resolution flag is experimental/);
24+
}));

0 commit comments

Comments
 (0)