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

Начало работы с системой сборки CLI на основе esbuild

Функция системы сборки приложений на основе модуля ECMAScript (ESM) в esbuild доступна для предварительного просмотра разработчиком. Она уже готова к использованию, но может измениться до того, как станет стабильной, и пока не рекомендуется для производственных сборок.

В версии 16 и выше новая система сборки предоставляет способ создания приложений Angular. Новая система сборки включает в себя:

  • Современный формат вывода с использованием ESM, с динамическими выражениями импорта для поддержки ленивой загрузки модулей.
  • Более высокая производительность при сборке как для начальных сборок, так и для инкрементных перестроек.
  • Новые инструменты экосистемы JavaScript, такие как esbuild и Vite.

Вы можете выбрать использование нового билдера для каждого приложения с минимальными обновлениями конфигурации.

Пробуем систему сборки ESM в приложении Angular CLI

Новый билдер под названием browser-esbuild доступен в пакете @angular-devkit/build-angular, который присутствует в сгенерированном приложении Angular CLI. Этот билд является заменой существующего билдера browser, который обеспечивает текущую стабильную систему сборки браузерных приложений. Вы можете опробовать новую систему сборки для приложений, использующих конструктор browser.

Обновление конфигурации приложения

Новая система сборки была внедрена, чтобы минимизировать количество изменений, необходимых для перехода ваших приложений. В настоящее время новая система сборки предоставляется через альтернативный билдер (browser-esbuild). Вы можете обновить цель build для любого приложения, чтобы опробовать новую систему сборки.

Ниже приведено то, что вы обычно находите в файле angular.json для приложения:

1
2
3
4
5
 ...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
...

Изменение поля builder — это единственное изменение, которое вам нужно будет сделать.

1
2
3
4
5
 ...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser-esbuild",
...

Выполнение сборки

После обновления конфигурации приложения сборку можно выполнить с помощью команды ng build, как это было сделано ранее. Для остальных опций, которые в настоящее время еще не реализованы в предварительной версии для разработчиков, будет выдано предупреждение, и опция будет проигнорирована во время сборки.

1
ng build

Запуск сервера разработки

Сервер разработки теперь имеет возможность автоматически определять новую систему сборки и использовать ее для сборки приложения. Для запуска сервера разработки не требуется вносить изменения в конфигурацию сборщика dev-server или командную строку.

1
ng serve

Вы можете продолжать использовать опции командной строки, которые вы использовали в прошлом с сервером разработки.

Предварительная версия для разработчиков в настоящее время не обеспечивает поддержку HMR, и опции, связанные с HMR, будут игнорироваться при использовании. Возможности HMR, ориентированные на Angular, в настоящее время планируются и будут представлены в будущей версии.

Нереализованные опции и поведение

Несколько опций сборки еще не реализованы, но будут добавлены в будущем по мере продвижения системы сборки к стабильному состоянию. Если ваше приложение использует эти опции, вы можете опробовать систему сборки, не удаляя их. Для всех нереализованных опций будут выдаваться предупреждения, но в остальном они будут игнорироваться. Однако, если ваше приложение полагается на функционирование каких-либо из этих опций, возможно, вы захотите подождать, чтобы попробовать.

Сборка библиотек с помощью новой системы сборки через ng-packagr также пока невозможна, но поддержка сборки библиотек будет доступна в будущем релизе.

Импорты ESM по умолчанию в сравнении с импортами пространств имен

TypeScript по умолчанию позволяет импортировать экспорты по умолчанию как импорт пространства имен и затем использовать их в выражениях вызова. К сожалению, это расхождение со спецификацией ECMAScript. Базовый компоновщик (esbuild) в новой системе сборки ожидает код ESM, соответствующий спецификации. Система сборки теперь будет выдавать предупреждение, если ваше приложение использует неправильный тип импорта пакета. Однако, чтобы TypeScript мог принять правильное использование, в файле tsconfig приложения должна быть включена опция TypeScript. Если опция esModuleInterop включена, она обеспечивает лучшее соответствие спецификации ECMAScript, а также рекомендуется командой разработчиков TypeScript. Если опция включена, вы можете обновить импорт пакетов, где это необходимо, до формы, соответствующей ECMAScript.

