JavaScript模块加载器基于静态分析与动态加载双路径管理依赖,import()实现按需加载并返回Promise,支持条件加载与缓存复用,但路径须可静态推断且不可用于顶层条件语句。
JavaScript 的模块加载器负责解析、获取、执行模块代码,并管理模块之间的依赖关系。现代浏览器和 Node.js 都原生支持 ES 模块(ESM),其加载机制基于静态分析与动态加载双路径,而动态导入(import())正是实现按需加载的核心能力。
当遇到 import 语句(如 import { foo } from './utils.js')时,加载器会:
export/import)import() 的工作方式import() 是一个返回 Promise 的函数,它绕过静态分析,在运行时决定加载哪个模块:
`./pages/${page}.js`),但不能是任意变量(否则打包工具无法预处理){ default: ..., foo: ..., bar: ... })import() 返回已缓存的 Promise示例:
async function loadChart() {
const chartModule = await import('./charts/bar-chart.js');
chartModule.render(document.getElementById('chart'));
}
ESM 规范定义了“即时初始化”模型:模块在首次执行前就建立好导出绑定,即使存在循环引用,也能保证导出对象存在(值可能为 undefined 直到执行完成)。
import() 的 Promise 会被拒绝,可用 catch 捕获
可通过 或 import() 触发加载;Node.js 中需启用 --experimental-modules(v12+ 已默认支持)import() 并生成独立 chunk,配合运行时加载器协作动态导入不是万能的,使用时要注意:
import() 不能出现在顶层作用域的条件语句中(如 if (x) import('./a.js')),因为引擎仍需在解析阶段识别所有潜在导入import(path + '.js')),否则构建工具无法分析,运行时会报错module: 'esnext' 和 target: 'es2015' 以上,才能正确类型推导 import() 结果