Компиляция Angular — обзор (с чего начать)
Прежде чем нырять в детали, надо разложить по полочкам какие вообще бывают компиляции в Angular. Слово «компиляция» тут перегружено — это сбивает с толку. Есть три независимых оси:
Ось 1. Когда компилируется шаблон: JIT vs AOT
| JIT (Just-in-Time) | AOT (Ahead-of-Time) | |
|---|---|---|
| Когда | в браузере, при старте | при сборке, на твоей машине/CI |
| Кто | @angular/compiler едет в бандл |
ngtsc (компилятор внутри сборки) |
| Скорость старта | медленнее (компилит на лету) | быстрее (готовый JS) |
| Размер бандла | больше (тащит компилятор) | меньше (компилятор не нужен в рантайме) |
| Где сейчас | только ng test/редкие случаи |
дефолт для v21 (ng build, ng serve) |
В v21 всё AOT. JIT остался как legacy. Поэтому весь наш разбор — про AOT.
Ось 2. Что на входе: твой код (app) vs чужая библиотека (lib)
Тут и живёт «partial Ivy», про который был вопрос. Две разные ситуации:
| Приложение (твой код) | Библиотека (npm-пакет) | |
|---|---|---|
| Чем собирается | ng build твоего app |
ng-packagr авторами либы |
| Режим компиляции | full (полный Ivy) | partial (частичный) |
| Что на выходе | ɵɵdefineComponent({...}) — финальные инструкции |
ɵɵngDeclareComponent({...}) — «декларация»: шаблон строкой + метаданные |
| Кто доводит до конца | — (уже готово) | Linker при сборке твоего app |
Зачем так? Если бы либа публиковалась в full-Ivy, её формат был бы жёстко
привязан к версии Angular (инструкции меняются от версии к версии — мы это видели:
ɵɵelementStart → ɵɵdomElementStart). Partial-формат стабилен между версиями: либа
говорит «вот мой шаблон и метаданные», а конкретные инструкции генерит linker той
версии Angular, которой собирают приложение. Это развязывает версии либы и app.
→ Полный разбор: 02-partial-ivy-and-linker
Ось 3. Кто превращает результат в загружаемый файл: bundler
Компилятор (ngtsc/linker) выдаёт JS-модули. Их ещё надо собрать в бандл,
минифицировать, дать dev-сервер. Этим занимается bundler — и он менялся:
- v14: webpack (медленный, но гибкий).
- v21: esbuild (Go, в десятки раз быстрее) + vite (dev-сервер с HMR).
→ Почему сменили и как устроено: 03-build-tooling
Как три оси складываются в одну сборку ng build
твой App.ts (@Component) npm-либа (@ngDeclareComponent)
│ ngtsc: FULL AOT │ уже partial (собрана ng-packagr)
▼ ▼
ɵɵdefineComponent({...}) LINKER: ngDeclare → ɵɵdefineComponent
│ │ (та же full-генерация, версия твоего app)
└──────────────┬───────────────┘
▼
bundler (esbuild/vite): bundle + minify + tree-shake
▼
dist/.../main.js → грузится в браузер
То есть и твой код, и библиотеки в итоге сходятся в одинаковые Ivy-инструкции — просто твой код проходит full-путь сразу, а либы доводит linker.
Куда дальше
- 01-full-pipeline — главная заметка: как
ngtscгонит твой шаблон через 7 стадий (HTML AST → render3 AST → IR → фазы → reify → emit →defineComponent). - 02-partial-ivy-and-linker — как собираются и «дотягиваются» библиотеки.
- 03-build-tooling — webpack vs esbuild/vite, почему так и как ngtsc встроен в сборку.