Пошук уроків, статей та іншого контенту
import() як функція для завантаження коду на вимогу, і чим script type=module відрізняється від звичайного script.
Звичайний import { add } from "./math.js" аналізується ще до виконання коду — рушій завантажує всі імпортовані модулі заздалегідь, навіть якщо код, що ними користується, ніколи не виконається. Для великих застосунків це означає завантаження коду, який відвідувач, можливо, ніколи не побачить (наприклад, адмін-панель, до якої в звичайного користувача немає доступу).
import() — це функція (не оператор, як статичний import), що повертає Promise (модуль «Асинхронний JavaScript») і завантажує модуль лише в момент виклику:
button.addEventListener("click", async () => {
const { generateChart } = await import("./chart.js");
generateChart(data); // код chart.js завантажується лише зараз, при першому кліку
});Це основа техніки «розділення коду» (code splitting): важкі бібліотеки чи рідко потрібні частини застосунку завантажуються лише тоді, коли справді знадобляться, замість того, щоб сповільнювати початкове завантаження сторінки для всіх відвідувачів.
Модулі можна підключати прямо в HTML — досить додати атрибут type:
<script type="module" src="app.js"></script>Кілька важливих відмінностей від звичайного script, які варто знати:
Модулі завжди виконуються в strict mode автоматично (модуль «Вступ до JavaScript») — директиву "use strict" писати не потрібно.
Модулі за поведінкою завантаження схожі на атрибут defer (модуль «Вступ до JavaScript»): не блокують парсинг HTML і виконуються після побудови DOM.
Кожен модуль має власну область видимості — змінні верхнього рівня НЕ потрапляють у глобальний об'єкт window, на відміну від звичайних скриптів.
Модулі, завантажені через file:// (з локального диска без сервера), у більшості браузерів блокуються політикою CORS — потрібен локальний сервер розробки навіть для найпростішого прикладу.
const showEmojiPickerBtn = document.querySelector("#emoji-btn");
showEmojiPickerBtn.addEventListener("click", async () => {
const { EmojiPicker } = await import("./emoji-picker.js"); // важкий модуль, потрібен рідко
new EmojiPicker().show();
});Очікування, що import() виконується миттєво й синхронно — це асинхронна операція, результат доступний лише після await чи .then.
Відкриття HTML-файлу з модулями напряму подвійним кліком (file://) замість через локальний сервер розробки.
Спроба звернутись до змінної верхнього рівня модуля через window — модулі не додають нічого в глобальний об'єкт автоматично.
Динамічний import() — функція, що асинхронно завантажує модуль саме тоді, коли він потрібен, а не заздалегідь — основа для розділення коду у великих застосунках. script type=module у браузері вмикає справжні ES-модулі зі своєю областю видимості, автоматичним strict mode та поведінкою завантаження, схожою на defer.
Спробуйте самостійно
Напишіть обробник кліку на кнопці, який через await import(...) динамічно підвантажує уявний модуль ./confetti.js з функцією launchConfetti() і викликає її одразу після завантаження.