Асинхронне розділення коду

Дата оновлення перекладу 2024-05-27

Асинхронне розділення коду

Коли ви вимагаєте/імпортуєте модуль JavaScript або CSS, Webpack компілює цей код у у кінцевий файл JavaScript або CSS. Зазвичай, це саме те, що вам потрібно. Але що якщо вам потрібно використовувати частину коду лише за певних умов? Наприклад, що, якщо ви хочете використовувати video.js для відтворення відео, але тільки після того, як користувач натиснув на посилання:

1
2
3
4
5
6
7
8
9
10
// assets/app.js

import $ from 'jquery';
// фіктивний модуль "large" (наприклад, він імпортує video.js внутрішньо)
import VideoPlayer from './components/VideoPlayer';

$('.js-open-video').on('click', function() {
    // використати більший модуль VideoPlayer
    const player = new VideoPlayer('some-element');
});

У цьому прикладі модуль VideoPlayer і все, що він імпортує, буде упаковано у кінцевий, зібраний JavaScript-файл, хоча це може бути не дуже поширеною практикою для того, щоб це дійсно знадобилося. Кращим рішенням є використання динамічного імпорту: завантаження коду через AJAX, коли він потрібен:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// assets/app.js

import $ from 'jquery';

$('.js-open-video').on('click', function() {
    // ви можете розпочати завантаження анімації тут

    // викоирстати import() як функцію - вона повертає Promise
    import('./components/VideoPlayer').then(({ default: VideoPlayer }) => {
        // ви можете перестати завантажувати анімацію тут

        // використати більший модуль VideoPlayer
        const player = new VideoPlayer('some-element');

    }).catch(error => 'An error occurred while loading the component');
});

Використовуючи import() як функцію, модуль буде завантажено асинхронно і після завершення буде виконано зворотний виклик .then(). Аргумент VideoPlayer зворотного виклику буде завантаженим модулем. Іншими словами, це працює як звичайний AJAX виклик! За лаштунками Webpack упакує модуль VideoPlayer в окремий файл (наприклад, 0.js), щоб його можна було завантажити. Всі деталі оброблено за вас.

Частина { default: VideoPlayer } може виглядати дивно. При використанні асинхронного імпорту, у ваш зворотний виклик .then() передається об'єкт, де модуль дійсно знаходиться у ключі .default. Існують причини, чому так зроблено, але це виглядає дивно. Код
{ default: VideoPlayer } гарантує, що потрібний нам модуль VideoPlayer буде прочитано з цієї властивості .default.

Для отримання додаткової інформації та параметрів налаштування дивіться розділ динамічний імпорт у документації Webpack.