Три года с Angular и не жалею: обзор возможностей фреймворка

Я начал работать с фреймворком Angular 2 в мае 2015-го. Тогда он был в альфа-версиях, и наша компания активно искала JavaScript-фреймворк для замены фронтенда большого приложения, сделанного на Adobe Flex. К тому времени мы уже попробовали Ext JS и Angular JS и не были в восторге. Зато нам понравилась комбинация компонентной структуры Ангуляра, типизированного языка TypeScript и хорошей поддержки IDE. Прошло почти три года, и мы довольны своим выбором. Эта статья — обзор Ангуляра.

Ваше приложение — дерево компонентов

Когда разработчик получает картинку с прототипом будущего приложения, он начинает с разбивки его на компоненты. Любое приложение на Ангуляре имеет один корневой компонент, который может включать другие компоненты («дети»), а те, в свою очередь, могут включать своих детей («внуков»). Допустим вы решите переписать Twitter UI на Ангуляре. Начните с разбивки его на компоненты.

Корневой компонент показан в красной рамке, и он включает несколько детей. В середине сверху можно разместить компонент New Tweet (в синей рамке) под которым пойдут экземпляры компонента Tweet (показаны в желтых рамках), у которых тоже есть «дети», показанные в черных рамках (reply, retweet, like, and direct messaging).

Компонент-родитель может передать данные компоненту-ребенку с помощью привязки данных (binding) к свойствам ребенка. Компонент-ребенок притворяется сиротой, типа я не знаю ни папу, ни маму. Такому ребенку не важно откуда прилетели данные. Но у этого сиротки все же теплится надежда, что родитель найдется, поэтому ребенок может генерировать события (events) и отправлять послания с данными наверх. Кому? Тому, кто захочет их получить и обработать. Такая архитектура делает компоненты самодостаточными, и их можно использовать в разных приложениях. Сегодня ты мой папа, а завтра — дядя Вася.

Чистое разделение между UI и апликационной логикой

Компонент — это TypeScript-класс, аннотированный декоратором @Component, где вы указываете метаданные компонента: HTML и CSS. Их можно имплементировать либо в отдельных файлах, либо прямо в декораторе (inline), как в этом примере:

@Component({
  selector: 'home',
  template: `<div class="home">Home Component
               <input type="text"/> </div>`,
  styles: [`.home {background: red; padding: 15px 0 0 30px;
                   height: 80px; width:70%;
                   font-size: 30px; float:left;}`]})
export class HomeComponent {
   // Implement business logic here
}

Когда темплейт (HTML) или стили состоят из многих строк, их можно держать в отдельных файлах:

