Angular v22: Разработка современных веб-приложений

Курс посвящен изучению актуальных возможностей фреймворка Angular v22, включая работу с Signals и Standalone Components. Студенты освоят создание производительных SPA, настройку SSR и применение лучших практик архитектуры.

1. Введение в экосистему Angular v22 и архитектура на основе Standalone Components

Введение в экосистему Angular v22 и архитектура на основе Standalone Components

Добро пожаловать в курс Angular v22: Разработка современных веб-приложений. Мы начинаем погружение в один из самых мощных и зрелых фреймворков для создания веб-интерфейсов. Если вы слышали об Angular раньше, возможно, вы помните его как сложную систему с множеством модулей и крутой кривой обучения. Angular v22 — это совершенно другая история. Это кульминация так называемого «Ренессанса Angular», который сделал фреймворк легче, быстрее и понятнее для разработчиков.

В этой первой статье мы разберем, из чего состоит современная экосистема Angular, почему мы отказались от NgModule в пользу Standalone Components и как теперь строится архитектура приложений.

Экосистема Angular: Больше, чем просто фреймворк

Часто Angular называют «платформой», а не просто библиотекой или фреймворком. Это связано с тем, что Angular предоставляет решение «все в одном» (batteries-included). Вам не нужно искать сторонние библиотеки для маршрутизации, работы с формами или HTTP-запросами — всё это уже есть в экосистеме и гарантированно работает вместе.

!Визуализация ключевых компонентов экосистемы Angular, обеспечивающих полный цикл разработки.

