Динамический импорт: 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) — нет.

Связанные темы

Ресурсы