导入属性

发布时间 · 标签:ECMAScript

之前 #

V8 在 v9.1 中发布了 导入断言 功能。此功能允许模块导入语句使用 assert 关键字包含附加信息。此附加信息目前用于在 JavaScript 模块中导入 JSON 和 CSS 模块。

导入属性 #

从那时起,导入断言已演变为 导入属性。该功能的目的是保持不变:允许模块导入语句包含附加信息。

最重要的区别是导入断言只有断言语义,而导入属性具有更宽松的语义。断言语义意味着附加信息不会影响模块的加载方式,只会影响模块的是否加载。例如,JSON 模块始终以 JSON 模块的形式加载,因为其 MIME 类型,并且 assert { type: 'json' } 子句只能在请求的模块的 MIME 类型不是 application/json 时导致加载失败。

但是,断言语义存在致命缺陷。在网络上,HTTP 请求的形状取决于请求的资源类型。例如,Accept 标头 会影响响应的 MIME 类型,而 Sec-Fetch-Dest 元数据标头 会影响 Web 服务器是否接受或拒绝请求。由于导入断言无法影响模块的加载方式,因此它无法更改 HTTP 请求的形状。正在请求的资源类型也会影响使用哪些 内容安全策略:导入断言无法与网络的安全模型正确配合使用。

导入属性放宽了断言语义,允许属性影响模块的加载方式。换句话说,导入属性可以生成包含适当的 AcceptSec-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 代替。

导入属性支持 #