动态导入关键在场景选择:import() 用于懒加载、权限控制等运行时不确定场景,静态 import 适用于顶层确定依赖;需结合构建工具、环境兼容性及错误处理实战使用。

学 JS 动态导入,关键不是背语法,而是搞懂“什么时候该用、怎么用稳、出问题怎么查”。它不是独立知识点,而是和模块系统、构建工具、运行环境绑在一起的实战能力。
先分清 import() 和静态 import 的分工
静态 import 必须写在顶层、路径必须是字符串字面量,打包时能被 Webpack/Vite 分析依赖、做 tree-shaking;import() 是运行时函数,支持变量拼接路径(比如 import(`./locales/${lang}.js`)),但不参与编译期分析——所以它适合懒加载、权限控制、多语言切换这些“不确定要不要、什么时候要”的场景。
常见误区:以为 import() 可以替代所有 import。其实不该用的地方硬用,反而破坏可维护性,比如工具函数、基础组件这类高频调用模块,静态引入更合适。
动手写几种典型用法
不用从零造轮子,照着业务中最常出现的模式练:
- 按钮点击加载图表库:
const { default: echarts } = await import('echarts'); - 路由级懒加载(React):
const Home = React.lazy(() => import('./pages/Home')); - 按语言加载翻译包:
const messages = await import(`./i18n/${locale}.json`); - 错误兜底处理:
try { const mod = await import('./feature.js'); } catch (e) { console.warn('功能未加载', e); }
配合构建工具看生成结果
只写代码不看打包产物,等于蒙眼开车。在 Vite 或 Webpack 项目里加一句 import('./utils.js'),然后开 dev server,打开浏览器 Network 面板,你会看到一个新 chunk 文件(比如 utils.abc123.js)被单独请求——这就是代码分割生效了。
想控制 chunk 名称?加魔法注释:/* webpackChunkName: "chart" */(Webpack)或 /* viteIgnore */(Vite)。这样后续排查加载慢、缓存失效都更直观。
注意运行环境和边界情况
import() 在现代浏览器和 Node.js(ESM 模式)中都支持,但 SSR 场景下要注意:
- 服务端执行 import(),路径需为相对或绝对文件路径,不能是 CDN URL
- 某些旧版 Node 不支持 ESM 动态导入,得用
await import(pathToFileURL('./mod.js'))兼容 - 路径拼接别太随意,
import(basePath + '/mod.js')可能让构建工具无法预判所有可能路径,导致部分 chunk 没被打出来
另外,它不能在模块顶层直接调用(除非用顶层 await),必须包在函数里,这是语法硬性要求。


















