Pull to refresh

Встречаем Angular 17

Level of difficultyEasy
Reading time17 min
Views25K
Original author: Minko Gechev

Эта статья — перевод оригинальной статьи "Introducing Angular v17".

Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.

Вступление

В прошлом месяце исполнилось 13 лет с момента появления "красного щита" Angular. AngularJS стал отправной точкой для новой волны JavaScript-фреймворков, появившихся для поддержки растущей потребности в богатом веб-опыте. Сегодня с новым внешним видом и набором перспективных функций мы ведем всех в будущее с версией 17, устанавливая новые стандарты производительности и удобства для разработчиков.

В v17 мы рады представить:

  • Deferrable views выводят производительность и удобство работы разработчика на новый уровень

  • В публичных бенчмарках время выполнения со встроенным циклом контроля потока увеличивается на 90%.

  • Ускорение сборки до 87% для гибридного рендеринга и до 67% для рендеринга на стороне клиента

  • Новый свежий вид, отражающий перспективные возможности Angular

  • Совершенно новый интерактивный курс обучения

  • ...и десятки других возможностей и улучшений!

Дизайн, ориентированный на будущее

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

Сегодня любимый фреймворк, проверенный миллионами разработчиков, приобретает новый облик, отражающий его перспективность и производительность!

Документация, ориентированная на будущее

Вместе с новым брендом мы также разработали новый дом для документации по Angular - angular.dev. На новом сайте документации мы создали новую структуру, новые руководства, улучшили содержание и создали платформу для интерактивного обучения, которая позволит вам изучать Angular и Angular CLI в удобном для вас темпе, прямо в браузере.

Новый интерактивный учебный процесс основан на WebContainers и позволяет использовать возможности Angular CLI в любом современном веб-браузере!

Сегодня мы запускаем бета-версию angular.dev и планируем сделать его сайтом по умолчанию для Angular в версии 18. Подробнее о новом облике Angular и angular.dev вы можете узнать из статьи "Анонс angular.dev".

А теперь позвольте мне перейти к рассмотрению функций из v17, о которых нам не терпится рассказать вам!

Встроенный контроль потока

Чтобы улучшить работу разработчиков, мы выпустили новый синтаксис шаблонов блоков, который предоставляет мощные возможности с простыми, декларативными API. Под капотом компилятор Angular преобразует синтаксис в эффективные инструкции JavaScript, которые могут выполнять контроль потока, ленивую загрузку и многое другое.

Мы использовали новый синтаксис блоков для оптимизации встроенного контроля потока. Проведя исследования пользователей, мы обнаружили, что многие разработчики испытывают трудности с *ngIf, *ngSwitch и *ngFor. Работая с Angular с 2016 года и являясь частью команды Angular на протяжении последних 5 лет, я лично до сих пор вынужден искать синтаксис *ngFor и trackBy. Собрав отзывы сообщества, партнеров и проведя UX-исследования, мы разработали новый встроенный контроль потока для Angular!

Встроенный контроль поток позволяет:

  • Более эргономичный синтаксис, приближенный к JavaScript, а значит, более интуитивно понятный, требующий меньшего количества обращений к документации

  • Улучшенная проверка типов благодаря более оптимальному сужению типов

  • Это концепция, которая в первую очередь существует во время сборки, что позволяет сократить занимаемое место во время выполнения (сделать его "исчезающим"), что может уменьшить размер вашего пакета до 30 килобайт и дополнительно улучшить показатели Core Web Vital.

  • Он автоматически доступен в ваших шаблонах без дополнительного импорта

  • Значительные улучшения производительности, о которых мы расскажем чуть позже

Условные операторы

Рассмотрим сравнение с *ngIf:

<div *ngIf="loggedIn; else anonymousUser">
  The user is logged in
</div>
<ng-template #anonymousUser>
  The user is not logged in
</ng-template>

С помощью встроенного оператора if это условие будет иметь вид:

@if (loggedIn) {
  Пользователь вошел в систему
} @else {
  Пользователь не вошел в систему
}

Возможность напрямую предоставлять содержимое @else - это значительное упрощение по сравнению с пунктом else устаревшей альтернативы *ngIf. Текущий контроль потока также делает тривиальным наличие @else if, что исторически было невозможно.

Улучшение эргономики еще более заметно при использовании *ngSwitch:

<div [ngSwitch]="accessLevel">
  <admin-dashboard *ngSwitchCase="admin"/>
  <moderator-dashboard *ngSwitchCase="moderator"/>
  <user-dashboard *ngSwitchDefault/>
</div>

который со встроенным контролем потоком превращается в:

