Перейти к содержанию

Динамический импорт

Динамические импорты - это новая фича и часть ECMAScript, которая позволяет пользователям асинхронно запрашивать модуль в любом месте вашей программы. TC39 комитет по JavaScript имеет свое собственное предложение, которое находится на стадии 4, и оно называется import() proposal for JavaScript.

Кроме того, сборщик webpack имеет функцию под названием Code Splitting, позволяющую разбивать вашу сборку на части, загружающиеся асинхронно позже. Это, например, позволяет при первой загрузке отдать минимальную сборку, а затем асинхронно догрузить дополнительные функции.

Естественно думать (если мы используем webpack в нашем рабочем процессе разработки), что TypeScript 2.4 динамические импорты автоматически создадут и разделят на части код вашей финальной сборки JS. НО это не так просто, как кажется, потому что это зависит от конфигурации tsconfig.json, с которой мы работаем.

Дело в том, что webpack поддерживает два способа для аналогичного разбиения кода: использование import () (предпочтительно, предложение ECMAScript) и require.ensure () (устаревшее, специфичное для webpack). И это означает, что ожидаемый результат от TypeScript - это оставить оператор import () как есть вместо того, чтобы транспилировать его во что либо еще.

Давайте рассмотрим пример, чтобы выяснить, как настроить webpack + TypeScript 2.4.

В следующем коде я хочу отложенно загрузить библиотеку moment, но меня также интересует разбиение кода, что означает наличие библиотеки moment в отдельной части JS (файл JavaScript), который будет загружен только при необходимости.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import(/* webpackChunkName: "momentjs" */ 'moment')
    .then((moment) => {
        // lazyModule имеет все нужные типы, автозаполнение работает,
        // проверка типов работает, ссылки на код работают \o/
        const time = moment().format();
        console.log(
            'TypeScript >= 2.4.0 Динамический импорт:'
        );
        console.log(time);
    })
    .catch((err) => {
        console.log('Ошибка в загрузке moment', err);
    });

Вот tsconfig.json:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
    "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "lib": [
            "dom",
            "es5",
            "scripthost",
            "es2015.promise"
        ],
        "jsx": "react",
        "declaration": false,
        "sourceMap": true,
        "outDir": "./dist/js",
        "strict": true,
        "moduleResolution": "node",
        "typeRoots": ["./node_modules/@types"],
        "types": ["node", "react", "react-dom"]
    }
}

Важные примечания:

Вы можете увидеть полный пример здесь.

Комментарии