掌握JS动态导入关键在于理解“何时加载、如何加载、加载后怎么用”三层逻辑,核心是浏览器原生支持的import()函数——运行时调用、返回Promise、支持字符串变量路径、需处理loading与错误。

掌握 JS 动态导入,关键不是背语法,而是理解它“何时加载、如何加载、加载后怎么用”这三层逻辑。核心就落在 import() 这个函数上——它是标准、轻量、浏览器原生支持的方案,其他如 require.ensure 已基本淘汰,不建议投入时间深挖。
明确 import() 的本质:它不是声明,是调用
和静态 import 语句不同,import() 是一个运行时函数调用,返回 Promise:
- 它必须写在代码执行流中(比如事件回调、条件分支里),不能出现在模块顶层作为声明式导入;
- 路径参数
moduleSpecifier可以是字符串变量,支持拼接(如import(`./pages/${page}.js`)),但不能是完全动态的表达式(如含未定义变量); - 返回的 Promise resolve 后得到的是模块命名空间对象,结构类似
{ default: ..., func1: ..., const1: ... },需解构或点取使用。
动手写两种典型用法,别只看示例
光读代码不如亲手跑通两个最小闭环:
-
按钮触发加载:给一个按钮绑定 click 事件,
await import('./utils.js'),然后调用其中导出的函数,观察控制台和 Network 面板是否真发起新请求; -
路由级按需加载:模拟简单路由切换,比如点击 “图表” 页时才加载
chart-lib.js,加载成功再渲染图表容器——这时你会自然意识到需要处理 loading 状态和错误 fallback。
注意三个高频踩坑点
这些不是细节,而是上线后真实报错的来源:
-
HTML 中没加 type="module":如果主脚本是通过
<script src="main.js"></script>引入的,默认是传统脚本模式,import()虽然可用,但模块内若用了export就会报错;推荐统一用<script type="module" src="main.js"></script>; -
本地双击打开 HTML 报 CORS:file:// 协议下浏览器禁止跨源模块加载,必须起本地服务(Live Server 插件或
npx http-server); -
没处理 Promise reject:路径写错、网络中断、模块语法错误都会导致
import()失败,不 catch 就是白屏或静默失败——哪怕只写.catch(console.error)也是必要兜底。
结合框架场景理解价值,不孤立学 API
动态导入的价值,在真实项目里才凸显:
- React 中
React.lazy()底层就是封装了import(),配合Suspense实现组件级懒加载; - Vue 单文件组件的
defineAsyncComponent同理,加载中显示 skeleton,失败时展示 error component; - 即使不用框架,做管理后台时,把“报表页”“日志页”“设置页”的 JS 拆成独立 chunk,能显著降低首页体积。