Ключевые компоненты платформы

  • Angular CLI (Command Line Interface)
  • Это ваш главный помощник. С помощью CLI вы создаете проект, генерируете новые компоненты, запускаете локальный сервер разработки и собираете приложение для продакшена. В v22 сборка происходит мгновенно благодаря использованию современных бандлеров (на базе esbuild).

  • Компонентная модель
  • Всё, что вы видите на экране в приложении Angular — это компоненты. Это кирпичики, из которых строится интерфейс.

  • Сигналы (Signals)
  • В Angular v22 сигналы стали стандартом де-факто для управления состоянием и реактивностью. Они позволяют приложению точно знать, где и что изменилось, обновляя только нужные части DOM, не перерисовывая всё дерево компонентов.

  • Server-Side Rendering (SSR) и Hydration
  • Современный веб требует высокой производительности. Angular v22 «из коробки» поддерживает серверный рендеринг и гидратацию, что делает приложения быстрыми для загрузки и дружелюбными для поисковых систем (SEO).

    Революция Standalone Components

    Долгое время (с версии 2 до 13) архитектура Angular строилась вокруг концепции NgModule. Это были контейнеры, в которых мы регистрировали компоненты. Это создавало лишний слой абстракции и усложняло понимание того, какие зависимости нужны конкретному компоненту.

    Начиная с Angular v14 и окончательно закрепившись как стандарт в v22, мы перешли на Standalone Components (автономные компоненты). Теперь компонент сам отвечает за свои зависимости.

    В чем суть Standalone Components?

    Автономный компонент — это компонент, который не нужно объявлять в модуле. У него есть специальный флаг (в v22 он часто подразумевается по умолчанию или устанавливается явно), и он имеет свой собственный массив imports.

    Рассмотрим пример простого компонента в Angular v22:

    Обратите внимание на ключевые особенности:

    * standalone: true: Эта строка сообщает Angular, что компонент является автономным. * imports: [...]: Мы прямо здесь указываем, что этому компоненту нужны CommonModule (для базовых директив) и другой компонент UserProfileComponent. Раньше это делалось в отдельном файле модуля, что заставляло разработчика постоянно переключаться между файлами.

    Преимущества подхода Standalone

  • Меньше кода (Less Boilerplate): Исчезли файлы *.module.ts, которые часто дублировали структуру папок.
  • Проще обучение: Новичкам легче понять связь «компонент использует X», чем концепцию глобальных модулей.
  • Лучшая производительность (Tree-shaking): Инструментам сборки проще понять, какие части кода действительно используются, а какие можно удалить из итогового бандла.
  • > Tree-shaking (встряхивание дерева) — это термин, описывающий процесс удаления «мертвого» (неиспользуемого) кода из финальной сборки приложения. Представьте, что вы трясете дерево: сухие листья (ненужный код) падают, а остаются только живые ветки.

    Архитектура приложения без модулей

    Как же теперь выглядит структура приложения, если у нас нет модулей? Архитектура Angular v22 строится на основе дерева компонентов и маршрутизации.

    Запуск приложения (Bootstrapping)

    Раньше точкой входа был корневой модуль (AppModule). Теперь мы загружаем напрямую корневой компонент. В файле main.ts это выглядит так:

    Функция bootstrapApplication принимает компонент, с которого начнется отрисовка, и объект конфигурации, где настраиваются глобальные провайдеры (например, маршрутизация или HTTP-клиент).

    Структура папок и ментальная модель

    Вместо группировки по техническому признаку (папка components, папка services), в современном Angular рекомендуется группировка по фичам (features) — функциональным возможностям.

    Пример структуры:

    * app/ * features/ * auth/ (Вход, регистрация) * login.component.ts * auth.service.ts * products/ (Список товаров) * product-list.component.ts * product-card.component.ts * shared/ (Переиспользуемые элементы: кнопки, инпуты) * ui/ * button.component.ts * app.component.ts * main.ts

    Такой подход делает архитектуру масштабируемой. Если вы хотите удалить функционал «Товары», вы просто удаляете папку products, и благодаря Standalone-компонентам у вас не останется «висячих» ссылок в глобальных модулях.

    Умные и Глупые компоненты (Smart vs Dumb)

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

  • Smart Components (Умные компоненты / Контейнеры):
  • * Обычно являются страницами (маршрутами). * Знают, откуда брать данные (обращаются к сервисам). * Управляют состоянием страницы. * Передают данные вниз в «глупые» компоненты.

  • Dumb Components (Глупые компоненты / Презентационные):
  • * Занимаются только отображением интерфейса. * Получают данные через входные параметры (@Input). * Сообщают о действиях пользователя через события (@Output). * Ничего не знают о сервисах или бизнес-логике. * Легко переиспользуются.

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

    Введение в Zoneless (Эра без Zone.js)

    Одной из важнейших особенностей Angular v22 является возможность работы без библиотеки Zone.js. Исторически Angular использовал Zone.js для перехвата асинхронных событий (клики, таймеры, HTTP-ответы), чтобы знать, когда запускать проверку изменений.

    Однако Zone.js имеет свои недостатки: она увеличивает размер бандла и иногда вызывает лишние проверки изменений, что снижает производительность. В v22, благодаря внедрению Signals, Angular точно знает, что изменилось, и ему больше не нужна «магия» зон для отслеживания событий.

    Это называется Zoneless Architecture. Она делает приложения: * Быстрее: Меньше накладных расходов на отслеживание событий. * Легче: Минус ~10-15кб из размера бандла. * Прозрачнее: Стек вызовов при отладке становится чище и понятнее.

    Заключение

    Angular v22 — это современная, производительная платформа, которая избавилась от исторического наследия в виде сложных модулей. Переход на Standalone Components упростил структуру приложений, а внедрение Signals и Zoneless-режима открыло двери для создания высокопроизводительных интерфейсов.

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

    Полезные ссылки

    * Официальная документация Angular * Руководство по Standalone Components

    2. Реактивность нового поколения: глубокое погружение в Signals и интеграция с RxJS

    Реактивность нового поколения: глубокое погружение в Signals и интеграция с RxJS

    В предыдущей статье мы рассмотрели архитектурный сдвиг Angular v22 в сторону Standalone Components, избавившись от громоздких модулей. Теперь пришло время заглянуть «под капот» и разобраться с тем, как наше приложение реагирует на изменения данных.

    Долгое время Angular полагался на библиотеку Zone.js и механизм «грязной проверки» (dirty checking). Это работало надежно, но не всегда эффективно. С приходом Angular v22 стандартом де-факто стала новая модель реактивности — Signals (Сигналы). Это не просто новая фича, это фундаментальное изменение в том, как фреймворк понимает поток данных.

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

    Что такое Signals и зачем они нужны?

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

    Представьте себе ячейки в электронной таблице Excel. Если в ячейке C1 записана формула =A1 + B1, то при изменении A1 значение C1 обновится автоматически. C1 «знает», что зависит от A1. В Angular до сигналов система не знала, какой именно компонент зависит от переменной. При любом событии (клик, таймер) Angular проверял всё дерево компонентов сверху вниз. Сигналы меняют правила игры, вводя точечную (granular) реактивность.

    !Граф зависимостей сигналов, показывающий точечное распространение изменений.

    Три примитива реактивности

    В Angular v22 работа с сигналами строится на трех китах:

  • Writable Signal (Записываемый сигнал)
  • Computed Signal (Вычисляемый сигнал)
  • Effect (Эффект)
  • #### 1. Writable Signal

    Это отправная точка. Сигнал, значение которого мы можем менять напрямую.

    Важно запомнить: чтение сигнала всегда происходит через вызов функции count(). Это позволяет Angular зарегистрировать зависимость в том месте, где сигнал был прочитан.

    #### 2. Computed Signal

    Вычисляемые сигналы — это значения, которые зависят от других сигналов. Они ленивы (вычисляются только при чтении) и мемоизированы (кэшируют результат, пока зависимости не изменятся).

    Если вы измените price, но никто не прочитает total, вычисления не произойдет. Это экономит ресурсы процессора.

    #### 3. Effect

    Эффект — это операция, которая выполняется каждый раз, когда меняется один из сигналов, прочитанных внутри неё. Эффекты редко нужны для бизнес-логики (для этого есть computed), но они незаменимы для побочных действий: логирования, ручной работы с DOM или синхронизации с внешними API.

    Практический пример: Архитектура на основе Сигналов

    Давайте соберем всё вместе. Рассмотрим типичный сервис в Angular v22, который управляет списком задач.

    В этом примере: * Мы скрыли возможность записи (todosState) внутри сервиса. * Компоненты получают данные через computed сигналы, которые обновляются только при необходимости. * Логика изменения данных инкапсулирована в методах.

    Заключение

    Сигналы в Angular v22 — это не просто синтаксический сахар, это эволюция производительности и удобства разработки (Developer Experience). Они позволяют писать код, который легче читать, проще отлаживать и который работает быстрее.

    Ключевые выводы:

  • Используйте signal() для хранения состояния.
  • Используйте computed() для любых данных, производных от состояния.
  • Используйте toSignal для потребления данных из RxJS (HTTP, сокеты).
  • Оставьте RxJS для обработки сложных событийных потоков.
  • В следующей статье мы рассмотрим, как новая система реактивности интегрируется с Router и как создавать динамические переходы в приложении без лишних проверок изменений.

    Полезные ссылки

    * Официальная документация Angular Signals * Пакет RxJS Interop

    3. Продвинутая работа с маршрутизацией и типизированными формами

    Продвинутая работа с маршрутизацией и типизированными формами

    Мы продолжаем наш курс Angular v22: Разработка современных веб-приложений. В прошлых статьях мы заложили фундамент: отказались от модулей в пользу Standalone Components и освоили реактивность нового поколения с помощью Signals. Теперь пришло время соединить эти компоненты в единое целое и научиться безопасно работать с данными пользователя.

    Любое серьезное веб-приложение держится на двух столпах: навигация (как пользователь перемещается по приложению) и ввод данных (как пользователь взаимодействует с системой). В Angular v22 эти механизмы стали не только мощнее, но и значительно удобнее для разработчика.

    В этой статье мы разберем:

  • Как маршрутизатор (Router) научился передавать данные прямо во входные параметры компонентов.
  • Как создавать плавные анимации переходов с помощью View Transitions API.
  • Почему типизированные формы (Typed Forms) — это лучшее, что случилось с формами в Angular, и как забыть о типе any.
  • Маршрутизатор нового поколения

    Маршрутизация в Angular всегда была мощной, но иногда требовала написания шаблонного кода (boilerplate). В версии v22 мы используем подходы, которые делают код чище и декларативнее.

    Component Input Binding (Привязка данных к инпутам)

    Вспомните, как мы раньше получали параметры из URL (например, id товара)? Нам приходилось внедрять сервис ActivatedRoute, подписываться на params или делать снимки (snapshot).

    В Angular v22 это делается элегантно через механизм Component Input Binding. Маршрутизатор теперь умеет сопоставлять параметры URL, query-параметры и данные резолверов напрямую с входными свойствами (@Input) компонента.

    Чтобы это заработало, в конфигурации приложения (app.config.ts) должна быть включена функция withComponentInputBinding().

    Теперь компонент выглядит так:

    Это превращает ваши компоненты в чистые функции, зависящие только от входных данных, что упрощает их тестирование и переиспользование.

    View Transitions API: Магия плавных переходов

    Современные пользователи привыкли к плавности мобильных приложений. Резкая смена страниц в вебе выглядит устаревшей. Angular v22 имеет встроенную поддержку View Transitions API — стандарта браузера для анимации изменений DOM.

    !Визуализация работы View Transitions: элемент плавно трансформируется при переходе между маршрутами.

    Вам не нужно писать сложные анимации на CSS/JS вручную. Достаточно включить withViewTransitions() в провайдере маршрутизации. Angular автоматически создаст «снимки» старого и нового состояния страницы и плавно переключит их.

    Если вы хотите, чтобы конкретная картинка товара в списке плавно увеличивалась и становилась картинкой на странице товара, вам нужно лишь задать им одинаковое имя перехода в CSS:

    Функциональные Guards и Resolvers

    В эпоху Standalone и функционального программирования, классовые гарды (CanActivate, CanDeactivate) ушли в прошлое. Теперь мы используем простые функции.

    Пример защиты маршрута (Guard), который проверяет, авторизован ли пользователь:

    Это делает код более компактным и легким для композиции (объединения нескольких проверок).

    Типизированные формы (Strictly Typed Reactive Forms)

    Долгое время Reactive Forms в Angular имели один существенный недостаток: они не были строго типизированы. Метод valueChanges возвращал any, а доступ к контролам через get('name') мог вернуть что угодно или null. Это приводило к ошибкам в рантайме, которые TypeScript не мог отловить на этапе сборки.

    В Angular v22 Typed Forms — это стандарт. Теперь TypeScript знает структуру вашей формы до мельчайших деталей.

    Объявление типизированной формы

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

    Проблема Nullable и решение nonNullable

    По умолчанию в Angular контролы могут быть null. Это происходит, когда вы вызываете метод .reset() без аргументов — форма сбрасывается в null.

    Если вы уверены, что поле всегда должно быть строкой (например, пустой строкой '', но не null), используйте опцию nonNullable: true или специальный хелпер NonNullableFormBuilder.

    FormArray и динамические списки

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

    Интеграция: Формы, Сигналы и Маршрутизация

    Высший пилотаж в Angular v22 — это умение связывать эти концепции. Давайте рассмотрим частый сценарий: форма фильтрации списка, состояние которой синхронизируется с URL.

    Почему это важно? Если пользователь отфильтровал список и скопировал ссылку другу, друг должен увидеть тот же отфильтрованный список.

    Рецепт синхронизации

  • Форма управляет вводом пользователя.
  • Сигналы реагируют на изменения формы.
  • Эффект обновляет URL.
  • Input Binding восстанавливает состояние формы при загрузке.
  • В этом примере мы видим идеальную синергию: * Reactive Forms обрабатывают ввод и валидацию. * RxJS (debounceTime) предотвращает спам обновлений. * Signals (toSignal, effect) управляют побочным эффектом (обновлением URL). * Router хранит состояние приложения (Source of Truth).

    Заключение

    Angular v22 предоставляет инструменты, которые делают сложные вещи простыми.

    * Component Input Binding убрал лишний код при чтении параметров маршрута. * View Transitions добавили приложению «премиальности» с помощью анимаций. * Typed Forms обеспечили надежность кода, защищая нас от глупых ошибок с типами данных.

    Теперь ваше приложение не только имеет красивую архитектуру (Standalone) и высокую производительность (Signals), но и обеспечивает отличный пользовательский опыт (UX) благодаря продвинутой маршрутизации и надежным формам.

    В следующей статье мы углубимся в работу с сервером: рассмотрим новый HttpClient, перехватчики (Interceptors) и особенности Server-Side Rendering (SSR).

    Полезные ссылки

    * Документация Angular Router * Руководство по Typed Forms

    4. Оптимизация производительности: Deferrable Views, SSR и гидратация

    Оптимизация производительности: Deferrable Views, SSR и гидратация

    Мы продолжаем наш курс Angular v22: Разработка современных веб-приложений. В предыдущих модулях мы создали прочный архитектурный фундамент с помощью Standalone Components, настроили реактивный поток данных через Signals и RxJS, а также освоили типизированные формы и маршрутизацию. Теперь наше приложение работает корректно и надежно.

    Но работает ли оно быстро?

    В современном вебе скорость — это не просто приятный бонус, это критический фактор успеха. Пользователи не ждут. Если ваше приложение загружается дольше 3 секунд, вы теряете аудиторию. В этой статье мы разберем инструменты Angular v22, которые позволяют достичь мгновенной загрузки и отличной производительности: Deferrable Views (откладываемые представления), Server-Side Rendering (SSR) и Hydration (гидратация).

    Deferrable Views: Загрузка только того, что нужно

    Традиционно Angular-приложения страдали от большого размера начального бандла (bundle size). Даже если пользователь заходил на главную страницу, браузер часто загружал код для компонентов, которые находятся глубоко внизу страницы или вообще скрыты (например, тяжелые графики или модальные окна).

    Раньше мы решали это через ленивую загрузку маршрутов (Lazy Loading Routes). Но что делать, если тяжелый компонент является частью текущей страницы?

    В Angular v22 стандартом стал механизм Deferrable Views, использующий новый синтаксис @defer. Это позволяет отложить загрузку части шаблона до тех пор, пока она действительно не понадобится.

    Синтаксис и блоки

    Конструкция @defer — это декларативный способ сказать компилятору: «Не загружай этот кусок кода сразу. Подожди определенного условия».

    Структура выглядит так:

    Разберем ключевые блоки:

  • @defer: Основной блок. Содержимое внутри него выносится в отдельный JavaScript-файл (чанк) и загружается асинхронно.
  • @placeholder: То, что пользователь видит до начала загрузки. Это критически важно для предотвращения сдвигов макета (Cumulative Layout Shift - CLS).
  • @loading: То, что пользователь видит во время загрузки кода по сети.
  • @error: Отображается, если сеть отвалилась или скрипт не загрузился.
  • !Жизненный цикл отложенного представления: от плейсхолдера до готового компонента.

    Триггеры: Когда загружать?

    Самое мощное в @defer — это триггеры. Вам не нужно писать код для IntersectionObserver вручную. Angular делает это за вас.

    * on viewport: Загрузить, когда плейсхолдер попал в видимую область экрана (скролл). * on idle: (По умолчанию) Загрузить, когда браузер простаивает и не занят другими задачами. * on interaction: Загрузить, когда пользователь кликнул или нажал клавишу на плейсхолдере. * on hover: Загрузить при наведении мыши. * on timer(5s): Загрузить через 5 секунд. * when condition: Загрузить, когда логическое выражение (например, сигнал) станет true.

    Пример комбинирования:

    Использование @defer позволяет разбить монолитный бандл на множество мелких частей, которые подгружаются по мере необходимости, значительно ускоряя LCP (Largest Contentful Paint).

    Server-Side Rendering (SSR): Быстрый первый кадр

    Даже с ленивой загрузкой, классическое SPA (Single Page Application) имеет недостаток: при первом запросе сервер отдает пустой index.html. Браузер должен скачать JS, распарсить его, выполнить и только потом отрисовать DOM. Пользователь видит белый экран.

    Server-Side Rendering (SSR) решает эту проблему. Приложение запускается на сервере (Node.js), генерирует готовый HTML и отправляет его браузеру. Пользователь сразу видит контент.

    В Angular v22 SSR встроен в платформу и не требует отдельного пакета @nguniversal. Чтобы добавить его в проект, достаточно выполнить:

    Преимущества SSR

  • SEO (Search Engine Optimization): Поисковые роботы гарантированно видят контент, даже если они плохо исполняют JavaScript.
  • FCP (First Contentful Paint): Пользователь видит интерфейс практически мгновенно, даже на медленном 3G-интернете.
  • Предварительный просмотр в соцсетях: Ссылки на ваше приложение в Telegram или Twitter будут иметь красивые карточки с заголовком и картинкой.
  • Гидратация (Hydration): Оживление страницы

    До версии 16 (и окончательно отполировано в v22) Angular использовал так называемую «деструктивную гидратацию». Это работало так:

  • Сервер присылал HTML.
  • Пользователь видел страницу.
  • Загружался Angular.
  • Angular удалял весь HTML, присланный сервером.
  • Angular рисовал заново тот же самый HTML с нуля.
  • Это вызывало мерцание экрана и было неэффективно.

    В Angular v22 используется Non-destructive Hydration (Недеструктивная гидратация). Angular «просыпается» и вместо перерисовки просто находит существующие DOM-элементы и привязывает к ним слушатели событий.

    !Эволюция гидратации: от полной перерисовки к подключению событий.

    Как включить гидратацию?

    В новых проектах v22 она включена по умолчанию. В файле app.config.ts это выглядит так:

    Event Replay: Ни один клик не потерян

    Существует проблема «Зловещей долины» (Uncanny Valley) в SSR: пользователь видит кнопку (HTML загружен), нажимает на неё, но ничего не происходит, потому что JavaScript еще не загрузился и не «оживил» кнопку.

    Angular v22 решает это с помощью Event Replay (Воспроизведение событий).

    Как это работает:

  • В HTML, который отдает сервер, встроен маленький скрипт (inline script).
  • Этот скрипт слушает все клики на странице до загрузки Angular.
  • Если пользователь кликнул кнопку «Купить», скрипт запоминает это событие.
  • Когда Angular загружается и проходит гидратацию, он «проигрывает» записанные события.
  • Товар добавляется в корзину.
  • Для разработчика это происходит прозрачно. Вам нужно лишь добавить функцию withEventReplay() в конфигурацию гидратации:

    Практическая стратегия оптимизации

    Чтобы ваше приложение на Angular v22 летало, следуйте этому чек-листу:

  • Используйте Standalone Components: Они лучше поддаются tree-shaking (удалению неиспользуемого кода).
  • Применяйте @defer: Оберните все компоненты, которые не нужны на первом экране (комментарии, футер, сложные виджеты).
  • Включите SSR и Гидратацию: Это база для современного веба.
  • Оптимизируйте изображения: Используйте директиву NgOptimizedImage (мы рассмотрим её в будущих материалах), которая работает в связке с SSR для предотвращения скачков контента.
  • Заключение

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

    * Deferrable Views позволяют дробить код на мелкие части декларативно. * SSR обеспечивает мгновенное отображение контента. * Hydration и Event Replay делают переход от статического HTML к интерактивному приложению бесшовным и незаметным для пользователя.

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

    Полезные ссылки

    * Руководство по Deferrable Views * Документация по SSR и Hydration * Информация о Event Replay

    5. Тестирование компонентов, сборка проекта и развертывание в продакшн

    Тестирование компонентов, сборка проекта и развертывание в продакшн

    Поздравляем! Вы прошли долгий путь от изучения архитектуры Standalone Components и реактивности Signals до настройки SSR и гидратации. Ваше приложение на Angular v22 написано, оно быстрое и современное. Но готово ли оно к встрече с реальными пользователями?

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

    Стратегия тестирования в Angular v22

    В экосистеме Angular тестирование всегда было гражданином первого класса. Однако подходы меняются. Если раньше мы полагались на Karma и Jasmine, то в v22 стандарты сместились в сторону более быстрых и современных инструментов.

    !Пирамида тестирования: от множества быстрых модульных тестов к небольшому количеству сквозных сценариев

    Модульное тестирование (Unit Testing)

    Модульные тесты проверяют изолированные части кода: отдельные компоненты, сервисы или пайпы. В Angular v22 для запуска тестов все чаще используется Web Test Runner или Jest, обеспечивающие мгновенную обратную связь.

    #### Тестирование компонентов с сигналами

    Поскольку мы используем Signals, подход к тестированию состояния немного изменился. Нам больше не нужно ждать whenStable() для проверки синхронных обновлений сигналов, но мы все еще должны управлять обновлением шаблона.

    Рассмотрим тест для компонента счетчика:

    Обратите внимание: fixture.detectChanges() критически важен. Сигнал обновляется мгновенно, но Angular обновляет DOM только при запуске обнаружения изменений.

    Component Test Harnesses

    Одна из лучших практик, перекочевавшая из Angular Material в ядро — это Test Harnesses. Это способ взаимодействия с компонентом через API, а не через CSS-селекторы. Это делает тесты устойчивыми к изменениям верстки.

    Если вы измените class="btn-primary" на class="btn-danger", тест с querySelector('.btn-primary') упадет. Тест с Harness продолжит работать.

    E2E Тестирование (End-to-End)

    Для проверки сценариев «от начала до конца» (например, пользователь заходит на сайт, логинится и покупает товар) Angular v22 официально рекомендует использовать Playwright или Cypress. Protractor официально мертв и удален.

    Playwright позволяет запускать тесты в реальных движках браузеров (Chromium, Firefox, WebKit) и работает невероятно быстро.

    Сборка проекта: Скорость света с esbuild

    Долгое время Angular использовал Webpack для сборки. Это надежный, но медленный инструмент. В Angular v22 по умолчанию используется esbuild.

    Что такое esbuild?

    Это сборщик, написанный на языке Go. Он компилирует код в 10-100 раз быстрее, чем инструменты на JavaScript. То, что раньше собиралось минуту, теперь собирается за секунды.

    Чтобы собрать проект для продакшена, мы используем команду:

    Эта команда выполняет несколько критических оптимизаций:

  • Ahead-of-Time (AOT) Compilation: Шаблоны компилируются в JavaScript-код во время сборки, а не в браузере.
  • Tree-Shaking: Удаление неиспользуемого кода (мы обсуждали это в контексте Standalone Components).
  • Minification: Удаление пробелов, комментариев и сокращение имен переменных.
  • Hashing: Добавление уникальных хешей к именам файлов (например, main.7a2b9c.js) для управления кешированием браузера.
  • Бюджеты производительности (Budgets)

    Как гарантировать, что мы случайно не импортировали огромную библиотеку и не раздули бандл? Angular CLI позволяет задать бюджеты в файле angular.json.

    Если размер начального бандла превысит 1 МБ, сборка завершится с ошибкой, и CI/CD пайплайн остановит деплой. Это жесткий, но эффективный контроль качества.

    Развертывание (Deployment)

    Процесс развертывания зависит от того, используете ли вы Server-Side Rendering (SSR) или только Client-Side Rendering (CSR).

    !Путь кода от коммита до продакшена: автоматическая сборка и доставка

    Сценарий 1: Статический хостинг (CSR)

    Если вы не используете SSR, ваше приложение — это просто набор статических файлов (index.html, .js, .css) в папке dist/my-app/browser.

    Вы можете загрузить эти файлы на любой веб-сервер: * Nginx / Apache * Firebase Hosting * Netlify / Vercel * AWS S3 + CloudFront

    Важный нюанс для SPA (Single Page Application): сервер должен быть настроен так, чтобы на любой запрос (например, /products/123) он отдавал index.html. Иначе при обновлении страницы пользователь получит ошибку 404.

    Пример конфигурации Nginx:

    Сценарий 2: SSR и Гидратация

    Если вы используете SSR (что рекомендуется в v22), результат сборки будет содержать две папки:

  • dist/my-app/browser — файлы для браузера.
  • dist/my-app/server — серверный код.
  • Для запуска вам понадобится среда Node.js. Angular генерирует простой серверный скрипт server.mjs.

    Команда запуска:

    В реальном продакшене этот процесс обычно заворачивают в Docker контейнер и запускают в кластере (например, Kubernetes) или на платформе вроде Google Cloud Run.

    Управление переменными окружения

    Никогда не храните секретные ключи (API keys) в коде. Angular предоставляет механизм файлов окружения (environment.ts и environment.prod.ts), но в v22 лучшей практикой считается использование реальных переменных окружения процесса сборки или сервера.

    Для SSR приложений вы можете читать переменные прямо из process.env на сервере и передавать их в приложение через TransferState, чтобы они не светились в браузере, если они нужны только для серверных запросов.

    Заключение курса

    Мы завершаем наш курс Angular v22: Разработка современных веб-приложений. Мы прошли путь от базовых концепций до профессиональных техник оптимизации и деплоя.

    Что мы изучили:

  • Standalone Components: Упрощение архитектуры и отказ от модулей.
  • Signals: Точечная реактивность и высокая производительность.
  • Router & Forms: Типизированные данные и плавные переходы.
  • SSR & Deferrable Views: Мгновенная загрузка и отличный UX.
  • Testing & Build: Инструменты для создания надежного продукта.
  • Angular v22 — это мощная платформа. Она дает вам все инструменты «из коробки», чтобы вы могли сосредоточиться на создании ценности для ваших пользователей, а не на настройке конфигураций. Продолжайте экспериментировать, следите за обновлениями и создавайте великолепные приложения!

    Полезные ссылки

    * Официальное руководство по тестированию * Документация по развертыванию * Playwright для Angular