动态 import() 必须在函数作用域内使用,返回 Promise,需 await 或 .then() 消费;路径须为字符串字面量或模板字符串常量,禁止运行时拼接;不支持顶层调用和旧浏览器,需兼容处理与错误兜底。

动态 import() 语法必须写在函数作用域内
直接在模块顶层写 import() 会报语法错误,因为它是异步操作,只能出现在 async 函数或事件回调里。浏览器不支持顶层动态导入(尽管某些打包工具能转译,但原生环境不行)。
常见错误现象:Uncaught SyntaxError: Cannot use import statement outside a module 或更具体的 Dynamic imports are only supported when the 'importsNotUsedAsValues' is set to 'preserve'(TypeScript 场景)。
- 正确写法:封装成
async函数,例如async function loadChart() { const mod = await import('./chart.js'); mod.render(); } - 不能这样写:
if (needChart) import('./chart.js');—— 缺少await或.then(),且没处理 Promise - 也不建议裸用
import('./a.js').then(...)在条件分支外,容易触发无意义预加载
import() 返回 Promise,必须用 await 或 .then() 消费
import() 不是同步函数,它返回一个解析为模块对象的 Promise。忽略这一点会导致变量未定义、方法调用失败,或模块看似“没加载”。
使用场景:按钮点击加载组件、路由切换时拉取页面逻辑、表单提交前校验规则模块。
立即学习“Java免费学习笔记(深入)”;
- 推荐用
await:语义清晰,错误可被try/catch捕获 - 避免只写
import('./util.js')而不接.then()或await—— Promise 会被丢弃,模块代码可能执行,但你拿不到导出内容 - 错误处理别漏掉:网络失败、404、模块语法错误都会 reject,建议包裹
try/catch
路径必须是字符串字面量或模板字符串常量
Vite、Webpack 等构建工具靠静态分析生成 chunk,所以 import() 的参数不能是拼接的变量,否则无法拆包,会退化成加载整个 bundle。
常见错误现象:打包后所有模块被打进主包,失去按需加载意义;开发时看似正常,上线后体积暴涨。
- ✅ 允许:
import(`./locales/${lang}.js`)(Vite 支持这种有限制的表达式) - ❌ 禁止:
const p = './mod.js'; import(p)或import(base + '/mod.js') - 路径中不要含运行时变量,如
import('./' + name + '.js')—— 构建工具无法推断依赖图
配合 type="module" 和 nomodule 处理兼容性
动态 import() 是 ES2020+ 特性,旧版 Safari、IE 完全不支持。如果需要兼容,得有降级方案。
性能影响:现代浏览器下无额外开销;但每个 import() 都是一次独立 HTTP 请求,频繁调用小模块反而增加延迟。
- 基础兼容写法:HTML 中用
<script type="module">加载主逻辑,再用<script nomodule src="legacy-bundle.js"></script> - 不建议在
nomodule脚本里模拟import()—— 很难做到行为一致,不如直接提供完整 legacy 包 - 注意:Service Worker 或 HTTP/2 Push 对动态加载资源优化有限,别指望自动合并请求



















