From a48872acb726d1ac3cbd22790de038be5cb95178 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 1 Mar 2023 18:50:25 +0100 Subject: [PATCH] esm: add a runtime warning when using import assertions --- lib/internal/modules/esm/assert.js | 13 +++++++++++++ test/es-module/test-esm-import-assertion-errors.js | 7 +++++++ test/es-module/test-esm-import-assertion-errors.mjs | 10 +++++++++- .../test-esm-import-assertion-validation.js | 10 +++++++++- .../es-module/test-esm-import-assertion-warning.mjs | 10 ++++++++++ test/es-module/test-esm-json.mjs | 5 ++--- 6 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 test/es-module/test-esm-import-assertion-warning.mjs diff --git a/lib/internal/modules/esm/assert.js b/lib/internal/modules/esm/assert.js index caa2845475f6c7..3437aa1a61b86f 100644 --- a/lib/internal/modules/esm/assert.js +++ b/lib/internal/modules/esm/assert.js @@ -3,6 +3,7 @@ const { ArrayPrototypeFilter, ArrayPrototypeIncludes, + ObjectKeys, ObjectValues, ObjectPrototypeHasOwnProperty, } = primordials; @@ -17,6 +18,8 @@ const { // The HTML spec has an implied default type of `'javascript'`. const kImplicitAssertType = 'javascript'; +let alreadyWarned = false; + /** * Define a map of module formats to import assertion types (the value of * `type` in `assert { type: 'json' }`). @@ -55,6 +58,16 @@ function validateAssertions(url, format, importAssertions = { __proto__: null }) { const validType = formatTypeMap[format]; + if (!alreadyWarned && ObjectKeys(importAssertions).length !== 0) { + alreadyWarned = true; + process.emitWarning( + 'Import assertions are not a stable feature of the JavaScript language, ' + + 'avoid relying on their current behavior and syntax as those might change ' + + 'in a future version of Node.js.', + 'ExperimentalWarning', + ); + } + switch (validType) { case undefined: // Ignore assertions for module formats we don't recognize, to allow new diff --git a/test/es-module/test-esm-import-assertion-errors.js b/test/es-module/test-esm-import-assertion-errors.js index 2fb167aa0941e2..8d12a2d12b3955 100644 --- a/test/es-module/test-esm-import-assertion-errors.js +++ b/test/es-module/test-esm-import-assertion-errors.js @@ -5,6 +5,13 @@ const { rejects } = require('assert'); const jsModuleDataUrl = 'data:text/javascript,export{}'; const jsonModuleDataUrl = 'data:application/json,""'; +common.expectWarning( + 'ExperimentalWarning', + 'Import assertions are not a stable feature of the JavaScript language, ' + + 'avoid relying on their current behavior and syntax as those might change ' + + 'in a future version of Node.js.' +); + async function test() { await rejects( import('data:text/css,', { assert: { type: 'css' } }), diff --git a/test/es-module/test-esm-import-assertion-errors.mjs b/test/es-module/test-esm-import-assertion-errors.mjs index acaeef50626508..a6be862c49f074 100644 --- a/test/es-module/test-esm-import-assertion-errors.mjs +++ b/test/es-module/test-esm-import-assertion-errors.mjs @@ -1,9 +1,17 @@ -import '../common/index.mjs'; +import { expectWarning } from '../common/index.mjs'; import { rejects } from 'assert'; const jsModuleDataUrl = 'data:text/javascript,export{}'; const jsonModuleDataUrl = 'data:application/json,""'; +expectWarning( + 'ExperimentalWarning', + 'Import assertions are not a stable feature of the JavaScript language, ' + + 'avoid relying on their current behavior and syntax as those might change ' + + 'in a future version of Node.js.' +); + + await rejects( // This rejects because of the unsupported MIME type, not because of the // unsupported assertion. diff --git a/test/es-module/test-esm-import-assertion-validation.js b/test/es-module/test-esm-import-assertion-validation.js index 3792ad7ff1617c..462f1c527e4b1b 100644 --- a/test/es-module/test-esm-import-assertion-validation.js +++ b/test/es-module/test-esm-import-assertion-validation.js @@ -1,11 +1,19 @@ // Flags: --expose-internals 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const { validateAssertions } = require('internal/modules/esm/assert'); +common.expectWarning( + 'ExperimentalWarning', + 'Import assertions are not a stable feature of the JavaScript language, ' + + 'avoid relying on their current behavior and syntax as those might change ' + + 'in a future version of Node.js.' +); + + const url = 'test://'; assert.ok(validateAssertions(url, 'builtin', {})); diff --git a/test/es-module/test-esm-import-assertion-warning.mjs b/test/es-module/test-esm-import-assertion-warning.mjs new file mode 100644 index 00000000000000..739d246f620e6f --- /dev/null +++ b/test/es-module/test-esm-import-assertion-warning.mjs @@ -0,0 +1,10 @@ +import { expectWarning } from '../common/index.mjs'; + +expectWarning( + 'ExperimentalWarning', + 'Import assertions are not a stable feature of the JavaScript language, ' + + 'avoid relying on their current behavior and syntax as those might change ' + + 'in a future version of Node.js.' +); + +await import('data:text/javascript,', { assert: { someUnsupportedKey: 'value' } }); diff --git a/test/es-module/test-esm-json.mjs b/test/es-module/test-esm-json.mjs index 14c86bac80af98..2740c0097f77da 100644 --- a/test/es-module/test-esm-json.mjs +++ b/test/es-module/test-esm-json.mjs @@ -6,7 +6,6 @@ import { describe, it } from 'node:test'; import secret from '../fixtures/experimental.json' assert { type: 'json' }; - describe('ESM: importing JSON', () => { it('should load JSON', () => { assert.strictEqual(secret.ofLife, 42); @@ -17,8 +16,8 @@ describe('ESM: importing JSON', () => { fixtures.path('/es-modules/json-modules.mjs'), ]); - assert.match(stderr, /ExperimentalWarning/); - assert.match(stderr, /JSON modules/); + assert.match(stderr, /ExperimentalWarning: Importing JSON modules/); + assert.match(stderr, /ExperimentalWarning: Import assertions/); assert.strictEqual(code, 0); assert.strictEqual(signal, null); });