На примере пакета moment следующий код приложения приведет к ошибкам во время выполнения:

1
2
3
import * as moment from 'moment';

console.log(moment().format());

Сборка выдаст предупреждение, чтобы сообщить вам о потенциальной проблеме. Предупреждение будет выглядеть следующим образом:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
▲ [WARNING] Calling "moment" will crash at run-time because it's an import namespace object, not a function [call-import-namespace]

    src/main.ts:2:12:
      2 │ console.log(moment().format());
        ╵             ~~~~~~

Consider changing "moment" to a default import instead:

    src/main.ts:1:7:
      1 │ import * as moment from 'moment';
        │        ~~~~~~~~~~~
        ╵        moment

Однако вы можете избежать ошибок времени выполнения и предупреждения, включив опцию esModuleInterop TypeScript для приложения и изменив импорт на следующий:

1
2
3
import moment from 'moment';

console.log(moment().format());

Vite в качестве сервера разработки

Использование Vite в Angular CLI в настоящее время возможно только в качестве сервера разработки. Даже без использования базовой системы сборки Vite предоставляет полнофункциональный сервер разработки с поддержкой клиентской стороны, собранный в малозависимый пакет npm. Это делает его идеальным кандидатом для обеспечения комплексной функциональности сервера разработки. Текущий процесс сервера разработки использует новую систему сборки для создания сборки приложения в памяти и передает результаты в Vite для обслуживания приложения. Использование Vite, как и сервера разработки на основе Webpack, инкапсулировано в конструкторе Angular CLI dev-server и в настоящее время не может быть настроено напрямую.

Известные проблемы

В настоящее время существует несколько известных проблем, с которыми вы можете столкнуться при использовании новой системы сборки. Этот список будет обновляться, чтобы оставаться актуальным. Если какая-либо из этих проблем мешает вам опробовать новую систему сборки, пожалуйста, загляните сюда в будущем, возможно, она уже решена.

Выражения динамического импорта с оценкой времени выполнения

Выражения динамического импорта, не содержащие статических значений, будут сохранены в исходном виде и не будут обрабатываться во время сборки. Это ограничение базового бандлера, но оно планируется быть реализовано в будущем. Во многих случаях код приложения можно заставить работать, изменив выражения импорта на статические строки с некоторой формой условного оператора, такого как if или switch для известных потенциальных файлов.

Не поддерживается:

1
return await import(`/abc/${name}.json`);

Поддерживается:

1
2
3
4
5
6
7
8
switch (name) {
    case 'x':
        return await import('/abc/x.json');
    case 'y':
        return await import('/abc/y.json');
    case 'z':
        return await import('/abc/z.json');
}

Зависимый от порядка импорт с побочными эффектами в ленивых модулях

Операторы импорта, которые зависят от определенного порядка, а также используются в нескольких ленивых модулях, могут привести к тому, что операторы верхнего уровня будут выполняться не по порядку. Это не частое явление, поскольку оно зависит от использования побочных модулей и не относится к опции polyfills.

Это вызвано дефектом в базовом бандлере, но будет устранено в одном из будущих обновлений.

Избегать использования модулей с нелокальными побочными эффектами (вне полифиллов) рекомендуется всегда, когда это возможно, независимо от используемой системы сборки, что позволяет избежать этой конкретной проблемы. Модули с нелокальными побочными эффектами могут оказывать негативное влияние как на размер приложения, так и на производительность во время выполнения.

Хэшированные имена файлов для неинжектируемых глобальных стилей/скриптов

Если ваше приложение в настоящее время использует под-опцию inject для любых глобальных стилей и скриптов через опции сборки styles или scripts, имена выходных файлов для этих стилей/скриптов будут неправильно содержать хэш. В зависимости от использования выходных файлов, это может привести к сбоям во время выполнения вашего приложения. Дополнительную информацию см. в соответствующем issue.

Сообщения об ошибках

Сообщайте о проблемах и запросах на GitHub.

Пожалуйста, по возможности предоставляйте минимальное воспроизведение, чтобы помочь команде в решении проблем.

Комментарии