Repository: nodejs/node
Pull request: esm: mark import attributes and JSON module as stable

The two proposals reached stage 4 yesterday, at the October 2024 meeting. The Node.js implementation already matches exactly the semantics required by the proposals. This PR can/should be backported to 22 and 20 (and 18?).

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: doc/api/esm.md
patch: @@ -270,13 +270,9 @@ changes:
     description: Switch from Import Assertions to Import Attributes.
 -->
 
-> Stability: 1.1 - Active development
-
-> This feature was previously named "Import assertions", and using the `assert`
-> keyword instead of `with`. Any uses in code of the prior `assert` keyword
-> should be updated to use `with` instead.
+> Stability: 2 - Stable
 
-The [Import Attributes proposal][] adds an inline syntax for module import
+[Import attributes][Import Attributes MDN] are an inline syntax for module import
 statements to pass on more information alongside the module specifier.
 
 ```js
@@ -286,13 +282,14 @@ const { default: barData } =
   await import('./bar.json', { with: { type: 'json' } });
 ```
 
-Node.js supports the following `type` values, for which the attribute is
-mandatory:
+Node.js only supports the `type` attribute, for which it supports the following values:
 
 | Attribute `type` | Needed for       |
 | ---------------- | ---------------- |
 | `'json'`         | [JSON modules][] |
 
+The `type: 'json'` attribute is mandatory when importing JSON modules.
+
 ## Built-in modules
 
 [Built-in modules][] provide named exports of their public API. A
@@ -631,7 +628,7 @@ separate cache.
 
 ## JSON modules
 
-> Stability: 1 - Experimental
+> Stability: 2 - Stable
 
 JSON files can be referenced by `import`:
 
@@ -1101,7 +1098,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
 [Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
 [ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration
 [Import Attributes]: #import-attributes
-[Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes
+[Import Attributes MDN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import/with
 [JSON modules]: #json-modules
 [Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require
 [Module customization hooks]: module.md#customization-hooks

filename: lib/internal/modules/esm/translators.js
patch: @@ -365,7 +365,6 @@ translators.set('builtin', function builtinStrategy(url) {
 
 // Strategy for loading a JSON file
 translators.set('json', function jsonStrategy(url, source) {
-  emitExperimentalWarning('Importing JSON modules');
   assertBufferSource(source, true, 'load');
   debug(`Loading JSONModule ${url}`);
   const pathname = StringPrototypeStartsWith(url, 'file:') ?

filename: test/es-module/test-esm-json.mjs
patch: @@ -16,12 +16,12 @@ describe('ESM: importing JSON', () => {
     assert.strictEqual(secret.ofLife, 42);
   });
 
-  it('should print an experimental warning', async () => {
+  it('should not print an experimental warning', async () => {
     const { code, signal, stderr } = await spawnPromisified(execPath, [
       fixtures.path('/es-modules/json-modules.mjs'),
     ]);
 
-    assert.match(stderr, /ExperimentalWarning: Importing JSON modules/);
+    assert.strictEqual(stderr, '');
     assert.strictEqual(code, 0);
     assert.strictEqual(signal, null);
   });