Внести вклад
Инструменты разработчика
Angular CLI

Система сборки Angular-приложений

В v17 и выше новая система сборки предоставляет улучшенный способ сборки Angular-приложений. Эта новая система сборки включает:

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

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

ВАЖНО: Существующая система сборки на базе webpack и builder browser устарели. Приложения могут временно продолжать использовать builder browser, а проекты могут отказаться от миграции во время обновления, но команда Angular рекомендует мигрировать на новую систему сборки.

Для новых приложений

Новые приложения по умолчанию используют эту новую систему сборки через builder application.

Для существующих приложений

В зависимости от требований проекта доступны как автоматизированные, так и ручные процедуры. Начиная с v18, процесс обновления спросит, хотите ли вы мигрировать существующие приложения на новую систему сборки через автоматизированную миграцию. Перед миграцией рассмотрите просмотр раздела Известные проблемы, так как он может содержать релевантную информацию для вашего проекта.

ПОЛЕЗНО: Не забудьте удалить любые предположения CommonJS в серверном коде приложения при использовании SSR, такие как require, __filename, __dirname или другие конструкции из области модуля CommonJS. Весь код приложения должен быть совместим с ESM. Это не относится к сторонним зависимостям.

Автоматизированная миграция скорректирует и конфигурацию приложения в angular.json, и код со стилями, чтобы удалить предыдущее использование webpack-specific возможностей. Хотя многие изменения можно автоматизировать и большинству приложений дальнейшие изменения не потребуются, каждое приложение уникально, и могут потребоваться некоторые ручные изменения. После миграции попробуйте собрать приложение, так как могут появиться новые ошибки, требующие корректировок в коде. Ошибки по возможности попытаются предоставить решения проблемы, а более поздние разделы этого руководства описывают некоторые из более распространённых ситуаций, с которыми вы можете столкнуться. При обновлении до Angular v18 через ng update вам предложат выполнить миграцию. Эта миграция полностью необязательна для v18 и также может быть запущена вручную в любое время после обновления следующей командой:

ng update @angular/cli --name use-application-builder

Миграция делает следующее:

  • Преобразует существующую цель browser или browser-esbuild в application
  • Удаляет любые предыдущие SSR builders (потому что application теперь делает это).
  • Соответствующим образом обновляет конфигурацию.
  • Объединяет tsconfig.server.json с tsconfig.app.json и добавляет опцию TypeScript "esModuleInterop": true, чтобы импорты express были совместимы с ESM.
  • Обновляет серверный код приложения для использования новой структуры bootstrap и выходного каталога.
  • Удаляет любое webpack-specific использование таблиц стилей builder, такое как tilde или caret в @import/url(), и обновляет конфигурацию для предоставления эквивалентного поведения
  • Переходит на использование нового пакета Node.js с меньшей зависимостью @angular/build, если не найдено другого использования @angular-devkit/build-angular.

Ручная миграция

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

  • Builder browser-esbuild собирает только клиентский бандл приложения, спроектированный совместимым с существующим builder browser, предоставляющим прежнюю систему сборки. Этот builder предоставляет эквивалентные опции сборки и во многих случаях служит drop-in заменой для существующих приложений browser.
  • Builder application охватывает всё приложение, например клиентский бандл, а также опционально собирает сервер для SSR и выполняет prerendering статических страниц на этапе сборки.

Builder application обычно предпочтителен, так как улучшает сборки с SSR и упрощает будущий переход клиентских проектов на SSR. Однако он требует немного больше усилий по миграции, особенно для существующих SSR-приложений при ручном выполнении. Если builder application сложно принять для вашего проекта, browser-esbuild может быть более простым решением, дающим большую часть преимуществ производительности сборки с меньшим числом breaking changes.

Ручная миграция на compatibility builder

Builder с именем browser-esbuild доступен в пакете @angular-devkit/build-angular, присутствующем в приложении, сгенерированном Angular CLI. Можно попробовать новую систему сборки для приложений, использующих builder browser. Если используется пользовательский builder, обратитесь к документации этого builder о возможных вариантах миграции.

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

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

...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
...

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

...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser-esbuild",
...

Ручная миграция на новый builder application

Builder с именем application также доступен в пакете @angular-devkit/build-angular, присутствующем в приложении, сгенерированном Angular CLI. Этот builder — значение по умолчанию для всех новых приложений, создаваемых через ng new.

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

