Skip to main content

Динамічний імпорт import()

1. Що таке динамічний імпорт

import() - це функція-завантажувач, яка дозволяє імпортувати модуль під час виконання (runtime), а не статично на початку файлу.

На відміну від звичайного import, який працює тільки на верхньому рівні і синхронно парситься під час запуску, import():

  • викликається в будь-якій частині коду (наприклад, усередині if, функції, обробника);
  • повертає Promise, який резолвиться в об'єкт з експортами модуля.

2. Синтаксис

javascript
const module = await import('./file.js');

чи через .then():

javascript
import('./file.js').then((module) => { console.log(module); });

3. Приклад використання в Node.js (ESM)

math.js

javascript
export function add(a, b) { return a + b; } export function multiply(a, b) { return a * b; }

app.mjs

javascript
const { add } = await import('./math.js'); console.log(add(2, 3)); // 5

Працює, якщо:

  • твій проєкт - ESM ("type": "module" у package.json),
  • чи файл має розширення .mjs.

4. Приклад з умовним завантаженням

javascript
if (process.env.NODE_ENV === 'production') { const analytics = await import('./analytics.js'); analytics.init(); } else { console.log('Аналітика вимкнена в режимі розробки'); }

Модуль analytics.js не буде завантажений, поки умова не виконається. Це економить ресурси - відмінна техніка для lazy-loading.

5. Приклад усередині функції

javascript
async function loadAndUseModule() { const { greet } = await import('./greetings.js'); greet('Tim'); } loadAndUseModule();

greetings.js

javascript
export function greet(name) { console.log(`Привіт, ${name}!`); }

6. Імпорт усього модуля

javascript
const math = await import('./math.js'); console.log(math.add(2, 2)); console.log(math.multiply(2, 3));

math містить усі експорти:

javascript
{ add: [Function: add], multiply: [Function: multiply] }

7. Імпорт за змінною

На відміну від статичного import, динамічний import() може використовувати змінні:

javascript
const moduleName = './features/' + process.argv[2] + '.js'; const feature = await import(moduleName); feature.run();

Це неможливо за звичайного import, тому що він вимагає статичного шляху:

javascript
import './' + path; // Помилка синтаксису

8. Імпорт JSON-файлів (Node.js 20+)

Node.js тепер дозволяє імпортувати JSON через import():

javascript
const data = await import('./config.json', { assert: { type: 'json' } }); console.log(data.default);

Обов'язково вказати assert:

  • { type: 'json' } повідомляє Node.js, що потрібно завантажити JSON як модуль.

9. Динамічний імпорт CommonJS-модулів

Якщо ти в ESM-проєкті, а хочеш імпортувати CommonJS-модуль (старий require):

javascript
const { readFileSync } = await import('fs'); const chalk = await import('chalk'); console.log(chalk.default.green('OK!'));

Node.js автоматично "обгортає" CJS-модуль, тому за замовчуванням він доступний через default.

10. Імпорт усередині циклу

Динамічний імпорт корисний для масового підвантаження модулів:

javascript
const features = ['auth', 'billing', 'analytics']; for (const f of features) { const mod = await import(`./modules/${f}.js`); mod.init?.(); }

11. Приклад: Lazy Loading на практиці

routes.mjs

javascript
export async function handleRoute(route) { if (route === '/admin') { const admin = await import('./routes/admin.mjs'); return admin.handler(); } const home = await import('./routes/home.mjs'); return home.handler(); }

Це ідеальний патерн для великих серверів (Express, Fastify, Next.js SSR):

  • завантажуються лише потрібні обробники;
  • немає зайвої пам'яті в runtime.

12. Особливості й відмінності від require()

Критерійrequire() (CJS)import() (ESM)
ЗавантаженняСинхроннеАсинхронне (Promise)
КонтекстCommonJSES Modules
КешуванняЄЄ
Live BindingsНемаєТак
Можна викликати будь-деТакТак
Підтримує awaitНіТак
У браузерахНіТак

13. Комбінований приклад (Node.js + ESM)

package.json

javascript
{ "type": "module" }

app.js

javascript
async function start() { const env = process.env.NODE_ENV || 'dev'; const { default: config } = await import(`./config.${env}.js`); console.log('Config loaded:', config); } start();

config.dev.js

javascript
export default { db: 'sqlite', debug: true };

config.prod.js

javascript
export default { db: 'postgres', debug: false };

→ під час запуску підставляється правильний конфіг без надлишкових імпортів.

14. Під капотом

Node.js під час виклику import():

  1. Аналізує URL (зокрема відносні й абсолютні);
  2. Асинхронно завантажує модуль;
  3. Кешує його;
  4. Повертає Promise, що резолвиться в об'єкт експортів.

Тобто import() ≈ "лінива" версія import + await require().

Коротке резюме

Що робитьПовертаєКоли виконується
import()Promise з експортами модуляПід час виконання (runtime)
import (статичний)Миттєво пов'язує модуль під час парсингуДо виконання коду

Одним реченням

Динамічний імпорт (import()) - це асинхронний спосіб завантажувати модулі "на льоту" в ES Modules, який повертає Promise з експортами й дозволяє робити умовне, ліниве чи параметричне підвантаження коду під час виконання.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.