Angular
Сборка: CLI, esbuild и schematics
Продакшен-сборка крупного приложения раньше шла на Webpack три минуты, а dev-сервер стартовал за полминуты. После перехода на application builder на esbuild холодная сборка ужалась в разы, а dev-сервер на Vite поднимается почти мгновенно за счёт ленивой обработки модулей. За этими цифрами стоит не магия, а смена сборочного движка под одной и той же командой ng build. Понимание архитектуры CLI - билдеров, schematics, миграций - превращает его из чёрного ящика в управляемый инструмент.
- Angular CLI - официальный инструмент сборки, под капотом которого в современных версиях работают esbuild и Vite вместо Webpack
- ng generate использует schematics для генерации компонентов, сервисов и целых фич по шаблонам - так работают и сторонние библиотеки
- ng update запускает миграции схематиками: при обновлении версии Angular код автоматически переписывается под новые API
- Nx и корпоративные монорепо строят свои билдеры и генераторы поверх той же архитектуры CLI
- Application builder заменил отдельные browser- и server-билдеры единым строителем для SSR, гидратации и SPA
Предварительные знания
- Опыт работы с Angular CLI: ng new, ng serve, ng build
- Понимание, что такое бандлинг и tree-shaking на уровне идеи
- Базовое представление о TypeScript-компиляции в JavaScript
От Webpack к esbuild и Vite
Долгие годы Angular CLI собирал приложения на Webpack - мощном, но медленном из-за обработки на JavaScript. С ростом проектов время сборки стало болью. В Angular 16 (2023) появился experimental esbuild builder, а в Angular 17 (ноябрь 2023) application builder на esbuild для продакшен-сборки и Vite для dev-сервера стал значением по умолчанию. esbuild написан на Go и бандлит на порядок быстрее, а Vite обслуживает dev-режим, отдавая модули по запросу. К 2025-2026 году Webpack-билдер остался как legacy, а application builder - основной путь.
Архитектура CLI: билдеры и angular.json
Angular CLI сам ничего не собирает - он оркестратор. Когда выполняется ng build, CLI смотрит в файл angular.json, находит для цели build назначенный билдер и запускает его с переданными опциями. Билдер - это и есть исполнитель конкретной задачи: один отвечает за сборку, другой за dev-сервер, третий за тесты. Такая развязка позволяет менять движок сборки, не меняя команду.
Каждая цель (target) под architect связывает имя команды с билдером и его опциями. ng build запускает цель build, ng serve - цель serve, ng test - test. Поле builder указывает конкретный пакет-исполнитель. Подменив его, можно переключить, скажем, тестовый раннер или весь сборочный движок, и команда ng test останется прежней.
Именно эта развязка позволила Angular заменить Webpack на esbuild незаметно для пользователя: поменялся билдер за целью build, а команда ng build осталась той же. На той же архитектуре Nx и другие инструменты подключают собственные билдеры поверх стандартного CLI.
Что происходит под капотом, когда разработчик запускает ng build?
Application builder: esbuild и Vite
Application builder (@angular/build:application) - это билдер по умолчанию с Angular 17. Он объединяет два движка под разные режимы. Для продакшен-сборки используется esbuild - бандлер, написанный на Go, который компилирует и связывает модули на порядок быстрее Webpack. Для dev-режима задействован Vite: он не бандлит всё заранее, а отдаёт модули браузеру по запросу, поэтому dev-сервер стартует почти мгновенно независимо от размера приложения.
- Webpack (legacy) — Обработка на JavaScript. Бандлит весь граф заранее и в dev, и в prod. Мощный и гибкий, но медленный на крупных проектах.
- Application builder — Prod на esbuild (Go, на порядок быстрее), dev на Vite (модули по запросу, мгновенный старт). Единый билдер для SPA, SSR и гидратации.
Разделение режимов неслучайно. В продакшене важен один оптимизированный бандл с tree-shaking и минификацией - это работа esbuild. В разработке важна скорость обратной связи: Vite не тратит время на полный бандл, а трансформирует и отдаёт только запрошенные модули, обновляя изменённое через HMR. Один application builder покрывает оба сценария и заодно объединил прежние раздельные browser- и server-билдеры для SSR.
Тот же сборочный конвейер переиспользуется тестами: Vitest в Angular 21 берёт esbuild-трансформацию application builder, поэтому тесты компилируются тем же быстрым движком, что и приложение. Сборка и тесты делят пайплайн, а не дублируют его.
esbuild жертвует частью гибкости Webpack ради скорости: экзотические Webpack-лоадеры и плагины напрямую не работают. Для большинства приложений это не проблема, но проект с тяжёлой кастомизацией Webpack потребует переноса этой логики на возможности application builder или кастомный билдер.
Почему application builder использует esbuild для продакшена, но Vite для dev-сервера?
Schematics: генерация кода
Schematic - это генератор, который по шаблону и параметрам создаёт или изменяет файлы в проекте. Команда ng generate component запускает встроенный schematic, который создаёт файлы компонента и регистрирует его, где нужно. Тот же механизм открыт наружу: библиотеки поставляют свои schematics, и ng add подключает библиотеку, выполняя её schematic - создаёт конфигурацию, правит файлы, ставит зависимости.
Ключевая идея schematic - идемпотентная и безопасная трансформация дерева файлов. Schematic не пишет в файловую систему напрямую: он формирует набор изменений (Tree) и применяет его атомарно, что позволяет CLI показать предпросмотр и откатить при ошибке. Поэтому ng generate и ng add надёжны: они не оставляют проект в полусломанном состоянии.
| Команда | Что делает schematic |
|---|---|
| ng generate component | Создаёт файлы компонента по шаблону |
| ng generate service | Создаёт инжектируемый сервис |
| ng add <lib> | Ставит библиотеку и настраивает проект под неё |
| ng generate <lib>:<name> | Запускает кастомный schematic библиотеки |
Schematics - это та же технология, что и миграции: и генерация нового кода, и переписывание существующего описываются как трансформация дерева файлов. Разница лишь в назначении - создать или обновить. Поэтому ng update в следующем разделе устроен на том же фундаменте.
Что такое schematic в архитектуре Angular CLI?
ng update, миграции и tsgo на горизонте
Обновление мажорной версии фреймворка обычно означает ручную правку кода под изменившиеся API. Angular снимает эту боль через ng update: команда не просто меняет версии в package.json, а запускает миграции - те же schematics, но переписывающие существующий код под новые API. Так Angular годами проводит обновления (переход на standalone, на новый control flow в шаблонах, на signal-inputs) автоматически, а не оставляет это разработчику.
Миграция - это schematic, который анализирует исходники и аккуратно их переписывает: например, заменяет конструкции NgModule на standalone или *ngIf на блок @if. Поскольку всё идёт через безопасную трансформацию дерева файлов, изменения предсказуемы и обозримы в diff. Это превращает мажорные апгрейды из многодневного ручного труда в по большей части автоматическую операцию.
Линия ускорения сборки на этом не останавливается. На горизонте - tsgo, порт компилятора TypeScript на Go от команды TypeScript, обещающий ускорение проверки типов и компиляции примерно в 5-10 раз. Поскольку TypeScript-компиляция - заметная часть времени сборки Angular, tsgo продолжает ту же траекторию, что начал переход с Webpack на esbuild: убрать узкие места, написав горячие пути на компилируемом языке.
Сквозная тема всего урока - вынос медленных частей пайплайна на быстрые движки: бандлинг ушёл на esbuild (Go), проверка типов идёт к tsgo (Go), dev-сервер ускорен Vite. CLI с его билдерами и схематиками - тот слой развязки, который позволяет подменять эти движки, не ломая команды и не переписывая проект.
Чем ng update отличается от простой смены номера версии Angular в package.json и переустановки пакетов?
Связь с другими темами
Урок открывает модуль про внутреннее устройство. Связи:
- Тестирование — Vitest использует ту же esbuild-трансформацию, что и application builder
- Будущее Angular — tsgo (компилятор TypeScript на Go) продолжает линию ускорения сборки в финале
- Оптимизация изображений — Application builder обрабатывает и хеширует ассеты, включая картинки
Итог
- Angular CLI - это оркестратор, который запускает билдеры и schematics, описанные в angular.json
- Application builder (с Angular 17 по умолчанию) собирает прод на esbuild и обслуживает dev-сервер на Vite
- esbuild на Go бандлит на порядок быстрее Webpack, Vite отдаёт модули dev-серверу по запросу для мгновенного старта
- Билдер - это исполнитель команды (build, serve, test); их можно подменять и писать свои, как делают Nx и библиотеки
- Schematics - генераторы кода по шаблонам: ng generate создаёт файлы, а ng add интегрирует библиотеки
- ng update запускает миграции-схематики, которые автоматически переписывают код под новые API при обновлении версии
Связанные уроки
- ng-02-setup-cli — Урок углубляет понимание CLI, с которого началась настройка проекта
- ng-40-testing — Vitest переиспользует ту же esbuild-трансформацию, что и application builder
- ng-44-internals-future — tsgo и сборочные internals продолжаются в финальном уроке о будущем Angular