...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
...

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

...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:application",
...

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

  • main следует переименовать в browser.
  • polyfills должен быть массивом, а не одним файлом.
  • buildOptimizer следует удалить, так как это покрывается опцией optimization.
  • resourcesOutputPath следует удалить, теперь это всегда media.
  • vendorChunk следует удалить, так как это была оптимизация производительности, которая больше не нужна.
  • commonChunk следует удалить, так как это была оптимизация производительности, которая больше не нужна.
  • deployUrl следует удалить и не поддерживается. Предпочитайте <base href>. См. документацию по развёртыванию для дополнительной информации.
  • ngswConfigPath следует переименовать в serviceWorker.

Если приложение сейчас не использует SSR, это должен быть финальный шаг, позволяющий ng build работать. После первого выполнения ng build могут появиться новые предупреждения или ошибки на основе поведенческих различий или использования приложением webpack-specific возможностей. Многие предупреждения предоставят предложения по устранению проблемы. Если кажется, что предупреждение некорректно или решение неочевидно, откройте issue на GitHub. Также более поздние разделы этого руководства предоставляют дополнительную информацию о нескольких конкретных случаях, а также о текущих известных проблемах.

Для приложений, новых для SSR, руководство Angular SSR предоставляет дополнительную информацию о процессе настройки добавления SSR в приложение.

Для приложений, уже использующих SSR, потребуются дополнительные корректировки для обновления сервера приложения для поддержки новых интегрированных возможностей SSR. Builder application теперь предоставляет интегрированную функциональность для всех следующих ранее существовавших builders:

  • app-shell
  • prerender
  • server
  • ssr-dev-server

Процесс ng update автоматически удалит использования пакетов области @nguniversal, где ранее располагались некоторые из этих builders. Новый пакет @angular/ssr также будет автоматически добавлен и использован с корректировкой конфигурации и кода во время обновления. Пакет @angular/ssr поддерживает и builder browser, и builder application.

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

После обновления конфигурации приложения сборки можно выполнять с помощью ng build, как и раньше. В зависимости от выбора миграции builder некоторые опции командной строки могут отличаться. Если команда сборки содержится в каких-либо скриптах npm или других, убедитесь, что они просмотрены и обновлены. Для приложений, мигрировавших на builder application и использующих SSR и/или prerendering, также можно удалить лишние команды ng run из скриптов, теперь когда ng build имеет интегрированную поддержку SSR.

ng build

Запуск development-сервера

Development-сервер автоматически обнаружит новую систему сборки и использует её для сборки приложения. Для запуска development-сервера изменения в конфигурации builder dev-server или командной строке не нужны.

ng serve

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

ПОЛЕЗНО: С development-сервером при запуске можно увидеть небольшой Flash of Unstyled Content (FOUC), пока сервер инициализируется. Development-сервер пытается отложить обработку таблиц стилей до первого использования, чтобы улучшить время пересборки. Это не происходит в сборках вне development-сервера.

Hot module replacement

Hot Module Replacement (HMR) — техника, используемая development-серверами, чтобы избежать перезагрузки всей страницы, когда изменена только часть приложения. Изменения во многих случаях могут сразу отображаться в браузере, что позволяет улучшить цикл edit/refresh при разработке приложения. Хотя общий JavaScript-based hot module replacement (HMR) сейчас не поддерживается, доступны несколько более специфичных форм HMR:

  • глобальная таблица стилей (опция сборки styles)
  • таблица стилей компонента (inline и file-based)
  • шаблон компонента (inline и file-based)

Возможности HMR включаются автоматически и не требуют изменений кода или конфигурации для использования. Angular предоставляет поддержку HMR и для file-based (templateUrl/styleUrl/styleUrls), и для inline (template/styles) стилей и шаблонов компонентов. Система сборки попытается скомпилировать и обработать минимальный объём кода приложения при обнаружении изменения только таблицы стилей.

При желании возможности HMR можно отключить, установив опцию development-сервера hmr в false. Это также можно изменить в командной строке через:

ng serve --no-hmr

Vite как development-сервер

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

Prebundling

