Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Динамічний імпорт import()». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`import()` - функція-завантажувач, яка імпортує модуль під час виконання (а не статично на початку файлу), повертає Promise з експортами й може приймати шлях-змінну - на відміну від звичайного `import`, який статичний і синхронно парситься при запуску. **Ключове:** ідеально для умовного чи lazy-завантаження модулів - код завантажується лише тоді, коли він реально потрібен.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 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`) | | Контекст | CommonJS | ES 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](http://config.dev).js** ```javascript export default { db: 'sqlite', debug: true }; ``` **[config.prod](http://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` з експортами й дозволяє робити умовне, ліниве чи параметричне підвантаження коду під час виконання.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.