@switch (accessLevel) {
  @case ('admin') { <admin-dashboard/> }
  @case ('moderator') { <moderator-dashboard/> }
  @default { <user-dashboard/> }
}

Новый контроль потока позволяет значительно улучшить сужение типов в отдельных ветвях в @switch, что невозможно в *ngSwitch.

Встроенный цикл for

Одно из моих самых любимых обновлений - это встроенный цикл for, который, помимо улучшений в работе разработчиков, выводит скорость рендеринга Angular на новый уровень!

Его основной синтаксис таков:

@for (user of users; track user.id) {
  {{ user.name }}
} @empty {
  Empty list of users
}

Мы часто наблюдаем проблемы с производительностью в приложениях из-за отсутствия функции trackBy в *ngFor. Отличия @for заключаются в том, что функция trackBy является обязательной для обеспечения быстрой работы функции diffing. Кроме того, его гораздо проще использовать, поскольку это просто выражение, а не метод в классе компонента. Встроенный цикл @for также имеет возможность быстрого использования для коллекций с нулевыми элементами с помощью необязательного блока @empty.

Оператор @for использует новый diffing алгоритм и имеет более оптимальную реализацию по сравнению с *ngFor, что позволяет ему на 90% ускорить время выполнения в бенчмарках сообщества!

Попробуйте!

Встроенный контроль потока доступен в v17 в предварительной версии для разработчиков уже сегодня!

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

ng generate @angular/core:control-flow

Что дальше?

Вы уже можете использовать встроенный контроль поток с последней языковой версией сервиса, и мы тесно сотрудничали с компанией JetBrains, чтобы обеспечить лучшую поддержку в их продуктах. Мы также поддерживаем контакт с Sosuke Suzuki из Prettier, чтобы обеспечить правильное форматирование шаблонов Angular.

По сравнению с *ngIf, *ngFor и *ngSwitch все еще существуют некоторые различия в том, как встроенный контроль потока обрабатывает выделение содержимого, и мы будем работать над ними в течение следующих месяцев. Кроме того, мы уверены в его реализации и стабильности, так что вы можете попробовать его уже сегодня! Мы хотели бы оставить его в состоянии предварительного просмотра разработчиками до следующего крупного релиза, чтобы открыть дверь для потенциальных исправлений обратной несовместимости в случае, если мы найдем возможности для дальнейшего улучшения работы разработчиков.

Deferrable views

Теперь давайте поговорим о будущем ленивой загрузки! Используя новый синтаксис блоков, мы разработали новый мощный механизм, который можно использовать для ускорения работы приложений. В начале статьи я сказал, что deferrable views выводят производительность и удобство разработчиков на новый уровень, поскольку они обеспечивают декларативную и мощную отложенную загрузку с беспрецедентной эргономикой.

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

Новые откладываемые представления позволяют лениво загрузить список комментариев и все их транзитивные зависимости одной строкой декларативного кода:

@defer {
  <comment-list />
}

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

Ленивая загрузка компонента при попадании определенного DOM-элемента в область просмотра требует много более нетривиальной логики и использования API IntersectionObserver. Angular делает использование IntersectionObservers таким же простым, как добавление deferrable view триггера!

@defer (on viewport) {
  <comment-list />
} @placeholder {
  <!-- A placeholder content to show until the comments load -->
  <img src="comments-placeholder.png">
}

В приведенном примере Angular сначала отображает содержимое блока placeholder. Когда он становится видимым в области просмотра, начинается загрузка компонента <comment-list / >. По завершении загрузки Angular удаляет placeholder и отображает компонент.

Также имеются блоки для загрузки и состояния ошибки:

