Skip to content

Commit 25017ca

Browse files
GeoffreyBoothdanielleadams
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 d301a88 commit 25017ca

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
@@ -667,7 +667,7 @@ of Node.js applications.
667667
668668
> Stability: 1 - Experimental
669669
670-
**Note: This API is currently being redesigned and will still change.**
670+
> This API is currently being redesigned and will still change.
671671
672672
<!-- type=misc -->
673673
@@ -688,7 +688,7 @@ changes:
688688
description: Add support for import assertions.
689689
-->
690690
691-
> Note: The loaders API is being redesigned. This hook may disappear or its
691+
> The loaders API is being redesigned. This hook may disappear or its
692692
> signature may change. Do not rely on the API described below.
693693
694694
* `specifier` {string}
@@ -761,10 +761,10 @@ export async function resolve(specifier, context, defaultResolve) {
761761

762762
#### `load(url, context, defaultLoad)`
763763

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

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

770770
* `url` {string}
@@ -802,7 +802,7 @@ overcome in the future.
802802
> are incompatible. Attempting to use them together will result in an empty
803803
> object from the import. This may be addressed in the future.
804804

805-
> Note: These types all correspond to classes defined in ECMAScript.
805+
> These types all correspond to classes defined in ECMAScript.
806806

807807
* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][].
808808
* The specific [`TypedArray`][] object is a [`Uint8Array`][].
@@ -852,10 +852,10 @@ source to a supported one (see [Examples](#examples) below).
852852

853853
#### `globalPreload()`
854854

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

858-
> Note: In a previous version of this API, this hook was named
858+
> In a previous version of this API, this hook was named
859859
> `getGlobalPreloadCode`.
860860

861861
* Returns: {string}
@@ -1465,6 +1465,10 @@ _internal_, _conditions_)
14651465

14661466
> Stability: 1 - Experimental
14671467

1468+
> Do not rely on this flag. We plan to remove it once the
1469+
> [Loaders API][] has advanced to the point that equivalent functionality can
1470+
> be achieved via custom loaders.
1471+
14681472
The current specifier resolution does not support all default behavior of
14691473
the CommonJS loader. One of the behavior differences is automatic resolution
14701474
of file extensions and the ability to import directories that have an index
@@ -1497,6 +1501,7 @@ success!
14971501
[Import Assertions]: #import-assertions
14981502
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
14991503
[JSON modules]: #json-modules
1504+
[Loaders API]: #loaders
15001505
[Node.js Module Resolution Algorithm]: #resolver-algorithm-specification
15011506
[Terminology]: #terminology
15021507
[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
@@ -386,6 +386,7 @@ function resolveDirectoryEntry(search) {
386386
}
387387

388388
const encodedSepRegEx = /%2F|%5C/i;
389+
let experimentalSpecifierResolutionWarned = false;
389390
/**
390391
* @param {URL} resolved
391392
* @param {string | URL | undefined} base
@@ -400,6 +401,13 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
400401

401402
let path = fileURLToPath(resolved);
402403
if (getOptionValue('--experimental-specifier-resolution') === 'node') {
404+
if (!experimentalSpecifierResolutionWarned) {
405+
process.emitWarning(
406+
'The Node.js specifier resolution flag is experimental. It could change or be removed at any time.',
407+
'ExperimentalWarning');
408+
experimentalSpecifierResolutionWarned = true;
409+
}
410+
403411
let file = resolveExtensionsWithTryExactName(resolved);
404412

405413
// 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)