Динамічний імпорт
Що таке динамічний імпорт
Динамічний імпорт - це виклик функції import(), яка повертає Promise і дозволяє завантажувати модулі під час виконання програми (runtime), а не під час збірки.
Приклад:
// Динамічний імпорт
const module = await import('./utils.js');
module.sayHello();Відмінність від статичного імпорту:
// Статичний імпорт
import { sayHello } from './utils.js';При статичному імпорті весь модуль завантажується одразу під час запуску. При динамічному - тільки коли справді потрібен.
Синтаксис
import(modulePath)
.then(module => {
// модуль завантажено
module.default();
})
.catch(err => console.error(err));або з await:
const module = await import('./math.js');
const { sum } = module;
console.log(sum(2, 3));Що повертає import()
import() повертає Promise, який резолвиться об'єктом модуля:
// math.js
export function add(a, b) { return a + b; }
export const PI = 3.14;const math = await import('./math.js');
console.log(math.add(2, 3)); // 5
console.log(math.PI); // 3.14Приклад: умовне завантаження (conditional import)
Можна динамічно завантажувати різні модулі залежно від ситуації:
if (navigator.language.startsWith('fr')) {
const messages = await import('./lang/fr.js');
console.log(messages.default.hello);
} else {
const messages = await import('./lang/en.js');
console.log(messages.default.hello);
}Чудово підходить для багатомовних інтерфейсів, плагінів, важких залежностей та лінивого завантаження сторінок (lazy loading).
Приклад: обробка помилок при завантаженні
try {
const module = await import('./missing.js');
} catch (err) {
console.error('Помилка при завантаженні модуля:', err);
}Приклад: завантаження за дією користувача
button.addEventListener('click', async () => {
const { openModal } = await import('./modal.js');
openModal();
});Модуль modal.js буде завантажено тільки при першому кліку,
а не під час запуску сайту - економія трафіку і прискорення старту.
Динамічний імпорт зі змінними
Можна використовувати динамічні шляхи, чого неможливо зі статичними імпортами:
const theme = 'dark';
const module = await import(`./themes/${theme}.js`);
module.applyTheme();Важливо: збирач (наприклад, Webpack) все одно повинен уміти передбачити шаблон шляхів - інакше він не включить потрібні файли в збірку.
Коли використовувати динамічний імпорт
| Сценарій | Чому корисний |
|---|---|
| Lazy loading компонентів | Завантажуємо компонент тільки при переході на потрібну сторінку |
| Переклади / локалізація | Імпортуємо потрібну мову динамічно |
| Важкі залежності | Відкладене завантаження великих бібліотек (chart.js, moment, three.js) |
| Плагіни / модульна архітектура | Підключаємо функціональність за запитом |
| SSR + Code splitting | У Next.js, Vite, Webpack - автоматичний розрив бандлів |
| Feature flags / A/B тести | Завантажуємо різні модулі залежно від прапора |
Як це працює під капотом
Збирачі (Webpack, Rollup, Vite, ESBuild):
- Аналізують вирази
import('./path'). - Роблять code splitting - розбивають проєкт на чанки.
- При виклику
import()завантажують потрібний чанк по мережі.
Приклад (Webpack output):
main.js (основний код)
vendors~chart.js (бібліотека)
chart.js (завантажиться при кліку)Відмінність від require()
| Критерій | import() | require() |
|---|---|---|
| Тип | Асинхронний (Promise) | Синхронний |
| Працює в | ESM (браузер, Node) | CommonJS (Node) |
| Можна використовувати динамічно | Так | Обмежено |
| Підтримує tree-shaking | Так | Ні |
| Підтримується збирачами (code-splitting) | Так | Ні |
Приклад: у React / Next.js
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('../components/Chart'), {
ssr: false,
loading: () => <p>Завантаження...</p>,
});
export default function Page() {
return (
<div>
<h1>Дані</h1>
<Chart />
</div>
);
}Компонент <Chart> підвантажиться тільки в браузері,
і тільки коли користувач відкриє сторінку.
Підсумок
| Що робить | Завантажує модулі асинхронно (за потреби) |
|---|---|
| Повертає | Promise з об'єктом модуля |
| Працює в | ES Modules (Node, браузер) |
| Використовується для | Lazy loading, code splitting, A/B тестів, динамічної локалізації |
| Синтаксис | const module = await import('./file.js') |
Головна ідея:
Динамічний імпорт - це "лінива" завантаження модулів. Замість того щоб тягнути весь застосунок одразу, ти вантажиш тільки те, що потрібно, коли це потрібно.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.