Prebundling обеспечивает улучшенное время сборки и пересборки при использовании development-сервера. Vite предоставляет возможности prebundling, которые включены по умолчанию при использовании Angular CLI. Процесс prebundling анализирует все сторонние зависимости проекта и обрабатывает их при первом запуске development-сервера. Этот процесс устраняет необходимость пересобирать и бандлить зависимости проекта при каждой пересборке или запуске development-сервера.

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

  • Настройку поведения loader для импортов внутри зависимости, например опция loader
  • Symlink зависимости на локальный код для разработки, например npm link
  • Обход ошибки, возникшей во время prebundling зависимости

Процесс prebundling можно полностью отключить или исключить отдельные зависимости, если это нужно проекту. Для этих кастомизаций можно использовать опцию prebundle builder dev-server. Чтобы исключить конкретные зависимости, доступна опция prebundle.exclude:

    "serve": {
      "builder": "@angular/build:dev-server",
      "options": {
        "prebundle": {
          "exclude": ["some-dep"]
        }
      },

По умолчанию prebundle установлен в true, но может быть установлен в false для полного отключения prebundling. Однако рекомендуется исключать конкретные зависимости, так как время пересборки увеличится при отключённом prebundling.

    "serve": {
      "builder": "@angular/build:dev-server",
      "options": {
        "prebundle": false
      },

Новые возможности

Одно из главных преимуществ системы сборки приложений — улучшенная скорость сборки и пересборки. Однако новая система сборки приложений также предоставляет дополнительные возможности, отсутствующие в builder browser.

ВАЖНО: Новые возможности builder application, описанные здесь, по умолчанию несовместимы с test builder karma, потому что он внутренне использует builder browser. Пользователи могут включить использование builder application, установив опцию builderMode в application для builder karma. Эта опция сейчас в developer preview. Если заметите какие-либо проблемы, сообщите о них здесь.

Замена значений на этапе сборки с define

Опция define позволяет заменять идентификаторы, присутствующие в коде, другим значением на этапе сборки. Это похоже на поведение Webpack DefinePlugin, который ранее использовался с некоторыми пользовательскими конфигурациями Webpack, использовавшими сторонние builders. Опцию можно использовать либо в файле конфигурации angular.json, либо в командной строке. Настройка define в angular.json полезна для случаев, когда значения постоянны и могут быть закоммичены в систему контроля версий.

В файле конфигурации опция имеет форму объекта. Ключи объекта представляют идентификатор для замены, а значения объекта — соответствующее значение замены для идентификатора. Пример:

  "build": {
    "builder": "@angular/build:application",
    "options": {
      ...
      "define": {
          "SOME_NUMBER": "5",
          "ANOTHER": "'this is a string literal, note the extra single quotes'",
          "REFERENCE": "globalThis.someValue.noteTheAbsentSingleQuotes"
      }
    }
  }

ПОЛЕЗНО: Все значения замены определяются как строки в файле конфигурации. Если замена должна быть фактическим строковым литералом, её следует заключить в одинарные кавычки. Это позволяет гибко использовать любой допустимый тип JSON, а также другой идентификатор как замену.

Использование командной строки предпочтительно для значений, которые могут меняться при каждом выполнении сборки, например hash коммита git или переменная окружения. CLI объединит значения --define из командной строки со значениями define из angular.json, включая оба в сборку. Использование командной строки имеет приоритет, если один и тот же идентификатор присутствует в обоих. Для использования командной строки опция --define использует формат IDENTIFIER=VALUE.

ng build --define SOME_NUMBER=5 --define "ANOTHER='these will overwrite existing'"

Переменные окружения также можно выборочно включать в сборку. Для оболочек не-Windows кавычки вокруг литерала hash можно экранировать напрямую, если предпочтительно. Этот пример предполагает bash-like оболочку, но похожее поведение доступно и для других оболочек.

export MY_APP_API_HOST="http://example.com"
export API_RETRY=3
ng build --define API_HOST=\'$MY_APP_API_HOST\' --define API_RETRY=$API_RETRY

Для любого использования TypeScript должен знать типы идентификаторов, чтобы предотвратить ошибки проверки типов во время сборки. Это можно сделать с помощью дополнительного файла определения типов в исходном коде приложения (например, src/types.d.ts) с похожим содержимым:

declare const SOME_NUMBER: number;
declare const ANOTHER: string;
declare const GIT_HASH: string;
declare const API_HOST: string;
declare const API_RETRY: number;

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

ВАЖНО: Эта опция не заменит идентификаторы, содержащиеся в метаданных Angular, таких как декоратор Component или Directive.

Кастомизация loader по расширению файла

ВАЖНО: Эта возможность доступна только с builder application.

Некоторым проектам может потребоваться контролировать, как все файлы с конкретным расширением загружаются и включаются в бандл приложения. При использовании builder application для обработки этих случаев можно использовать опцию loader. Опция позволяет проекту определить тип loader для использования с указанным расширением файла. Файл с определённым расширением затем можно использовать в коде приложения через оператор import или выражение динамического импорта. Доступные loaders:

  • text — встраивает содержимое как string, доступный как default export
  • binary — встраивает содержимое как Uint8Array, доступный как default export
  • file — эмитит файл по выходному пути приложения и предоставляет runtime-расположение файла как default export
  • dataurl — встраивает содержимое как data URL.
  • base64 — встраивает содержимое как строку в кодировке Base64.
  • empty — считает содержимое пустым и не включит его в бандлы

Значение empty, хотя и менее распространено, может быть полезно для совместимости сторонних библиотек, которые могут содержать bundler-specific использование импортов, которое нужно удалить. Один случай для этого — side-effect импорты (import 'my.css';) CSS-файлов, которые не имеют эффекта в браузере. Вместо этого проект может использовать empty, а затем CSS-файлы можно добавить в опцию сборки styles или использовать другой метод внедрения.

Опция loader — объектная опция, где ключи определяют расширение файла, а значения — тип loader.

Пример использования опции сборки для встраивания содержимого SVG-файлов в бандл приложения:

  "build": {
    "builder": "@angular/build:application",
    "options": {
      ...
      "loader": {
        ".svg": "text"
      }
    }
  }

Затем SVG-файл можно импортировать:

import contents from './some-file.svg';

console.log(contents); // <svg>...</svg>

Кроме того, TypeScript должен знать тип модуля для импорта, чтобы предотвратить ошибки проверки типов во время сборки. Это можно сделать с помощью дополнительного файла определения типов в исходном коде приложения (например, src/types.d.ts) со следующим или похожим содержимым:

declare module '*.svg' {
  const content: string;
  export default content;
}

Конфигурация проекта по умолчанию уже настроена на использование любых файлов определения типов (файлы .d.ts), присутствующих в исходных каталогах проекта. Если конфигурация TypeScript проекта была изменена, tsconfig может потребоваться скорректировать, чтобы ссылаться на этот вновь добавленный файл определения типов.

Кастомизация loader через import attribute

Для случаев, когда только определённые файлы должны загружаться конкретным способом, доступен контроль загрузки на уровне файла. Это достигается с помощью import attribute loader, который можно использовать и с операторами import, и с выражениями. Наличие import attribute имеет приоритет над всем другим поведением загрузки, включая JS/TS и любые значения опции сборки loader. Для общей загрузки всех файлов иначе неподдерживаемого типа файла рекомендуется опция сборки loader.

Для import attribute поддерживаются следующие значения loader:

  • text — встраивает содержимое как string, доступный как default export
  • binary — встраивает содержимое как Uint8Array, доступный как default export
  • file — эмитит файл по выходному пути приложения и предоставляет runtime-расположение файла как default export
  • dataurl — встраивает содержимое как data URL.
  • base64 — встраивает содержимое как строку в кодировке Base64.

Дополнительное требование для использования import attributes — опция TypeScript module должна быть установлена в esnext, чтобы TypeScript успешно собрал код приложения. Как только ES2025 станет доступен в TypeScript, это изменение больше не понадобится.

На данный момент TypeScript не поддерживает определения типов на основе значений import attribute. Сейчас требуется использование @ts-expect-error/@ts-ignore или использование отдельных файлов определения типов (при условии, что файл импортируется только с тем же атрибутом loader). Как пример, SVG-файл можно импортировать как текст через:

// @ts-expect-error TypeScript cannot provide types based on attributes yet
import contents from './some-file.svg' with {loader: 'text'};

То же можно сделать с выражением import внутри async-функции.

async function loadSvg(): Promise<string> {
  // @ts-expect-error TypeScript cannot provide types based on attributes yet
  return import('./some-file.svg', {with: {loader: 'text'}}).then((m) => m.default);
}

Для выражения import значение loader должно быть строковым литералом для статического анализа. Если значение не является строковым литералом, будет выдано предупреждение.

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

// @ts-expect-error TypeScript cannot provide types based on attributes yet
import imagePath from './image.webp' with {loader: 'file'};

console.log(imagePath); // media/image-ULK2SIIB.webp

Loader base64 полезен, когда файл нужно встроить напрямую в бандл как закодированную строку, которую позже можно использовать для построения Data URL.

// @ts-expect-error TypeScript cannot provide types based on attributes yet
import logo from './logo.png' with {loader: 'base64'};

console.log(logo); // "iVBORw0KGgoAAAANSUhEUgAA..."

Loader dataurl для встраивания ресурсов как полных Data URL.

// @ts-expect-error TypeScript cannot provide types based on attributes yet
import icon from './icon.svg' with {loader: 'dataurl'};

console.log(icon); // "data:image/svg+xml;..."

Для production-сборок, как показано в комментарии к коду выше, hashing будет автоматически добавлен к пути для долгосрочного кэширования.

ПОЛЕЗНО: При использовании development-сервера и атрибута loader для импорта файла из пакета Node.js этот пакет должен быть исключён из prebundling через опцию development-сервера prebundle.

Условия import/export

Проектам может потребоваться сопоставлять определённые пути импорта с разными файлами в зависимости от типа сборки. Это особенно полезно для случаев, когда ng serve нужно использовать debug/development-specific код, а ng build — код без каких-либо development-возможностей/информации. Несколько условий import/export применяются автоматически для поддержки этих потребностей проекта:

  • Для оптимизированных сборок включается условие production.
  • Для неоптимизированных сборок включается условие development.
  • Для browser-выходного кода включается условие browser.

Оптимизированная сборка определяется значением опции optimization. Когда optimization установлен в true или, более конкретно, если optimization.scripts установлен в true, сборка считается оптимизированной. Эта классификация применяется и к ng build, и к ng serve. В новом проекте ng build по умолчанию оптимизирован, а ng serve — неоптимизирован.

Полезный метод использования этих условий в коде приложения — комбинировать их с subpath imports. Используя следующий оператор import:

import {verboseLogging} from '#logger';

Файл можно переключать в поле imports в package.json:

{
  ...
  "imports": {
    "#logger": {
      "development": "./src/logging/debug.ts",
      "default": "./src/logging/noop.ts"
    }
  }
}

Для приложений, также использующих SSR, browser и server код можно переключать с помощью условия browser:

{
  ...
  "imports": {
    "#crashReporter": {
      "browser": "./src/browser-logger.ts",
      "default": "./src/server-logger.ts"
    }
  }
}

Эти условия также применяются к пакетам Node.js и любым определённым exports внутри пакетов.

ПОЛЕЗНО: Если сейчас используется опция сборки fileReplacements, эта возможность может заменить её использование.

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

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

Проверка типов кода Web Worker и обработка вложенных Web Workers

Web Workers можно использовать в коде приложения с тем же синтаксисом (new Worker(new URL('<workerfile>', import.meta.url))), который поддерживается с builder browser. Однако код внутри Worker сейчас не будет проверяться на типы компилятором TypeScript. Код TypeScript поддерживается, просто не проверяется на типы. Кроме того, любые вложенные workers не будут обрабатываться системой сборки. Вложенный worker — это создание экземпляра Worker внутри другого файла Worker.

ESM default imports vs. namespace imports

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

Используя пакет moment как пример, следующий код приложения вызовет runtime-ошибки:

import * as moment from 'moment';

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

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

▲ [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

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

import moment from 'moment';

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

Order-dependent side-effectful imports в ленивых модулях

Операторы import, зависящие от конкретного порядка и также используемые в нескольких ленивых модулях, могут привести к выполнению top-level операторов не по порядку. Это нетипично, так как зависит от использования side-effectful модулей и не применяется к опции polyfills. Это вызвано дефектом в базовом bundler, но будет устранено в будущем обновлении.

ВАЖНО: Избегание использования модулей с нелокальными side effects (вне polyfills) рекомендуется всегда, когда возможно, независимо от используемой системы сборки, и избегает этой конкретной проблемы. Модули с нелокальными side effects могут отрицательно влиять и на размер приложения, и на runtime-производительность.

Изменения расположения вывода

По умолчанию после успешной сборки builder application бандл располагается в каталоге dist/<project-name>/browser (вместо dist/<project-name> для browser builder). Это может сломать некоторые toolchain, опирающиеся на предыдущее расположение. В этом случае можно настроить выходной путь под свои нужды.

Отчёты об ошибках

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

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