之前 #
V8 在 v9.1 中发布了 导入断言 功能。此功能允许模块导入语句使用 assert
关键字包含附加信息。此附加信息目前用于在 JavaScript 模块中导入 JSON 和 CSS 模块。
导入属性 #
从那时起,导入断言已演变为 导入属性。该功能的目的是保持不变:允许模块导入语句包含附加信息。
最重要的区别是导入断言只有断言语义,而导入属性具有更宽松的语义。断言语义意味着附加信息不会影响模块的加载方式,只会影响模块的是否加载。例如,JSON 模块始终以 JSON 模块的形式加载,因为其 MIME 类型,并且 assert { type: 'json' }
子句只能在请求的模块的 MIME 类型不是 application/json
时导致加载失败。
但是,断言语义存在致命缺陷。在网络上,HTTP 请求的形状取决于请求的资源类型。例如,Accept
标头 会影响响应的 MIME 类型,而 Sec-Fetch-Dest
元数据标头 会影响 Web 服务器是否接受或拒绝请求。由于导入断言无法影响模块的加载方式,因此它无法更改 HTTP 请求的形状。正在请求的资源类型也会影响使用哪些 内容安全策略:导入断言无法与网络的安全模型正确配合使用。
导入属性放宽了断言语义,允许属性影响模块的加载方式。换句话说,导入属性可以生成包含适当的 Accept
和 Sec-Fetch-Dest
标头的 HTTP 请求。为了使语法与新的语义匹配,旧的 assert
关键字更新为 with
// main.mjs
//
// New 'with' syntax.
import json from './foo.json' with { type: 'json' };
console.log(json.answer); // 42
动态 import()
#
类似地,动态 import()
也类似地更新为接受 with
选项。
// main.mjs
//
// New 'with' option.
const jsonModule = await import('./foo.json', {
with: { type: 'json' }
});
console.log(jsonModule.default.answer); // 42
with
的可用性 #
导入属性在 V8 v12.3 中默认启用。
assert
的弃用和最终删除 #
从 V8 v12.3 开始,assert
关键字已弃用,并计划在 v12.6 中删除。请使用 with
代替 assert
!使用 assert
子句将向控制台打印警告,建议使用 with
代替。