动态 import() 的使用场景和注意事项?
import() 是 ESM 的动态加载语法,返回 Promise,用于按需加载模块。
基本用法
// 静态导入(编译时加载)
import { add } from './math.js'
// 动态导入(运行时加载)
const module = await import('./math.js')
console.log(module.add(1, 2))使用场景
1. 路由懒加载
// React
const Home = lazy(() => import('./pages/Home'))
const About = lazy(() => import('./pages/About'))
// Vue
const routes = [
{ path: '/', component: () => import('./pages/Home.vue') },
{ path: '/about', component: () => import('./pages/About.vue') }
]2. 条件加载
if (featureFlags.advanced) {
const advanced = await import('./features/advanced.js')
advanced.init()
}3. 按需加载大依赖
// 只在需要时加载 PDF 库
async function exportPDF() {
const { jsPDF } = await import('jspdf')
const doc = new jsPDF()
doc.text('Hello', 10, 10)
doc.save()
}4. 加载语言包
async function setLanguage(lang) {
const messages = await import(`./locales/${lang}.js`)
i18n.setLocaleMessage(lang, messages.default)
}import() 与代码分割
构建工具遇到 import() 会自动创建单独的 chunk:
// 构建前
import('./heavy.js').then(module => {
module.run()
})
// 构建后生成:
// main.js(入口 chunk)
// heavy.[hash].js(单独 chunk,按需加载)预加载提示
// Webpack magic comments
const module = import(
/* webpackChunkName: "dashboard" */
/* webpackPrefetch: true */ // 空闲时预加载
'./Dashboard'
)
/* webpackPreload: true */ // 与父 chunk 并行加载prefetch vs preload
- prefetch:浏览器空闲时加载(将来可能用到)
- preload:与当前页面并行加载(马上会用到)
<!-- HTML 中的 prefetch/preload -->
<link rel="prefetch" href="/next-page.js">
<link rel="preload" href="/critical.js" as="script">动态导入的注意事项
1. 模块路径
// ✅ 静态字符串
import('./module.js')
// ✅ 模板字符串(有限制)
import(`./locales/${lang}.js`) // 构建工具会生成所有可能的 chunk
// ❌ 完全动态
import(variablePath) // 不支持2. 错误处理
try {
const module = await import('./optional.js')
} catch (e) {
console.log('模块加载失败')
// 降级处理
}3. 缓存
// 同一模块多次 import() 只加载一次
const a = await import('./math.js')
const b = await import('./math.js')
console.log(a === b) // true(缓存的模块记录)Vite 中的动态导入
// Vite 支持 glob 导入
const modules = import.meta.glob('./pages/*.vue')
// 返回: { './pages/Home.vue': () => import('./pages/Home.vue'), ... }
// Eager(立即加载)
const modules = import.meta.glob('./pages/*.vue', { eager: true })使用建议
- 路由组件一律懒加载
- 大依赖(图表、编辑器、PDF)按需加载
- 条件功能按需加载
- 搭配 prefetch 优化用户体验