ES Modules 不支持 import 语句中直接写条件逻辑,但可通过动态导入 import() 配合 if/else、特性检测或用户操作实现运行时条件加载,支持按环境、浏览器能力、路由等场景灵活加载模块。

ES Modules 本身不支持直接在 import 语句中写条件逻辑(比如 if 判断),因为静态导入必须在编译时确定模块路径。但可以通过动态导入(import() 函数)配合条件语句实现运行时的条件化加载。
用 import() 动态加载 + if/else
import() 返回一个 Promise,可在任意 JavaScript 执行上下文中调用,包括条件分支、循环、函数内部等。
- 路径可以是字符串模板或变量,支持运行时拼接
- 加载成功后通过
.then()或await获取模块对象 - 适合按环境、用户权限、功能开关、浏览器特性等做加载决策
示例:根据环境加载不同配置模块
async function loadConfig() {
const env = process.env.NODE_ENV || 'development';
if (env === 'production') {
const { default: config } = await import('./config.prod.js');
return config;
} else {
const { default: config } = await import('./config.dev.js');
return config;
}
}
按浏览器能力做条件加载(如现代 vs 兼容模式)
利用 import() 配合特性检测,只给支持的浏览器加载新语法模块。
立即学习“Java免费学习笔记(深入)”;
- 例如检测
import.meta.url或Promise.allSettled等特性 - 也可结合
<script type="module">和nomodule做 HTML 层分流,再在模块内进一步细粒度加载
示例:按是否支持 ResizeObserver 加载对应组件
async function loadComponent() {
if ('ResizeObserver' in window) {
const { ResizablePanel } = await import('./ResizablePanel.modern.js');
return new ResizablePanel();
} else {
const { ResizablePanel } = await import('./ResizablePanel.fallback.js');
return new ResizablePanel();
}
}
结合路由或用户操作按需加载
常见于 SPA 中,点击菜单、切换 Tab、打开弹窗时才加载对应模块,减少首屏体积。
- 避免提前
import所有模块,而是把import()放在事件处理函数里 - 可搭配
Promise缓存(如单例加载)避免重复请求 - 支持
try/catch处理加载失败(如网络错误、404)
示例:点击按钮后加载并渲染图表模块
document.getElementById('chart-btn').addEventListener('click', async () => {
try {
const { renderChart } = await import('./charts/bar-chart.js');
renderChart(document.getElementById('chart-container'));
} catch (err) {
console.error('图表模块加载失败:', err);
alert('功能暂不可用,请稍后重试');
}
});
注意点和限制
动态导入虽灵活,但需留意以下细节:
-
import()路径必须是相对或绝对 URL,不能是纯变量(如import(moduleName)会报错),但可用模板字符串:import(`./modules/${name}.js`) - Webpack/Vite/Rollup 会自动识别
import()并生成独立 chunk;若路径含变量,打包工具可能预设多个匹配模块(如正则匹配) - 服务端 Node.js 中使用
import()需确保文件扩展名明确(如.js),且运行在 ESM 模式下(type: "module") - 不支持在模块顶层(非函数内)直接写带条件的
import(),但可包裹在 IIFE 或初始化函数中


















