Skip to content

Commit a30e0de

Browse files
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 82342c2 commit a30e0de

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

doc/api/esm.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ of Node.js applications.
677677
678678
> Stability: 1 - Experimental
679679
680-
**Note: This API is currently being redesigned and will still change.**
680+
> This API is currently being redesigned and will still change.
681681
682682
<!-- type=misc -->
683683
@@ -700,7 +700,7 @@ changes:
700700
description: Add support for import assertions.
701701
-->
702702
703-
> Note: The loaders API is being redesigned. This hook may disappear or its
703+
> The loaders API is being redesigned. This hook may disappear or its
704704
> signature may change. Do not rely on the API described below.
705705
706706
* `specifier` {string}
@@ -773,10 +773,10 @@ export async function resolve(specifier, context, defaultResolve) {
773773

774774
#### `load(url, context, defaultLoad)`
775775

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

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

782782
* `url` {string}
@@ -814,7 +814,7 @@ overcome in the future.
814814
> are incompatible. Attempting to use them together will result in an empty
815815
> object from the import. This may be addressed in the future.
816816

817-
> Note: These types all correspond to classes defined in ECMAScript.
817+
> These types all correspond to classes defined in ECMAScript.
818818

819819
* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][].
820820
* The specific [`TypedArray`][] object is a [`Uint8Array`][].
@@ -864,10 +864,10 @@ source to a supported one (see [Examples](#examples) below).
864864

865865
#### `globalPreload()`
866866

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

870-
> Note: In a previous version of this API, this hook was named
870+
> In a previous version of this API, this hook was named
871871
> `getGlobalPreloadCode`.
872872

873873
* Returns: {string}
@@ -1456,6 +1456,10 @@ _internal_, _conditions_)
14561456

14571457
> Stability: 1 - Experimental
14581458

1459+
> Do not rely on this flag. We plan to remove it once the
1460+
> [Loaders API][] has advanced to the point that equivalent functionality can
1461+
> be achieved via custom loaders.
1462+
14591463
The current specifier resolution does not support all default behavior of
14601464
the CommonJS loader. One of the behavior differences is automatic resolution
14611465
of file extensions and the ability to import directories that have an index
@@ -1488,6 +1492,7 @@ success!
14881492
[Import Assertions]: #import-assertions
14891493
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
14901494
[JSON modules]: #json-modules
1495+
[Loaders API]: #loaders
14911496
[Node.js Module Resolution Algorithm]: #resolver-algorithm-specification
14921497
[Terminology]: #terminology
14931498
[URL]: https://url.spec.whatwg.org/

lib/internal/modules/esm/formats.js

Lines changed: 0 additions & 12 deletions
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

Lines changed: 8 additions & 0 deletions
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
Lines changed: 24 additions & 0 deletions
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)