动态 import() 是现代 javascript 按需加载的核心,本质异步、需运行时触发、路径须静态可析,必须在函数等可执行上下文中调用,返回 promise 需手动处理加载状态与错误,框架懒加载组件仍依赖其底层执行。

动态 import() 是现代 JavaScript 实现按需加载的核心手段,它不参与静态分析、支持运行时路径计算、返回 Promise,并由构建工具自动分片。关键在于“异步”是本质,“按需”靠触发,“条件”由逻辑控制——不是写出来就加载,而是执行到才发起请求。
必须在可执行上下文中调用
import() 不能出现在模块顶层,否则会报 SyntaxError。它只能放在函数体、事件回调、if 分支、async 函数内等运行时能判断的位置。
- ✅ 正确:按钮点击时加载
button.addEventListener('click', async () => {<br> const { default: Chart } = await import('./Chart.js');<br> Chart.render();<br>});
- ✅ 正确:路由切换后加载
- ✅ 正确:权限校验通过再加载管理后台模块
- ❌ 错误:直接写在
<script type="module"></script>的第一行
路径必须可被构建工具静态识别
Webpack、Vite 等依赖静态分析生成独立 chunk。路径若含非常量变量(如 import(`./${name}.js`)),会导致无法分包,甚至回退为全量打包。
- ✅ 支持:字面量路径
import('./utils.js') - ✅ 支持:模板字符串常量
import(`./config.${process.env.NODE_ENV}.js`)(构建期已知) - ✅ 支持:简单拼接
import('./' + 'api' + '.js')(部分新版工具支持) - ❌ 不支持:运行时拼接
const name = getUserPref(); import(`./${name}.js`)
加载状态与错误要主动处理
import() 返回 Promise,但不会自动捕获网络失败、404、语法错误或模块导出缺失。不加处理容易静默失败。
- 显示 loading:在
import()调用前设置 UI 状态(如显示 spinner) - 成功后使用:用
await或.then()获取模块对象,再访问.default或命名导出 - 必须捕获异常:用
try/catch或.catch()处理加载失败,提供降级方案(如提示、空占位、备用逻辑)
示例:
async function loadEditor() {<br> try {<br> const { Editor } = await import('./Editor.js');<br> return new Editor().mount('#editor');<br> } catch (err) {<br> console.warn('编辑器加载失败,启用纯文本模式');<br> document.getElementById('editor').textContent = '仅支持查看';<br> }<br>}
与框架配合实现懒加载组件
React 和 Vue 并非“替代” import(),而是封装其调用时机和生命周期。真正触发网络请求的,仍是底层的 import() 执行。
- React:
const Modal = React.lazy(() => import('./Modal'));配合<suspense fallback></suspense>控制 loading 状态 - Vue:
defineAsyncComponent(() => import('./Dashboard.vue')),组件首次渲染时才执行 import - 关键点:这些写法本身不触发加载;只有当组件进入 DOM(如路由匹配、
v-if为真)时,框架才调用工厂函数,进而执行import()











