diff --git a/doc/api/errors.md b/doc/api/errors.md index 9c88b7d7d4de0f..4e776380beb766 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1762,7 +1762,8 @@ added: - v16.14.0 --> -An import assertion has failed, preventing the specified module to be imported. +An import `type` attribute was provided, but the specified module is of a +different type. @@ -1774,7 +1775,7 @@ added: - v16.14.0 --> -An import assertion is missing, preventing the specified module to be imported. +An import attribute is missing, preventing the specified module to be imported. @@ -1786,7 +1787,17 @@ added: - v16.14.0 --> -An import assertion is not supported by this version of Node.js. +An import attribute is not supported by this version of Node.js. + + + +### `ERR_IMPORT_ATTRIBUTE_UNSUPPORTED` + + + +An import attribute is not supported by this version of Node.js. diff --git a/doc/api/esm.md b/doc/api/esm.md index 8f147b9c2445b2..d9f9ccf8d1ab85 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -15,7 +15,7 @@ changes: - v17.1.0 - v16.14.0 pr-url: https://github.com/nodejs/node/pull/40250 - description: Add support for import assertions. + description: Add experimental support for import assertions. - version: - v17.0.0 - v16.12.0 @@ -230,7 +230,9 @@ absolute URL strings. import fs from 'node:fs/promises'; ``` -## Import assertions + + +## Import attributes -> Stability: 1 - Experimental +> Stability: 1.1 - Active development + +> This feature was previously named "Import assertions", and using the `assert` +> keyword instead of `with`. Because the version of V8 on this release line does +> not support the `with` keyword, you need to keep using `assert` to support +> this version of Node.js. -The [Import Assertions proposal][] adds an inline syntax for module import +The [Import Attributes proposal][] adds an inline syntax for module import statements to pass on more information alongside the module specifier. ```js @@ -250,10 +257,10 @@ const { default: barData } = await import('./bar.json', { assert: { type: 'json' } }); ``` -Node.js supports the following `type` values, for which the assertion is +Node.js supports the following `type` values, for which the attribute is mandatory: -| Assertion `type` | Needed for | +| Attribute `type` | Needed for | | ---------------- | ---------------- | | `'json'` | [JSON modules][] | @@ -529,7 +536,7 @@ JSON files can be referenced by `import`: import packageConfig from './package.json' assert { type: 'json' }; ``` -The `assert { type: 'json' }` syntax is mandatory; see [Import Assertions][]. +The `assert { type: 'json' }` syntax is mandatory; see [Import Attributes][]. The imported JSON only exposes a `default` export. There is no support for named exports. A cache entry is created in the CommonJS cache to avoid duplication. @@ -732,6 +739,11 @@ prevent unintentional breaks in the chain. + * `linker` {Function} * `specifier` {string} The specifier of the requested module: ```mjs @@ -623,15 +631,14 @@ The identifier of the current module, as set in the constructor. * `referencingModule` {vm.Module} The `Module` object `link()` is called on. * `extra` {Object} - * `assert` {Object} The data from the assertion: - - ```js + * `attributes` {Object} The data from the attribute: + ```mjs import foo from 'foo' assert { name: 'value' }; - // ^^^^^^^^^^^^^^^^^ the assertion + // ^^^^^^^^^^^^^^^^^ the attribute ``` - Per ECMA-262, hosts are expected to ignore assertions that they do not - support, as opposed to, for example, triggering an error if an - unsupported assertion is present. + Per ECMA-262, hosts are expected to trigger an error if an + unsupported attribute is present. + * `assert` {Object} Alias for `extra.attributes`. * Returns: {vm.Module|Promise} * Returns: {Promise} @@ -730,7 +737,7 @@ changes: - v17.0.0 - v16.12.0 pr-url: https://github.com/nodejs/node/pull/40249 - description: Added support for import assertions to the + description: Added support for import attributes to the `importModuleDynamically` parameter. --> @@ -760,7 +767,7 @@ changes: `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. * `specifier` {string} specifier passed to `import()` * `module` {vm.Module} - * `importAssertions` {Object} The `"assert"` value passed to the + * `importAttributes` {Object} The `"assert"` value passed to the [`optionsExpression`][] optional parameter, or an empty object if no value was provided. * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -974,7 +981,7 @@ changes: - v17.0.0 - v16.12.0 pr-url: https://github.com/nodejs/node/pull/40249 - description: Added support for import assertions to the + description: Added support for import attributes to the `importModuleDynamically` parameter. - version: v15.9.0 pr-url: https://github.com/nodejs/node/pull/35431 @@ -1018,7 +1025,7 @@ changes: considered stable. * `specifier` {string} specifier passed to `import()` * `function` {Function} - * `importAssertions` {Object} The `"assert"` value passed to the + * `importAttributes` {Object} The `"assert"` value passed to the [`optionsExpression`][] optional parameter, or an empty object if no value was provided. * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -1204,7 +1211,7 @@ changes: - v17.0.0 - v16.12.0 pr-url: https://github.com/nodejs/node/pull/40249 - description: Added support for import assertions to the + description: Added support for import attributes to the `importModuleDynamically` parameter. - version: v6.3.0 pr-url: https://github.com/nodejs/node/pull/6635 @@ -1242,7 +1249,7 @@ changes: using it in a production environment. * `specifier` {string} specifier passed to `import()` * `script` {vm.Script} - * `importAssertions` {Object} The `"assert"` value passed to the + * `importAttributes` {Object} The `"assert"` value passed to the [`optionsExpression`][] optional parameter, or an empty object if no value was provided. * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -1282,7 +1289,7 @@ changes: - v17.0.0 - v16.12.0 pr-url: https://github.com/nodejs/node/pull/40249 - description: Added support for import assertions to the + description: Added support for import attributes to the `importModuleDynamically` parameter. - version: v14.6.0 pr-url: https://github.com/nodejs/node/pull/34023 @@ -1341,7 +1348,7 @@ changes: using it in a production environment. * `specifier` {string} specifier passed to `import()` * `script` {vm.Script} - * `importAssertions` {Object} The `"assert"` value passed to the + * `importAttributes` {Object} The `"assert"` value passed to the [`optionsExpression`][] optional parameter, or an empty object if no value was provided. * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -1385,7 +1392,7 @@ changes: - v17.0.0 - v16.12.0 pr-url: https://github.com/nodejs/node/pull/40249 - description: Added support for import assertions to the + description: Added support for import attributes to the `importModuleDynamically` parameter. - version: v6.3.0 pr-url: https://github.com/nodejs/node/pull/6635 @@ -1421,7 +1428,7 @@ changes: using it in a production environment. * `specifier` {string} specifier passed to `import()` * `script` {vm.Script} - * `importAssertions` {Object} The `"assert"` value passed to the + * `importAttributes` {Object} The `"assert"` value passed to the [`optionsExpression`][] optional parameter, or an empty object if no value was provided. * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 63536dee1af393..76a806711536a3 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1177,12 +1177,17 @@ E('ERR_HTTP_SOCKET_ENCODING', E('ERR_HTTP_TRAILER_INVALID', 'Trailers are invalid with this transfer encoding', Error); E('ERR_ILLEGAL_CONSTRUCTOR', 'Illegal constructor', TypeError); +// TODO(aduh95): change the error to mention import attributes instead of import assertions. E('ERR_IMPORT_ASSERTION_TYPE_FAILED', 'Module "%s" is not of type "%s"', TypeError); +// TODO(aduh95): change the error to mention import attributes instead of import assertions. E('ERR_IMPORT_ASSERTION_TYPE_MISSING', - 'Module "%s" needs an import assertion of type "%s"', TypeError); + 'Module "%s" needs an import attribute of type "%s"', TypeError); +// TODO(aduh95): change the error to mention import attributes instead of import assertions. E('ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED', - 'Import assertion type "%s" is unsupported', TypeError); + 'Import attribute type "%s" is unsupported', TypeError); +E('ERR_IMPORT_ATTRIBUTE_UNSUPPORTED', + 'Import attribute "%s" with value "%s" is not supported', TypeError); E('ERR_INCOMPATIBLE_OPTION_PAIR', 'Option "%s" cannot be used in combination with option "%s"', TypeError); E('ERR_INPUT_TYPE_NOT_ALLOWED', '--input-type can only be used with string ' + diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 88bb870a8fd2e5..4ec63e9c695dd7 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1157,10 +1157,10 @@ function wrapSafe(filename, content, cjsModuleInstance) { const script = new Script(wrapper, { filename, lineOffset: 0, - importModuleDynamically: async (specifier, _, importAssertions) => { + importModuleDynamically: async (specifier, _, importAttributes) => { const loader = asyncESM.esmLoader; return loader.import(specifier, normalizeReferrerURL(filename), - importAssertions); + importAttributes); }, }); @@ -1183,10 +1183,10 @@ function wrapSafe(filename, content, cjsModuleInstance) { '__dirname', ], { filename, - importModuleDynamically(specifier, _, importAssertions) { + importModuleDynamically(specifier, _, importAttributes) { const loader = asyncESM.esmLoader; return loader.import(specifier, normalizeReferrerURL(filename), - importAssertions); + importAttributes); }, }); diff --git a/lib/internal/modules/esm/assert.js b/lib/internal/modules/esm/assert.js index b1267a10a7a6b2..4a82de4c794162 100644 --- a/lib/internal/modules/esm/assert.js +++ b/lib/internal/modules/esm/assert.js @@ -3,7 +3,6 @@ const { ArrayPrototypeFilter, ArrayPrototypeIncludes, - ObjectCreate, ObjectKeys, ObjectValues, ObjectPrototypeHasOwnProperty, @@ -14,16 +13,15 @@ const { ERR_IMPORT_ASSERTION_TYPE_FAILED, ERR_IMPORT_ASSERTION_TYPE_MISSING, ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED, + ERR_IMPORT_ATTRIBUTE_UNSUPPORTED, } = require('internal/errors').codes; // 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' }`). + * Define a map of module formats to import attributes types (the value of + * `type` in `with { type: 'json' }`). * @type {Map} */ const formatTypeMap = { @@ -32,7 +30,7 @@ const formatTypeMap = { 'commonjs': kImplicitAssertType, 'json': 'json', 'module': kImplicitAssertType, - 'wasm': kImplicitAssertType, // It's unclear whether the HTML spec will require an assertion type or not for Wasm; see https://github.com/WebAssembly/esm-integration/issues/42 + 'wasm': kImplicitAssertType, // It's unclear whether the HTML spec will require an attribute type or not for Wasm; see https://github.com/WebAssembly/esm-integration/issues/42 }; /** @@ -41,60 +39,56 @@ const formatTypeMap = { * `import './file.js' assert { type: 'javascript' }` throws. * @type {Array} */ -const supportedAssertionTypes = ArrayPrototypeFilter( +const supportedAttributesTypes = ArrayPrototypeFilter( ObjectValues(formatTypeMap), (type) => type !== kImplicitAssertType); /** - * Test a module's import assertions. + * Test a module's import attributes. * @param {string} url The URL of the imported module, for error reporting. * @param {string} format One of Node's supported translators - * @param {Record} importAssertions Validations for the + * @param {Record} importAttributes Validations for the * module import. * @returns {true} * @throws {TypeError} If the format and assertion type are incompatible. */ -function validateAssertions(url, format, - importAssertions = ObjectCreate(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', - ); +function validateAttributes(url, format, + importAttributes = { __proto__: null }) { + const keys = ObjectKeys(importAttributes); + for (let i = 0; i < keys.length; i++) { + if (keys[i] !== 'type') { + throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED(keys[i], importAttributes[keys[i]]); + } } + const validType = formatTypeMap[format]; switch (validType) { case undefined: - // Ignore assertions for module formats we don't recognize, to allow new + // Ignore attributes for module formats we don't recognize, to allow new // formats in the future. return true; case kImplicitAssertType: // This format doesn't allow an import assertion type, so the property - // must not be set on the import assertions object. - if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) { + // must not be set on the import attributes object. + if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) { return true; } - return handleInvalidType(url, importAssertions.type); + return handleInvalidType(url, importAttributes.type); - case importAssertions.type: + case importAttributes.type: // The asserted type is the valid type for this format. return true; default: // There is an expected type for this format, but the value of - // `importAssertions.type` might not have been it. - if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) { + // `importAttributes.type` might not have been it. + if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) { // `type` wasn't specified at all. throw new ERR_IMPORT_ASSERTION_TYPE_MISSING(url, validType); } - return handleInvalidType(url, importAssertions.type); + return handleInvalidType(url, importAttributes.type); } } @@ -108,7 +102,7 @@ function handleInvalidType(url, type) { validateString(type, 'type'); // `type` might not have been one of the types we understand. - if (!ArrayPrototypeIncludes(supportedAssertionTypes, type)) { + if (!ArrayPrototypeIncludes(supportedAttributesTypes, type)) { throw new ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED(type); } @@ -119,5 +113,5 @@ function handleInvalidType(url, type) { module.exports = { kImplicitAssertType, - validateAssertions, + validateAttributes, }; diff --git a/lib/internal/modules/esm/load.js b/lib/internal/modules/esm/load.js index 71a9f8da0b49f3..f5dfd0891a06f3 100644 --- a/lib/internal/modules/esm/load.js +++ b/lib/internal/modules/esm/load.js @@ -7,7 +7,7 @@ const { } = primordials; const { defaultGetFormat } = require('internal/modules/esm/get_format'); -const { validateAssertions } = require('internal/modules/esm/assert'); +const { validateAttributes, emitImportAssertionWarning } = require('internal/modules/esm/assert'); const { getOptionValue } = require('internal/options'); const { fetchModule } = require('internal/modules/esm/fetch_module'); @@ -76,19 +76,29 @@ async function getSource(url, context) { */ async function defaultLoad(url, context) { let responseURL = url; - const { importAssertions } = context; let { + importAttributes, format, source, } = context; + if (importAttributes == null && !('importAttributes' in context) && 'importAssertions' in context) { + emitImportAssertionWarning(); + importAttributes = context.importAssertions; + // Alias `importAssertions` to `importAttributes` + context = { + ...context, + importAttributes, + }; + } + const urlInstance = new URL(url); throwIfUnsupportedURLScheme(urlInstance, experimentalNetworkImports); format ??= await defaultGetFormat(urlInstance, context); - validateAssertions(url, format, importAssertions); + validateAttributes(url, format, importAttributes); if ( format === 'builtin' || diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 32b34ee8478e37..b865b38c0a1d4c 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -13,6 +13,7 @@ const { ObjectCreate, ObjectDefineProperty, ObjectSetPrototypeOf, + ReflectSet, RegExpPrototypeExec, SafePromiseAllReturnArrayLike, SafeWeakMap, @@ -56,6 +57,30 @@ const { translators } = require( 'internal/modules/esm/translators'); const { getOptionValue } = require('internal/options'); +let importAssertionAlreadyWarned = false; + +function emitImportAssertionWarning() { + if (!importAssertionAlreadyWarned) { + importAssertionAlreadyWarned = true; + process.emitWarning('Use `importAttributes` instead of `importAssertions`', 'ExperimentalWarning'); + } +} + +function defineImportAssertionAlias(context) { + return ObjectDefineProperty(context, 'importAssertions', { + __proto__: null, + configurable: true, + get() { + emitImportAssertionWarning(); + return this.importAttributes; + }, + set(value) { + emitImportAssertionWarning(); + return ReflectSet(this, 'importAttributes', value); + }, + }); +} + /** * @typedef {object} ExportedHooks * @property {Function} globalPreload Global preload hook. @@ -377,8 +402,8 @@ class ESMLoader { const { ModuleWrap, callbackMap } = internalBinding('module_wrap'); const module = new ModuleWrap(url, undefined, source, 0, 0); callbackMap.set(module, { - importModuleDynamically: (specifier, { url }, importAssertions) => { - return this.import(specifier, url, importAssertions); + importModuleDynamically: (specifier, { url }, importAttributes) => { + return this.import(specifier, url, importAttributes); }, }); @@ -403,27 +428,27 @@ class ESMLoader { * @param {string | undefined} parentURL The URL of the module importing this * one, unless this is the Node.js entry * point. - * @param {Record} importAssertions Validations for the + * @param {Record} importAttributes Validations for the * module import. * @returns {Promise} The (possibly pending) module job */ - async getModuleJob(specifier, parentURL, importAssertions) { - let importAssertionsForResolve; + async getModuleJob(specifier, parentURL, importAttributes) { + let importAttributesForResolve; // By default, `this.#hooks.load` contains just the Node default load hook if (this.#hooks.load.length !== 1) { // We can skip cloning if there are no user-provided loaders because - // the Node.js default resolve hook does not use import assertions. - importAssertionsForResolve = { + // the Node.js default resolve hook does not use import attributes. + importAttributesForResolve = { __proto__: null, - ...importAssertions, + ...importAttributes, }; } const { format, url } = - await this.resolve(specifier, parentURL, importAssertionsForResolve); + await this.resolve(specifier, parentURL, importAttributesForResolve); - let job = this.moduleMap.get(url, importAssertions.type); + let job = this.moduleMap.get(url, importAttributes.type); // CommonJS will set functions for lazy job evaluation. if (typeof job === 'function') { @@ -431,7 +456,7 @@ class ESMLoader { } if (job === undefined) { - job = this.#createModuleJob(url, importAssertions, parentURL, format); + job = this.#createModuleJob(url, importAttributes, parentURL, format); } return job; @@ -440,7 +465,7 @@ class ESMLoader { /** * Create and cache an object representing a loaded module. * @param {string} url The absolute URL that was resolved for this module - * @param {Record} importAssertions Validations for the + * @param {Record} importAttributes Validations for the * module import. * @param {string} [parentURL] The absolute URL of the module importing this * one, unless this is the Node.js entry point @@ -448,16 +473,16 @@ class ESMLoader { * `resolve` hook * @returns {Promise} The (possibly pending) module job */ - #createModuleJob(url, importAssertions, parentURL, format) { + #createModuleJob(url, importAttributes, parentURL, format) { const moduleProvider = async (url, isMain) => { const { format: finalFormat, responseURL, source, - } = await this.load(url, { + } = await this.load(url, defineImportAssertionAlias({ format, - importAssertions, - }); + importAttributes, + })); const translator = translators.get(finalFormat); @@ -480,13 +505,13 @@ class ESMLoader { const job = new ModuleJob( this, url, - importAssertions, + importAttributes, moduleProvider, parentURL === undefined, inspectBrk, ); - this.moduleMap.set(url, importAssertions.type, job); + this.moduleMap.set(url, importAttributes.type, job); return job; } @@ -499,13 +524,13 @@ class ESMLoader { * loader module. * @param {string | string[]} specifiers Path(s) to the module. * @param {string} parentURL Path of the parent importing the module. - * @param {Record} importAssertions Validations for the + * @param {Record} importAttributes Validations for the * module import. * @returns {Promise} * A collection of module export(s) or a list of collections of module * export(s). */ - async import(specifiers, parentURL, importAssertions) { + async import(specifiers, parentURL, importAttributes) { // For loaders, `import` is passed multiple things to process, it returns a // list pairing the url and exports collected. This is especially useful for // error messaging, to identity from where an export came. But, in most @@ -521,7 +546,7 @@ class ESMLoader { const jobs = new Array(count); for (let i = 0; i < count; i++) { - jobs[i] = this.getModuleJob(specifiers[i], parentURL, importAssertions) + jobs[i] = this.getModuleJob(specifiers[i], parentURL, importAttributes) .then((job) => job.run()) .then(({ module }) => module.getNamespace()); } @@ -779,11 +804,11 @@ class ESMLoader { * @param {string} originalSpecifier The specified URL path of the module to * be resolved. * @param {string} [parentURL] The URL path of the module's parent. - * @param {ImportAssertions} importAssertions Assertions from the import + * @param {ImportAttributes} importAttributes Attributes from the import * statement or expression. * @returns {{ format: string, url: URL['href'] }} */ - async resolve(originalSpecifier, parentURL, importAssertions) { + async resolve(originalSpecifier, parentURL, importAttributes) { const isMain = parentURL === undefined; if ( @@ -800,7 +825,7 @@ class ESMLoader { const chain = this.#hooks.resolve; const context = { conditions: DEFAULT_CONDITIONS, - importAssertions, + importAttributes, parentURL, }; const meta = { diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index f1fe73eec6edb6..02dbbb4a439b47 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -51,10 +51,10 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) => class ModuleJob { // `loader` is the Loader instance used for loading dependencies. // `moduleProvider` is a function - constructor(loader, url, importAssertions = ObjectCreate(null), + constructor(loader, url, importAttributes = ObjectCreate(null), moduleProvider, isMain, inspectBrk) { this.loader = loader; - this.importAssertions = importAssertions; + this.importAttributes = importAttributes; this.isMain = isMain; this.inspectBrk = inspectBrk; @@ -73,8 +73,8 @@ class ModuleJob { // so that circular dependencies can't cause a deadlock by two of // these `link` callbacks depending on each other. const dependencyJobs = []; - const promises = this.module.link(async (specifier, assertions) => { - const jobPromise = this.loader.getModuleJob(specifier, url, assertions); + const promises = this.module.link(async (specifier, attributes) => { + const jobPromise = this.loader.getModuleJob(specifier, url, attributes); ArrayPrototypePush(dependencyJobs, jobPromise); const job = await jobPromise; return job.modulePromise; @@ -147,7 +147,7 @@ class ModuleJob { let format; try { // This might throw for non-CommonJS modules because we aren't passing - // in the import assertions and some formats require them; but we only + // in the import attributes and some formats require them; but we only // care about CommonJS for the purposes of this error message. ({ format } = await this.loader.load(childFileURL)); diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index a425749e82acd7..f44b06cf981c90 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -106,8 +106,8 @@ function errPath(url) { return url; } -async function importModuleDynamically(specifier, { url }, assertions) { - return asyncESM.esmLoader.import(specifier, url, assertions); +async function importModuleDynamically(specifier, { url }, attributes) { + return asyncESM.esmLoader.import(specifier, url, attributes); } // Strategy for loading a standard JavaScript module. diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 7379db357bdcc4..c3a63f63d1d613 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -83,9 +83,9 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { filename: name, displayErrors: true, [kVmBreakFirstLineSymbol]: !!breakFirstLine, - importModuleDynamically(specifier, _, importAssertions) { + importModuleDynamically(specifier, _, importAttributes) { const loader = asyncESM.esmLoader; - return loader.import(specifier, baseUrl, importAssertions); + return loader.import(specifier, baseUrl, importAttributes); }, })); if (print) { diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index 109b2d7e5b650c..797c582716aa4c 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -302,8 +302,8 @@ class SourceTextModule extends Module { this[kLink] = async (linker) => { this.#statusOverride = 'linking'; - const promises = this[kWrap].link(async (identifier, assert) => { - const module = await linker(identifier, this, { assert }); + const promises = this[kWrap].link(async (identifier, attributes) => { + const module = await linker(identifier, this, { attributes, assert: attributes }); if (module[kWrap] === undefined) { throw new ERR_VM_MODULE_NOT_MODULE(); } diff --git a/lib/repl.js b/lib/repl.js index 8109595b119a8b..7551d079c94bc0 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -458,9 +458,9 @@ function REPLServer(prompt, vm.createScript(fallbackCode, { filename: file, displayErrors: true, - importModuleDynamically: (specifier, _, importAssertions) => { + importModuleDynamically: (specifier, _, importAttributes) => { return asyncESM.esmLoader.import(specifier, parentURL, - importAssertions); + importAttributes); }, }); } catch (fallbackError) { @@ -502,9 +502,9 @@ function REPLServer(prompt, script = vm.createScript(code, { filename: file, displayErrors: true, - importModuleDynamically: (specifier, _, importAssertions) => { + importModuleDynamically: (specifier, _, importAttributes) => { return asyncESM.esmLoader.import(specifier, parentURL, - importAssertions); + importAttributes); }, }); } catch (e) { diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 0645b3ddf506df..7fc30777fbdea7 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -249,19 +249,19 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(that); } -static Local createImportAssertionContainer(Environment* env, - Isolate* isolate, Local raw_assertions) { - Local assertions = - Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0); - for (int i = 0; i < raw_assertions->Length(); i += 3) { - assertions - ->Set(env->context(), - raw_assertions->Get(env->context(), i).As(), - raw_assertions->Get(env->context(), i + 1).As()) - .ToChecked(); - } - - return assertions; +static Local createImportAttributesContainer( + Environment* env, Isolate* isolate, Local raw_attributes) { + Local attributes = + Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0); + for (int i = 0; i < raw_attributes->Length(); i += 3) { + attributes + ->Set(env->context(), + raw_attributes->Get(env->context(), i).As(), + raw_attributes->Get(env->context(), i + 1).As()) + .ToChecked(); + } + + return attributes; } void ModuleWrap::Link(const FunctionCallbackInfo& args) { @@ -297,13 +297,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo& args) { Utf8Value specifier_utf8(env->isolate(), specifier); std::string specifier_std(*specifier_utf8, specifier_utf8.length()); - Local raw_assertions = module_request->GetImportAssertions(); - Local assertions = - createImportAssertionContainer(env, isolate, raw_assertions); + Local raw_attributes = module_request->GetImportAssertions(); + Local attributes = + createImportAttributesContainer(env, isolate, raw_attributes); Local argv[] = { specifier, - assertions, + attributes, }; MaybeLocal maybe_resolve_return_value = @@ -499,7 +499,7 @@ void ModuleWrap::GetError(const FunctionCallbackInfo& args) { MaybeLocal ModuleWrap::ResolveModuleCallback( Local context, Local specifier, - Local import_assertions, + Local import_attributes, Local referrer) { Environment* env = Environment::GetCurrent(context); if (env == nullptr) { @@ -552,7 +552,7 @@ static MaybeLocal ImportModuleDynamically( Local host_defined_options, Local resource_name, Local specifier, - Local import_assertions) { + Local import_attributes) { Isolate* isolate = context->GetIsolate(); Environment* env = Environment::GetCurrent(context); if (env == nullptr) { @@ -601,13 +601,13 @@ static MaybeLocal ImportModuleDynamically( UNREACHABLE(); } - Local assertions = - createImportAssertionContainer(env, isolate, import_assertions); + Local attributes = + createImportAttributesContainer(env, isolate, import_attributes); Local import_args[] = { object, Local(specifier), - assertions, + attributes, }; Local result; diff --git a/src/module_wrap.h b/src/module_wrap.h index 58b233d036515c..e9fd7d219593fe 100644 --- a/src/module_wrap.h +++ b/src/module_wrap.h @@ -96,7 +96,7 @@ class ModuleWrap : public BaseObject { static v8::MaybeLocal ResolveModuleCallback( v8::Local context, v8::Local specifier, - v8::Local import_assertions, + v8::Local import_attributes, v8::Local referrer); static ModuleWrap* GetFromModule(node::Environment*, v8::Local); diff --git a/test/es-module/test-esm-dynamic-import-assertion.js b/test/es-module/test-esm-dynamic-import-attribute.js similarity index 100% rename from test/es-module/test-esm-dynamic-import-assertion.js rename to test/es-module/test-esm-dynamic-import-attribute.js diff --git a/test/es-module/test-esm-dynamic-import-assertion.mjs b/test/es-module/test-esm-dynamic-import-attribute.mjs similarity index 100% rename from test/es-module/test-esm-dynamic-import-assertion.mjs rename to test/es-module/test-esm-dynamic-import-attribute.mjs diff --git a/test/es-module/test-esm-import-assertion-2.mjs b/test/es-module/test-esm-import-assertion-2.mjs deleted file mode 100644 index 8001c29772b1f0..00000000000000 --- a/test/es-module/test-esm-import-assertion-2.mjs +++ /dev/null @@ -1,6 +0,0 @@ -import '../common/index.mjs'; -import { strictEqual } from 'assert'; - -import secret from '../fixtures/experimental.json' assert { type: 'json', unsupportedAssertion: 'should ignore' }; - -strictEqual(secret.ofLife, 42); diff --git a/test/es-module/test-esm-import-assertion-validation.js b/test/es-module/test-esm-import-assertion-validation.js deleted file mode 100644 index ec2d2a2c08f7b5..00000000000000 --- a/test/es-module/test-esm-import-assertion-validation.js +++ /dev/null @@ -1,45 +0,0 @@ -// Flags: --expose-internals -'use strict'; -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', {})); -assert.ok(validateAssertions(url, 'commonjs', {})); -assert.ok(validateAssertions(url, 'json', { type: 'json' })); -assert.ok(validateAssertions(url, 'module', {})); -assert.ok(validateAssertions(url, 'wasm', {})); - -assert.throws(() => validateAssertions(url, 'json', {}), { - code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING', -}); - -assert.throws(() => validateAssertions(url, 'module', { type: 'json' }), { - code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED', -}); - -// The HTML spec specifically disallows this for now, while Wasm module import -// and whether it will require a type assertion is still an open question. -assert.throws(() => validateAssertions(url, 'module', { type: 'javascript' }), { - code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED', -}); - -assert.throws(() => validateAssertions(url, 'module', { type: 'css' }), { - code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED', -}); - -assert.throws(() => validateAssertions(url, 'module', { type: false }), { - code: 'ERR_INVALID_ARG_TYPE', -}); diff --git a/test/es-module/test-esm-import-assertion-warning.mjs b/test/es-module/test-esm-import-assertion-warning.mjs index 0b18d8ff9eaf62..1a74cca22dfb51 100644 --- a/test/es-module/test-esm-import-assertion-warning.mjs +++ b/test/es-module/test-esm-import-assertion-warning.mjs @@ -1,10 +1,35 @@ -import { expectWarning } from '../common/index.mjs'; +import { spawnPromisified } from '../common/index.mjs'; +import assert from 'node:assert'; +import { execPath } from 'node:process'; -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 Promise.all([ + // Setting importAssertions on the context object of the load hook should warn but still work. + `data:text/javascript,export ${encodeURIComponent(function load(u, c, n) { + if (u !== 'data:') return n(u, c); + c.importAssertions.type = 'json'; + return n('data:application/json,1', c); + })}`, + // Creating a new context object with importAssertions in the load hook should warn but still work. + `data:text/javascript,export ${encodeURIComponent(function load(u, c, n) { + if (u !== 'data:') return n(u, c); + c.importAssertions = { type: 'json' }; + return n('data:application/json,1', c); + })}`, +].map(async (loaderURL) => { + const { stdout, stderr, code } = await spawnPromisified(execPath, [ + '--input-type=module', + '--experimental-loader', + loaderURL, + '--eval', ` + import assert from 'node:assert'; + + assert.deepStrictEqual( + { ...await import('data:') }, + { default: 1 } + );`, + ]); -await import('data:text/javascript,', { assert: { someUnsupportedKey: 'value' } }); + assert.match(stderr, /Use `importAttributes` instead of `importAssertions`/); + assert.strictEqual(stdout, ''); + assert.strictEqual(code, 0); +})); diff --git a/test/es-module/test-esm-import-assertion-1.mjs b/test/es-module/test-esm-import-attributes-1.mjs similarity index 100% rename from test/es-module/test-esm-import-assertion-1.mjs rename to test/es-module/test-esm-import-attributes-1.mjs diff --git a/test/es-module/test-esm-import-assertion-4.mjs b/test/es-module/test-esm-import-attributes-2.mjs similarity index 100% rename from test/es-module/test-esm-import-assertion-4.mjs rename to test/es-module/test-esm-import-attributes-2.mjs diff --git a/test/es-module/test-esm-import-assertion-3.mjs b/test/es-module/test-esm-import-attributes-3.mjs similarity index 100% rename from test/es-module/test-esm-import-assertion-3.mjs rename to test/es-module/test-esm-import-attributes-3.mjs diff --git a/test/es-module/test-esm-import-assertion-errors.js b/test/es-module/test-esm-import-attributes-errors.js similarity index 84% rename from test/es-module/test-esm-import-assertion-errors.js rename to test/es-module/test-esm-import-attributes-errors.js index e2abd3fb43976d..9cf5ce33693ce5 100644 --- a/test/es-module/test-esm-import-assertion-errors.js +++ b/test/es-module/test-esm-import-attributes-errors.js @@ -5,19 +5,17 @@ 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' } }), { code: 'ERR_UNKNOWN_MODULE_FORMAT' } ); + await rejects( + import('data:text/css,', { assert: { unsupportedAttribute: 'value' } }), + { code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' } + ); + await rejects( import(`data:text/javascript,import${JSON.stringify(jsModuleDataUrl)}assert{type:"json"}`), { code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' } diff --git a/test/es-module/test-esm-import-assertion-errors.mjs b/test/es-module/test-esm-import-attributes-errors.mjs similarity index 81% rename from test/es-module/test-esm-import-assertion-errors.mjs rename to test/es-module/test-esm-import-attributes-errors.mjs index 9cc08c06528fc6..acaeef50626508 100644 --- a/test/es-module/test-esm-import-assertion-errors.mjs +++ b/test/es-module/test-esm-import-attributes-errors.mjs @@ -1,17 +1,9 @@ -import { expectWarning } from '../common/index.mjs'; +import '../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-attributes-validation.js b/test/es-module/test-esm-import-attributes-validation.js new file mode 100644 index 00000000000000..f436f7073126d7 --- /dev/null +++ b/test/es-module/test-esm-import-attributes-validation.js @@ -0,0 +1,45 @@ +// Flags: --expose-internals +'use strict'; +require('../common'); + +const assert = require('assert'); + +const { validateAttributes } = require('internal/modules/esm/assert'); + +const url = 'test://'; + +assert.ok(validateAttributes(url, 'builtin', {})); +assert.ok(validateAttributes(url, 'commonjs', {})); +assert.ok(validateAttributes(url, 'json', { type: 'json' })); +assert.ok(validateAttributes(url, 'module', {})); +assert.ok(validateAttributes(url, 'wasm', {})); + +assert.throws(() => validateAttributes(url, 'json', {}), { + code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING', +}); + +assert.throws(() => validateAttributes(url, 'json', { type: 'json', unsupportedAttribute: 'value' }), { + code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED', +}); + +assert.throws(() => validateAttributes(url, 'module', { unsupportedAttribute: 'value' }), { + code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED', +}); + +assert.throws(() => validateAttributes(url, 'module', { type: 'json' }), { + code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED', +}); + +// The HTML spec specifically disallows this for now, while Wasm module import +// and whether it will require a type assertion is still an open question. +assert.throws(() => validateAttributes(url, 'module', { type: 'javascript' }), { + code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED', +}); + +assert.throws(() => validateAttributes(url, 'module', { type: 'css' }), { + code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED', +}); + +assert.throws(() => validateAttributes(url, 'module', { type: false }), { + code: 'ERR_INVALID_ARG_TYPE', +}); diff --git a/test/es-module/test-esm-json.mjs b/test/es-module/test-esm-json.mjs index 2740c0097f77da..68202b077f67b7 100644 --- a/test/es-module/test-esm-json.mjs +++ b/test/es-module/test-esm-json.mjs @@ -17,7 +17,6 @@ describe('ESM: importing JSON', () => { ]); assert.match(stderr, /ExperimentalWarning: Importing JSON modules/); - assert.match(stderr, /ExperimentalWarning: Import assertions/); assert.strictEqual(code, 0); assert.strictEqual(signal, null); }); diff --git a/test/fixtures/es-module-loaders/assertionless-json-import.mjs b/test/fixtures/es-module-loaders/assertionless-json-import.mjs index 07656d4ec40fa3..f8aba42cadd5b8 100644 --- a/test/fixtures/es-module-loaders/assertionless-json-import.mjs +++ b/test/fixtures/es-module-loaders/assertionless-json-import.mjs @@ -3,15 +3,15 @@ const JSON_URL_PATTERN = /\.json(\?[^#]*)?(#.*)?$/; export function resolve(url, context, next) { // Mutation from resolve hook should be discarded. - context.importAssertions.type = 'whatever'; + context.importAttributes.type = 'whatever'; return next(url); } export function load(url, context, next) { - if (context.importAssertions.type == null && + if (context.importAttributes.type == null && (DATA_URL_PATTERN.test(url) || JSON_URL_PATTERN.test(url))) { - const { importAssertions } = context; - importAssertions.type = 'json'; + const { importAttributes } = context; + importAttributes.type = 'json'; } return next(url); } diff --git a/test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs b/test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs index 8c317c1b7ce31e..5de2dd48eeb9fd 100644 --- a/test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs +++ b/test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs @@ -20,7 +20,7 @@ export async function resolve(specifier, context, next) { return { shortCircuit: true, url: `custom-${def.url}`, - importAssertions: context.importAssertions, + importAttributes: context.importAttributes, }; } return def; diff --git a/test/fixtures/es-module-loaders/hooks-custom.mjs b/test/fixtures/es-module-loaders/hooks-custom.mjs index ea2ffaf7e97070..5656f95232b856 100644 --- a/test/fixtures/es-module-loaders/hooks-custom.mjs +++ b/test/fixtures/es-module-loaders/hooks-custom.mjs @@ -6,7 +6,7 @@ import count from '../es-modules/stateful.mjs'; // used to assert node-land and user-land have different contexts count(); -export function resolve(specifier, { importAssertions }, next) { +export function resolve(specifier, { importAttributes }, next) { let format = ''; if (specifier === 'esmHook/format.false') { @@ -24,7 +24,7 @@ export function resolve(specifier, { importAssertions }, next) { format, shortCircuit: true, url: pathToFileURL(specifier).href, - importAssertions, + importAttributes, }; } diff --git a/test/fixtures/es-module-loaders/hooks-input.mjs b/test/fixtures/es-module-loaders/hooks-input.mjs index 6859cfc07d9b6a..53fce5ca475ccf 100644 --- a/test/fixtures/es-module-loaders/hooks-input.mjs +++ b/test/fixtures/es-module-loaders/hooks-input.mjs @@ -17,14 +17,14 @@ export async function resolve(specifier, context, next) { url = new URL(specifier).href; assert.match(specifier, /json-modules\.mjs$/); assert.strictEqual(context.parentURL, undefined); - assert.deepStrictEqual(context.importAssertions, { + assert.deepStrictEqual(context.importAttributes, { __proto__: null, }); } else if (resolveCalls === 2) { url = new URL(specifier, context.parentURL).href; assert.match(specifier, /experimental\.json$/); assert.match(context.parentURL, /json-modules\.mjs$/); - assert.deepStrictEqual(context.importAssertions, { + assert.deepStrictEqual(context.importAttributes, { __proto__: null, type: 'json', }); @@ -33,7 +33,7 @@ export async function resolve(specifier, context, next) { // Ensure `context` has all and only the properties it's supposed to assert.deepStrictEqual(Reflect.ownKeys(context), [ 'conditions', - 'importAssertions', + 'importAttributes', 'parentURL', ]); assert.ok(Array.isArray(context.conditions)); @@ -57,13 +57,13 @@ export async function load(url, context, next) { if (loadCalls === 1) { assert.match(url, /json-modules\.mjs$/); - assert.deepStrictEqual(context.importAssertions, { + assert.deepStrictEqual(context.importAttributes, { __proto__: null, }); format = 'module'; } else if (loadCalls === 2) { assert.match(url, /experimental\.json$/); - assert.deepStrictEqual(context.importAssertions, { + assert.deepStrictEqual(context.importAttributes, { __proto__: null, type: 'json', }); @@ -74,7 +74,7 @@ export async function load(url, context, next) { // Ensure `context` has all and only the properties it's supposed to assert.deepStrictEqual(Object.keys(context), [ 'format', - 'importAssertions', + 'importAttributes', ]); assert.strictEqual(context.format, 'test'); assert.strictEqual(typeof next, 'function'); diff --git a/test/fixtures/es-module-loaders/loader-invalid-format.mjs b/test/fixtures/es-module-loaders/loader-invalid-format.mjs index e7dd06c108ba1d..dc61a792b2be8b 100644 --- a/test/fixtures/es-module-loaders/loader-invalid-format.mjs +++ b/test/fixtures/es-module-loaders/loader-invalid-format.mjs @@ -1,4 +1,4 @@ -export async function resolve(specifier, { parentURL, importAssertions }, next) { +export async function resolve(specifier, { parentURL, importAttributes }, next) { if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') { return { shortCircuit: true, diff --git a/test/fixtures/es-module-loaders/loader-invalid-url.mjs b/test/fixtures/es-module-loaders/loader-invalid-url.mjs index a54f39521f29ac..aac2b16b6f58fe 100644 --- a/test/fixtures/es-module-loaders/loader-invalid-url.mjs +++ b/test/fixtures/es-module-loaders/loader-invalid-url.mjs @@ -1,9 +1,9 @@ -export async function resolve(specifier, { parentURL, importAssertions }, next) { +export async function resolve(specifier, { parentURL, importAttributes }, next) { if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') { return { shortCircuit: true, url: specifier, - importAssertions, + importAttributes, }; } return next(specifier); diff --git a/test/fixtures/es-module-loaders/loader-with-dep.mjs b/test/fixtures/es-module-loaders/loader-with-dep.mjs index 1b5fd6c3c1642a..625341eaed7eb2 100644 --- a/test/fixtures/es-module-loaders/loader-with-dep.mjs +++ b/test/fixtures/es-module-loaders/loader-with-dep.mjs @@ -3,9 +3,9 @@ import {createRequire} from '../../common/index.mjs'; const require = createRequire(import.meta.url); const dep = require('./loader-dep.js'); -export async function resolve(specifier, { parentURL, importAssertions }, defaultResolve) { +export async function resolve(specifier, { parentURL, importAttributes }, defaultResolve) { return { - url: (await defaultResolve(specifier, { parentURL, importAssertions }, defaultResolve)).url, + url: (await defaultResolve(specifier, { parentURL, importAttributes }, defaultResolve)).url, format: dep.format }; } diff --git a/test/fixtures/es-module-loaders/not-found-assert-loader.mjs b/test/fixtures/es-module-loaders/not-found-assert-loader.mjs index ea4c73724298db..1786b7c04fc555 100644 --- a/test/fixtures/es-module-loaders/not-found-assert-loader.mjs +++ b/test/fixtures/es-module-loaders/not-found-assert-loader.mjs @@ -3,7 +3,7 @@ import assert from 'node:assert'; // a loader that asserts that the defaultResolve will throw "not found" // (skipping the top-level main of course) let mainLoad = true; -export async function resolve(specifier, { importAssertions }, next) { +export async function resolve(specifier, { importAttributes }, next) { if (mainLoad) { mainLoad = false; return next(specifier); @@ -15,7 +15,7 @@ export async function resolve(specifier, { importAssertions }, next) { assert.strictEqual(e.code, 'ERR_MODULE_NOT_FOUND'); return { url: 'node:fs', - importAssertions, + importAttributes, }; } assert.fail(`Module resolution for ${specifier} should be throw ERR_MODULE_NOT_FOUND`); diff --git a/test/fixtures/es-module-loaders/string-sources.mjs b/test/fixtures/es-module-loaders/string-sources.mjs index 396d17cb17a75c..39ad32c465fa31 100644 --- a/test/fixtures/es-module-loaders/string-sources.mjs +++ b/test/fixtures/es-module-loaders/string-sources.mjs @@ -23,7 +23,7 @@ const SOURCES = { export function resolve(specifier, context, next) { if (specifier.startsWith('test:')) { return { - importAssertions: context.importAssertions, + importAttributes: context.importAttributes, shortCircuit: true, url: specifier, }; diff --git a/test/parallel/test-vm-module-dynamic-import.js b/test/parallel/test-vm-module-dynamic-import.js index cd318511401412..5bca08b8c9c3bb 100644 --- a/test/parallel/test-vm-module-dynamic-import.js +++ b/test/parallel/test-vm-module-dynamic-import.js @@ -59,10 +59,10 @@ async function test() { { const s = new Script('import("foo", { assert: { key: "value" } })', { - importModuleDynamically: common.mustCall((specifier, wrap, assertion) => { + importModuleDynamically: common.mustCall((specifier, wrap, attributes) => { assert.strictEqual(specifier, 'foo'); assert.strictEqual(wrap, s); - assert.deepStrictEqual(assertion, { __proto__: null, key: 'value' }); + assert.deepStrictEqual(attributes, { __proto__: null, key: 'value' }); return foo; }), });