@defer (on viewport) {
  <comment-list/>
} @loading {
  Loading…
} @error {
  Loading failed :(
} @placeholder {
  <img src="comments-placeholder.png">
}

Вот и все! Под капотом находится множество сложностей, которыми Angular управляет за вас.

Deferrable views предлагают еще несколько триггеров:

  • on Idle - ленивая загрузка блока, когда браузер не выполняет никакой тяжелой работы

  • on immediate - начать ленивую автоматическую загрузку, не блокируя браузер

  • on timer(<time>) - задержка загрузки с помощью таймера

  • on viewport иon viewport(<ref>) - viewport также позволяет указать ссылку на якорный элемент. Когда элемент якоря становится видимым, Angular лениво загрузит компонент и отрендерит его

  • on interaction иon interaction(<ref>) - позволяет инициировать ленивую загрузку при взаимодействии пользователя с определенным элементом

  • on hover иon hover(<ref>) - запускает ленивую загрузку, когда пользователь наводит курсор на элемент

  • when <expr> - позволяет задать собственное условие через выражение, возвращающее обещание

Deferrable views также предоставляют возможность предварительной выборки зависимостей перед их отрисовкой. Добавить предварительную выборку так же просто, как добавить оператор prefetch в блок defer и поддерживать все те же триггеры.

@defer (on viewport; prefetch on idle) {
  <comment-list />
}

Deferrable views доступны в предварительной версии для разработчиков в v17 уже сегодня! Подробнее об этой функции можно узнать из этого руководства.

Что дальше?

Откладываемые представления уже готовы к использованию, и мы настоятельно рекомендуем вам попробовать их! Причина, по которой мы оставляем их в предварительной версии для разработчиков, заключается в том, что мы можем собрать больше отзывов и внести изменения в поверхность API до тех пор, пока не переведем их на семантическое версионирование, как и остальную часть фреймворка.

В настоящее время при рендеринге на стороне сервера отображается указанный placeholder. Как только фреймворк загрузит приложение и гидратирует его, deferrable views будут работать так, как мы описали выше.

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

Также будет много интересных возможностей взаимодействия с сигналами, так что следите за новостями!

Обновленный опыт гибридного рендеринга

Сегодня мы приближаем серверный рендеринг (SSR) и генерацию статических сайтов (SSG или prerendering) к разработчикам с помощью подсказки в ng new:

Это изменение мы хотели внести уже давно, но сначала мы хотели быть уверены в том, что разработчики Angular смогут использовать SSR.

Кроме того, вы можете включить SSR в новых проектах с помощью:

ng new my-app --ssr

Гидратация выведена из предварительной версии для разработчиков

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

Новый пакет @angular/ssr

Мы перенесли репозиторий Angular Universal в репозиторий Angular CLI и сделали рендеринг на стороне сервера еще более неотъемлемой частью нашего инструментария!

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

ng add @angular/ssr

Эта команда сгенерирует точку входа в сервер, добавит возможности сборки SSR и SSG, а также включит гидратацию по умолчанию. @angular/ssr предоставляет функциональность, эквивалентную @nguniversal/express-engine, который в настоящее время находится в статусе поддержки. Если вы используете express-engine, Angular CLI автоматически обновит ваш код до @angular/ssr.

Компания Virgin Media O2 отметила рост продаж на 112% после перехода на новейшее решение для гибридного рендеринга Angular Hybrid с устаревшей платформы. При использовании NgOptimizedImage в сочетании с Angular SSR с DOM Hydration среднее снижение кумулятивного сдвига макета составило 99,4%.

Развертывание вашего приложения с SSR

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

Firebase автоматически распознает и развертывает ваше Angular-приложение практически без конфигурации, благодаря ранней предварительной версии нового CLIENTS с поддержкой фреймворка.

firebase experiments:enable webframeworks
firebase init hosting
firebase deploy

CLI с учетом фреймворка распознает использование SSR, i18n, оптимизацию изображений и многое другое, позволяя обслуживать производительные веб-приложения на экономичной бессерверной инфраструктуре.

Для тех, кто имеет сложные моноресурсы Angular или просто предпочитает нативные инструменты, AngularFire позволяет развертывать приложения на Firebase с помощью ng deploy:

ng add @angular/fire
ng deploy

Чтобы обеспечить развертывание на edge воркерах, мы включили поддержку модулей ECMAScript в серверный рендеринг Angular, внедрили бэкенд fetch для HttpClient и работали с CloudFlare над оптимизацией процесса.

Новые хуки жизненного цикла

Для повышения производительности SSR и SSG Angular в долгосрочной перспективе мы хотели бы отказаться от эмуляции DOM и прямых манипуляций с DOM. В то же время на протяжении жизненного цикла большинства приложений им необходимо взаимодействовать с элементами для инстанцирования сторонних библиотек, измерения размера элементов и т.д.

Для этого мы разработали набор новых хуков жизненного цикла:

  • afterRender - регистрирует обратный вызов, который будет вызываться каждый раз, когда приложение завершает рендеринг-

  • afterNextRender  - регистрирует обратный вызов, который будет вызван в следующий раз, когда приложение завершит рендеринг

Эти крючки будут вызываться только браузером, что позволяет безопасно подключать пользовательскую DOM-логику непосредственно внутри компонентов. Например, если вы хотите создать библиотеку графиков, вы можете использовать afterNextRender:

@Component({
  selector: 'my-chart-cmp',
  template: `<div #chart>{{ ... }}</div>`,
})
export class MyChartCmp {
  @ViewChild('chart') chartRef: ElementRef;
  chart: MyChart|null;

  constructor() {
    afterNextRender(() => {
      this.chart = new MyChart(this.chartRef.nativeElement);
    }, {phase: AfterRenderPhase.Write});
  }
}

Каждый хук поддерживает значение phase (например, чтение, запись), которое Angular будет использовать для планирования обратных вызовов, чтобы уменьшить количество ошибок в компоновке и повысить производительность.

Vite и esbuild по умолчанию для новых проектов

Мы не смогли бы включить SSR в Angular с самого начала, если бы не фундаментальные изменения, внесенные нами в конвейер сборки Angular CLI!

В версии 16 мы представили разработчикам предварительную версию сборки esbuild plus Vite powered build. С тех пор многие разработчики экспериментировали с ним, а некоторые корпоративные партнеры сообщили об улучшении времени сборки некоторых приложений на 67%! Сегодня мы рады сообщить, что новый сборщик приложений вышел из предварительной версии и теперь включен по умолчанию для всех новых приложений!

Кроме того, мы обновили конвейер сборки при использовании гибридного рендеринга. С помощью SSR и SSG вы можете наблюдать до 87% прироста скорости в ng build и 80% ускорения цикла редактирования-обновления в for ng serve.

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

Отладка инъекции зависимостей в DevTools

В прошлом году мы показали предварительную версию возможностей отладки инъекций зависимостей в Angular DevTools. За последние несколько месяцев мы реализовали совершенно новые отладочные API, позволяющие подключаться к среде выполнения фреймворка и инспектировать дерево инжекторов.

На основе этих API мы создали пользовательский интерфейс, позволяющий просматривать дерево инжекторов:

  • Зависимости ваших компонентов в инспекторе компонентов

  • Дерево инжекторов и путь разрешения зависимостей

  • Провайдеры, объявленные в отдельных инжекторах

Быстрый предварительный просмотр функций представлен на анимации ниже. Подробнее об Angular DevTools можно узнать на сайте angular.io.

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

Standalone API с самого начала

Собрав за последние полтора года отзывы об standalone компонентах, директивах и пайпах и отшлифовав их в DevEx, мы уверены, что теперь они будут включены во все новые приложения с самого начала. Все команды ng generate теперь будут использовать standalone компоненты, директивы и пайпы.

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

Мы сохраним NgModules в обозримом будущем, но, видя преимущества новых standalone API, мы настоятельно рекомендуем постепенно переводить на них свои проекты. Мы также предлагаем схему, которая позволит автоматизировать большую часть этой работы:

ng generate @angular/core:standalone

Для получения дополнительной информации ознакомьтесь с нашим руководством по миграции.

Следующие шаги в области реактивности

Новая реактивная система Angular, основанная на сигналах, стала одним из самых значительных изменений, которые мы сделали во фреймворке. Чтобы обеспечить обратную совместимость и взаимодействие с системой обнаружения изменений на основе Zone.js, мы много работали над прототипами и проектированием дальнейших действий.

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

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

Дальнейшие шаги по тестированию

Мы продолжаем экспериментировать с Jest и убеждаемся, что создаем решение, которое будет достаточно производительным, гибким и интуитивно понятным, чтобы удовлетворить потребности разработчиков. Мы также начинаем экспериментировать с Web Test Runner и открыли PR для его первоначальной реализации. В ближайшем будущем мы, скорее всего, сосредоточимся на Web Test Runner, чтобы разблокировать проекты, желающие перейти с Karma.

Следующие шаги для Material 3

Совместно с командой Material Design компании Google мы активно работаем над рефакторингом внутренних компонентов Angular Material с целью внедрения маркеров дизайна - системы, предоставляющей значительно больше возможностей для настройки компонентов и обеспечивающей поддержку Material 3. Хотя мы еще не готовы к внедрению маркеров дизайна и поддержки M3 в v17, мы ожидаем, что эти функции появятся в ближайшее время в минорном выпуске v17.

В IV квартале 2022 года мы объявили о выпуске новых компонентов Angular Material на базе MDC и об отказе от старых компонентов, которые имеют эквивалентную функциональность, но отличаются структурой и стилями DOM. В v15 мы отказались от устаревших компонентов, которые будут удалены в v17. Несмотря на то, что они не будут входить в пакет Angular Material v17, вы можете обновить свои приложения до Angular v17 и использовать пакет Angular Material v16. Такая возможность будет действовать до версии 18, после чего Angular Material v16 перестанет быть совместимым с новыми версиями Angular. Мы также сотрудничаем с нашими партнерами из HeroDevs, которые собираются предложить платную постоянную поддержку в случае, если вы пока не можете выполнить миграцию.

Улучшение качества жизни

Вместе с этими перспективными функциями мы отправили на рынок ряд небольших улучшений для разработчиков!

Экспериментальная поддержка View Transitions

View Transitions API обеспечивает плавные переходы при изменении DOM. В маршрутизаторе Angular мы теперь обеспечиваем прямую поддержку этого API с помощью функции withViewTransitions. С ее помощью можно использовать встроенные возможности браузера для создания анимированных переходов между маршрутами.

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

bootstrapApplication(App, {
  providers: [
    provideRouter(routes, withViewTransitions()),
  ]
});

withViewTransitions принимает необязательный объект конфигурации со свойством onViewTransitionCreated, которое представляет собой обратный вызов, обеспечивающий дополнительный контроль:

  • Решите, хотите ли вы пропустить определенные анимации

  • Добавьте в документ классы для настройки анимации и удалите эти классы по завершении анимации

  • и так далее

Автоматическое предварительное подключение в директиве image

Директива Angular image теперь автоматически генерирует ссылки предварительного соединения для доменов, которые вы указали в качестве аргумента загрузчику изображений. Если директива image не может автоматически определить источник и не обнаруживает предварительную ссылку для LCP-изображения, то во время разработки она выдаст предупреждение.

Подробнее об этой возможности можно узнать из руководства по работе с директивой image.

Отложенная загрузка модуля анимации

Эта возможность позволяет сэкономить 60 КБ от начального пакета (16 КБ в gzipped). Участник сообщества Matthieu Riegler предложил и реализовал функцию, позволяющую лениво загружать модуль анимации через асинхронную функцию провайдера:

import { provideAnimationsAsync } from '@angular/platform-browser/animations-async';

bootstrapApplication(RootCmp, {
  providers: [provideAnimationsAsync()]
});

Преобразования входных значений

Часто встречается компонент, который получает на вход булевое значение. Это, однако, накладывает ограничения на то, как можно передать значение такому компоненту. Например, если у нас есть следующее определение компонента Expander:

@Component({
  standalone: true,
  selector: 'my-expander',
  template: `…`
})
export class Expander {
  @Input() expanded: boolean = false;
}

...и мы стараемся использовать его как:

<my-expander expanded/>

При этом будет выдана ошибка "string is not assignable to boolean". Преобразования входных значений позволяют исправить это, настроив декоратор ввода:

@Component({
  standalone: true,
  selector: 'my-expander',
  template: `…`
})
export class Expander {
  @Input({ transform: booleanAttribute }) expanded: boolean = false;
}

Оригинальные запросы функций можно найти на GitHub - Boolean properties as HTML binary attributes и Boolean properties as HTML binary attributes.

Style и styleUrls как строки

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

@Component({
  styles: [`
    ...
  `]
})
...
@Component({
  styleUrls: ['styles.css']
})
...

...к более простому и логичному:

@Component({
  styles: `
    ...
  `
})
...
@Component({
  styleUrl: 'styles.css'
})
...

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

Схемы сообществ

Для поддержки разработки схем сообщества мы добавили несколько методов-утилит в рамках @schematics/angular/utility. Теперь вы можете импортировать выражение непосредственно в корень приложения Angular и добавить провайдер в корень приложения Angular, а также воспользоваться уже существующей возможностью добавления зависимостей в package.json.

Более подробную информацию можно получить в руководстве по схемам в документации.

Обучение разработчиков Angular

Мы сотрудничали с SoloLearn, интерактивной платформой EdTech, для разработки нового курса по Angular на основе недавно разработанного нами курса "Введение в Angular". Они создали интерактивный учебный курс, который за последние два месяца посетили более 70 тыс. человек!

Более подробная информация содержится в нашем недавнем сообщении.

Яркие моменты деятельности сообщества

Мы хотели бы поблагодарить 346 участников, которые сделали Angular v17 таким особенным! Мы хотели бы перечислить несколько наиболее ярких моментов:

Построение будущего с Angular

В течение последних шести месяцев мы продолжаем возрождать Angular, выпуская новые функции для повышения удобства работы разработчиков и производительности. Сегодня мы рады отразить эту динамику в обновленном бренде Angular и учебном опыте с angular.dev.

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

Мы гордимся тем, что являемся частью вашего путешествия по созданию будущего с помощью Angular! Спасибо!

Tags:
Hubs:
Total votes 10: ↑10 and ↓0+10
Comments6

Articles