Sync Imports S2
中文标题:同步导入
- 阶段: Stage 2
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案引入了 import.sync,一个用于 ES 模块的同步导入函数,使得在模块已经可用时能够同步动态加载说明符。它基于 Defer Import Eval 提案中的同步求值语义,并在模块不可同步获得或使用顶层 await 时抛出错误。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
同步导入
状态
提案发起人:Guy Bedford 阶段:2
问题陈述
当模块已经完全加载到模块注册表中时,支持一个同步导入函数将会很有用,以便在同步函数路径中加载动态说明符表达式。
背景
随着我们进入原生 ESM 在 JS 生态系统中被广泛采用的成熟阶段,诸如 Node.js 中的 require(esm) 等特性为许多人解锁了升级路径,但在从 CommonJS 迁移到 ES 模块的道路上仍存在一些遗留的可用性问题。
特别是,Node.js 中的 CommonJS 用户习惯于能够同步动态地 require 模块,而不必因此将他们的代码路径转换为异步。
延迟导入求值 通过允许模块的同步懒加载解决了其中一个问题。它通过有效地将模块加载流程中的异步方面与同步方面分离,从而允许在延迟命名空间上使用同步求值函数。
即使支持了这个提案,当说明符预先未知时,动态懒加载仍然存在空白,因为动态的 import.defer(specifier) 仍然是一个异步函数。
使用与 Defer Import Eval 提案中已经定义的同步求值完全相同的语义,我们可以为 JavaScript 提供一个显式的同步导入钩子,从而为 JavaScript 开发者解决这个可用性问题。
以前,在 ESM 规范的早期阶段,启用此类功能的主要障碍之一是异步解析问题。后来事实证明,所有 JS 环境都实现了同步模块解析。 因此,鉴于这一约束,同步导入是可能的。
提案
我们提议为 ES 模块公开一个显式的同步导入函数,作为 Defer Import Eval 提案中已定义的同步执行行为的直接扩展:
该提案的主要设计是,当模块不可同步获得或使用了顶层 await 时,抛出一个新的 Error。
模块是否可同步获得将是一个由宿主决定的属性。
使用场景
获取已加载的模块
在 Web 上,如果一个模块之前已经被加载过,那么它总是可以同步获得的。
这样,import.sync() 可以像注册表获取器一样工作:
条件加载
与动态导入一样,使用同步导入,可以检查模块或内置模块是否可用,但是同步地进行。
例如,检查宿主内置模块是否可用:
或者一个条件绑定到框架依赖的库:
同步加载模块表达式和模块声明
支持导入没有 TLA 和异步依赖的模块表达式:
同样适用于模块声明:
常见问题
导入同步是模块加载阶段吗?
不,与 defer 和 source 不同,import.sync 不是一个阶段,它是一个新的元属性,类似于 import.meta。
不支持类似于 import sync mod from 'mod' 的语法。
要预先保证图是同步的,请参见 模块同步断言 提案,该提案可能会提供导入属性或其他方式。
提出问题请提交 issue。