Динамический импорт: import
import(path)— функция (не директива), возвращающаяPromiseс объектом модуля, позволяющая загружать ES-модули лениво — по требованию, а не при старте приложения.
Зачем нужно
Статический import загружает все зависимости при запуске, увеличивая начальный бандл. Динамический import позволяет разбить код на чанки и загружать их только когда нужно — при навигации, клике, после первого взаимодействия. Это ключевая техника code splitting для ускорения Time to Interactive.
Где используется
- Code splitting: загрузка страниц/компонентов только при переходе
- Условный импорт в зависимости от среды, флагов или роли
- Ленивая загрузка тяжёлых библиотек (chart.js, moment, pdf-lib)
- Импорт по динамическому пути (из строки/переменной)
Синтаксис
// Возвращает Promise<ModuleNamespace>
const module = await import('./path/to/module.js');
// Аналогично через .then
import('./module.js').then(mod => {
mod.default; // вызов default-экспорта
mod.namedFn; // вызов named-экспорта
});
Примеры
Ленивая загрузка при клике
document.getElementById('open-chart').addEventListener('click', async () => {
// Загружаем Chart.js только при первом клике
const { Chart } = await import('https://cdn.jsdelivr.net/npm/chart.js');
renderChart(Chart);
});
Code splitting для роутинга
const routes = {
'/': => import('./pages/Home.js'),
'/about': => import('./pages/About.js'),
'/admin': => import('./pages/Admin.js'),
};
async function navigate(path) {
const loadPage = routes[path] || routes['/'];
const { default: Page } = await loadPage;
document.getElementById('app').innerHTML = '';
new Page(document.getElementById('app'));
}
window.addEventListener('popstate', () => navigate(location.pathname));
navigate(location.pathname);
Условный импорт
async function loadTranslations(lang) {
// Путь вычисляется динамически
const { default: translations } = await import(`./i18n/${lang}.js`);
return translations;
}
const t = await loadTranslations(userLang); // './i18n/ru.js'
Деструктуризация именованных экспортов
// utils.js
export function formatDate(d) { ... }
export function formatPrice(p) { ... }
// main.js
const { formatDate, formatPrice } = await import('./utils.js');
С обработкой ошибок
async function loadModule(path) {
try {
return await import(path);
} catch (err) {
console.error(`Не удалось загрузить модуль ${path}:`, err);
return null;
}
}
Частые ошибки
- Динамический импорт в не-async функции —
importвозвращает промис; не забывайтеawaitили.then. - Кеширование — браузер и бандлеры кешируют модули; повторный
import('./same.js')не загрузит файл заново. - Неверный путь в динамическом import — некоторые бандлеры (webpack) не могут разрешить полностью динамические пути; использование шаблона типа
`./i18n/${lang}.js`работает, а переменнаяimport(someVar)— нет.