@Component({
  selector: 'home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
export class HomeComponent {
}

Навигация на клиенте с помощью раутера

Ангуляр хорош для создания single-page apps (SPA). Браузер не перезагружает всю страницу, а только ее фрагменты, по мере того как пользователь взаимодействует с приложением (жмет на кнопки, ссылки и т. д.). У Ангуляра есть Router для навигации внутри приложения. Внутри темплейта компонента с помощью тега <router-outlet> можно выделить одну или больше областей для отображения разных фрагментов страницы. Например, в приложении Twitter вы можете выделить среднюю часть страницы под <router-outlet>, и, если пользователь нажмет на меню Notifications, в этой области будет показан другой компонент.

Модуляризация приложения

Приложение можно и нужно разбивать на модули. У приложения должен быть один корневой модуль с минимальной функциональностью, а фичи можно имплементировать в отдельных модулях, например, Billing, Shipping и т. д.

Более того, эти модули могут подгружаться «лениво», чтобы минимизировать размер базовой страницы приложения. Так, например, главная страница приложения не грузит модуль Billing до тех пор, пока пользователь не нажмет кнопку «Оплатить». А еще можно легко сделать так, что такие фичи будут автоматически подгружаться в бэкграунде после того, как главная страница уже загружена и пользователь начал работать с приложением.

Dependency injection

Компоненты — это классы, у которых есть UI, а сервисы — это классы, содержащие аппликационную логику. Вы пишете такой класс, например, ProductService, а Ангуляр создает его экземпляр и вставляет (injects) его в ProductComponent. Для этого нужно просто указать сервис аргументом конструктора компонента и не нужно создавать экземпляр класса оператором new:

@Component(...)
class ProductComponent{

  constructor (public productService: ProductService){ }

  onClick(){
    this.productService.getProducts();
  }
}

В этом примере мы используем API сервиса в обработчике события click.

TypeScript и ECMAScript

Для программирования Ангуляр-приложений рекомендуется использовать язык TypeScript. Это надстройка над JavaScript, которая поддерживает статические типы. Если вы будете объявлять переменные с типами (хотя это не обязательно), то IDE предложит autocomplete и будет подсвечивать синтаксические ошибки, как только вы их сделаете, не дожидаясь ни компиляции, ни запуска программы. По опыту нашей компании, продуктивность разработчиков существенно повышается по сравнению с программированием на JavaScript.

Typescript легко изучить любому, кто знает Java, C#, PHP или Python. Этот язык поддерживает классы, интерфейсы, наследование, дженерики и многое другое. Вы пишете на TypeScript и компилируете код в JavaScript, который понимают все браузеры. Взгляните на вот этот скриншот и сравните TypeScript-код слева со сгенерированным эквивалентом на JavaScript (ES5) справа. Не знаю, как вам, а мне больше нравится версия на TypeScript.

Все браузеры поддерживают синтаксис JavaScript версии ECMAScript 5 и большинство современных браузеров уже поддерживают ES6, который добавил много элементов, включая классы. ES7 и ES8 добавили немного, хотя важным улучшением является введение ключевых слов async и await, которые позволяют вырваться из ада колбэков. Если вы будете писать на TypeScript, то можете пользоваться последними новинками уже сегодня, а компилятор сам преобразует код в ту версию JavaScript, которая поддерживается всеми браузерами.

Шлепаем формы

Трудно представить веб-приложение, где не нужны формы. Ну, хотя бы залогиниться надо?

За каждой формой стоит объект с моделью данных, хранящей все значения, введенные пользователем. Ангуляр предлагает два API для форм: template-driven и reactive. Тот, который template-driven, позволяет кодировать формы, не парясь созданием модели в TypeScript. Просто спрысните HTML-формы несколькими директивами, а Ангуляр сам создаст модель.

Для более продвинутой работы с формами используйте reactive Forms API. Здесь вы сами будете кодировать объект модели в TypeScript, зато у вас будет больше контроля над поведением формы.

И template-driven и reactive API имеют встроенные валидаторы и позволяют использовать кастомные, чтобы пользователь не вводил невесть чего. Можно и на сервере организовать валидацию с использованием так называемых асинхронных валидаторов.

Реактивное программирование

В последнее время стали популярными реактивные (RX) библиотеки, которые построены на работе с observable потоками данных, которые асинхронно генерируются каким-либо источником, например событиями мышки,сенсорами, сокетами и т. д. Такие библиотеки включают большой набор операторов, которые легко собирать в цепочку для манипуляции данными по дороге от источника данных до подписчика. Ангуляр поставляется с библиотекой RxJS и вы можете либо подписываться на готовые observable streams предоставляемые разными APIs, либо создавать такие потоки сами.

Допустим, пользователь вводит название акции из финансовой биржи в поле searchInput. Следующий код подписывается на поток valueChanges (он есть у всех ангуляровских элементов форм) и хочет сделать запрос к серверу, чтобы получать меняющиеся цены на эти акции. Чтобы миниизировать количество запросов к серверу, мы используем оператор debounceTime, чтобы функция getStockQuoteFromServer() вызывалась, только если пользователь ничего не вводит в течение 500 милисекунд.

this.searchInput.valueChanges
  .debounceTime(500)
  .subscribe(stock => this.getStockQuoteFromServer(stock));
 }

Код получается компактным, но будьте готовы потратить время на изучение библиотеки RxJS. В этом примере я поместил один оператор debounceTime между источником данных и подписчиком, но я мог собрать цепочку из нескольких операторов, например map и filter. Можно добавить одну строку с оператором switchMap, который автоматически будет отписываться от запросов, которые еще не вернулись (медленный интернет), а пользователь уже вводит новое значение. Попробуйте отменять ненужные запросы у простых Ajax-вызовов — oдной строчкой не обойдетесь.

Современный UI

Многие веб-приложения используют популярную библиотеку Bootstrap для стилизации и разметки (layout) страниц. Вы можете пользоваться этой библиотекой и в приложениях на Ангуляре. Bootstrap поддерживает responsive web design, чтобы расположение UI-компонентов автоматически адаптировалось к ширине экрана устройства пользователя.

Есть и другие библиотеки, сделанные специально для Ангуляра. Angular Material — это библиотека, включающая 30 современных компонентов, сделанных согласно спецификации Google Material Design. Если вам нужно больше компонентов, используйте одну из сторонних библиотек. Так, например, PrimeNG включает 75 UI компонентов, сделанных специально для Ангуляра.

Тулзы

Генерация нового проекта с установкой всех зависимостей занимает около минуты с помощью Angular CLI — программы, запускаемой с командной строки. Angular CLI не только генерирует новые проекты, но и компоненты, сервисы и другие артефакты в процессе работы над проектом. Angular CLI включает веб-сервер с автоперезагрузкой кода. В вашем проекте могут быть сотни файлов, однако одной командой они собираются в несколько JavaScript-файлов (bundles). Размер минимального приложения, обработанного gzip, — 55KB, а скоро будет значительно меньше. Не вау? Читайте статью до конца. При правильной разбивке приложения на модули оно быстро грузится.

Дебажить TypeScript-код можно либо прямо в браузере, либо в IDE.

Проекты, сгенерированные Angular CLI, включают полностью сконфигурированные библиотеки для unit и end-to-end тестирования.

Ангуляр на мобильных устройствах

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

  • Используйте один и тот же код для десктопов, планшетов и смартфонов, но имплементируйте приемы responsive web design для изменения содержимого и разметки экрана в зависимости от его размера.
  • Используйте одну из библиотек (например Native Script), которые предлагают набор тегов для применения в темплейтах компонентов Ангуляра с автозаменой их на нативные компоненты iOS или Android.

Server-side rendering

Sever-side rendering (SSR) еще более улучшает скорость рендеринга в браузерах. SSR еще на сервере готовит HTML-страницу из вашего ангуляровского приложения. Это особенно полезно, если ваши пользователи используют мобильники или вам важно, чтобы приложение лучше находилось поисковиками. Angular Universal — это технология, которая генерирует статические веб-страницы на сервере.

Если у вас уже рука тянется к клавиатуре, чтобы написать: «А Реакт лучше Ангуляра», — не тратьте время зря. Не будем сравнивать мягкое с теплым. Хотя почему бы и нет?

Так Angular или React?

Вы сможете нагуглить много статей «Почему мы перешли с Ангуляра на Реакт» и «Почему мы перешли с Реакта на Ангуляр». Помните, что Ангуляр — это полноценный фреймворк, который поддерживает быструю отрисовку страниц, навигацию, dependency injection, стильные UI-компоненты, server-side rendering, сконфигурированные тулы для тестинга, минимизации, деплоймента и много чего другого. Реакт — это библиотека для быстрой отрисовки страниц, и вам придется самому собирать набор других библиотек для routing, UI-компонентов, сборки и т. д.

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

Если вы работаете в маленьком стартапе, где есть только 2-3 сильных разработчика, выбор фреймворка менее критичен. Эти 10X разработчики продуктивны с любым фреймворком, библиотекой или просто с чистым JavaScript. Да и увольняются из стартапов реже, чем с галер.

Что день грядущий нам готовит

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

Angular Elements. Ангуляр хорош для создания single-page applications, а создание виджетов, которые можно использовать на любой HTML-странице, — непростая задача. Новый модуль Angular Elements позволит создавать отдельный компонент и публиковать его как Web Component, который можно будет использовать на любой HTML-странице. Эта фича — киллер, которая откроет еще больше дверей для Ангуляра.

Ivy renderer. Этo новый движок для рендеринга, который уменьшит размер минимального приложения до 3KB (gzipped). Разработчики Ангуляра обещают сделать переход на Ivy Renderer гладким. Если они это сделают, я сниму шляпу.

Bazel and Closure Compiler. Bazel — это сборщик, используемый внутри Google почти для всех приложений, включая 300 приложений, написанных на Ангуляре. Closure Compiler отлично оптимизирует билды, генерирует бандлы и лучше, чем Webpack и Rollup, убирает неиспользуемый код. В новых релизах Angular CLI будет использовать эти тулзы.

Component Dev Kit (CDK). Этот пакет уже есть и используется UI-компонентами из Angular Material. А что если вы захотите сделать свою библиотеку UI-компонентов и контролировать разметку страницы? CDK позволяет это сделать.

Schematics. Angular CLI генерирует код на основе калек (blueprints). Если вы решите создать свои кальки, чтобы Angular CLI ими пользовался при генерации, Schematics вам поможет.


Это была обзорная статья, но я регулярно публикую технические блоги об Ангуляре у себя на сайте. Я слышал, что вышел перевод на русский язык первого издания нашей книжки по Ангуляру, однако я советую взять второе издание здесь. А промокод «fccfain» снизит цену на 37%.

Для тех, кто уже знает основы Ангуляра, предлагаю записаться на мои короткие онлайн-тренинги. Один по созданию симпатичного UI — за две сессии под моим чутким руководством вы сделаете фронтенд небольшого онлайн-магазина. Второй воркшоп о state management в стиле Redux с помощью библиотеки ngrx. Для читателей DOU — скидка 25% с промо кодом «dou». Оба воркшопа на английском, звиняйте.

Похожие статьи:
Через початок повномасштабного вторгнення в Україну IT-індустрія переживає не найкращі часи. У 2023-му айтівці зауважували про...
У свіжому випуску новинного дайджесту DOU News говоримо про бронювання айтівців, відкритий код застосунку «Дія», кількість...
Військова агресія рф проти України триває вже понад 40 днів, і за цей час на воєнні рейки довелось встати не лише...
Міжнародна аутстафінгова ІТ-компанія ALLSTARSIT, яка має орієнтовно тисячу фахівців в Україні, повідомила DOU про...
Всем привет. В прошлой статье я описывал, что изменилось в ASP.NET для разработчика. В продолжении цикла хочу...
Яндекс.Метрика