×Закрыть

Три года с 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». Оба воркшопа на английском, звиняйте.

LinkedIn

33 комментария

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Регистрация на тренинг по созданию онлайн магазина закрыта.

И еще вопрос — какую библиотеку компонентов вы лично предпочитаете?

Использовали ли вы Redux вместе с Angular?

Да, ngrx, который смесь redux и RxJS

Та сама хвороба: люблю Angular з альфа версій, і чим далі тим дужче!

Якове, ви згадували автокомпліт в TS-коді — так, він діє файно! Є ще один бонус, про який не згадано в дописі: у VS Code можна отримати автокопліт і transpile-time errors check прямо в коді html-шаблонів, встановивши плагін Angular Language Service for VS Code.

Коли в мене зібрався проект на 15 компонентів, ще на предрелізових рц-шках (2, 4) з першого запуску, без тижневих читань доки — я зрозумів — це для мене мірило фронт-енду. Щей немає ніякої строгої вимоги типізації, а то ці псевдо-розробники регакту лякають Джунів, що там як в джаві. У всіх великих проектах, що доводилось в команді розробляти на перших етапах все без типів можна робити і нічого поганого не буде, але для продуктивності, кращого процесу відладки і розвитку компонентів, сервісів, директив та інших модулей — типізація і створення інтерфейсів це великий плюс і очевидна необхідність... так довго можна...

Забавно, уже на протяжении многих лет невольно повторяю технологическую эволюцию Якова, хоть и с некоторым запозданием, но вехи те же самые. 5 лет на Flex, потом 3 года Ext, и вот уже месяц на Angular 5. Ну что я могу сказать — мой satisfaction level от каждой новой технологии неуклонно падает. С Flex 3 я был счастлив. С Flex 4 я прищуривал глаз и говорил «ну, это скоро пофиксят». С Ext-ом меня всегда преследовало чувство «все есть — но ни хрена как надо не работает». В Ангуляре ни хрена нет, ни хрена не работает — но TS божественен по сравнению с голым ES5 и даже AS3.
Скучаю по древним временам с Delphi/C# + DevExpress.

В Ангуляре ни хрена нет, ни хрена не работает

В Ангуляре все работает. Посмотрите видео моего 3-х часового воркшопа: www.youtube.com/watch?v=owZVKNg6cG4

Три года с Angular и не жалею

це як «три года в браке и не жалею» : ніби і віриться, але все ж деякий сумнів закрадається :)

Vue.js все равно лучше.... можно грабить корованы.

обмежена бібліотека, яка не може навіть приблизно рівнятись до фреймворка, тим більше до Ангуляра.

по перше фреймворк, по друге чим обмеженый?

Хочу вас розчарувати, це все ще бібліотека (назвавши паперовий літачок — літаком, навряд чи зможете людей ним транспортувати), а те що в ньому з’явилися додаткові бібліотеки це добре, проте ще далеко до фреймворка (ось у цьому його обмеженість, пока). В моєму списку «хейтерства» (зневажання) його немає на відмінну від регакта з його костилями, так як я бачу в

Vue

хорошу команду розробників, хороші результати і націленість на універсальність.

Обожнюю розробників котрі документацію не всилі прочитати

Що ж ви так себе хвалите. Ось Вам надам частини з їх доки: «В тех случаях, когда альтернативные библиотеки имеют существенные преимущества, как например обширнейшая экосистема альтернативных средств отрисовки React’а или поддержка браузеров вплоть до IE6 Knockout’ом», «С другой стороны, Vue полностью подходит и для создания сложных одностраничных приложений (SPA, Single-Page Applications), если использовать его совместно с современными инструментами и дополнительными библиотеками.», «Если вы — опытный фронтенд-разработчик, и хотите узнать, чем Vue отличается от остальных библиотек или фреймворков, обратите внимание на сравнение с другими фреймворками.» Я надіюся Ви це хоча б осилите, якщо в самому коді даної бібліотеки очевидного не бачите.

Спробуйте спростувати це «В качестве ещё одного важного различия между React и Vue можно упомянуть тот факт, что все дополнительные библиотеки Vue, включая библиотеки для управления состоянием приложения и для роутинга (среди прочих задач), официально поддерживаются в актуальном соответствии с ядром библиотеки. »

Так где здесь утверждение что вью = библиотека. Тут общее сравнение инструментов подводящее к конкретике которая уже раскрывается в главе сравнения.
И как можно не заметить слова в теге h1 на главной странице или не суметь прочитать дискрипшн в репозитории?!

землю(щоб не сказати щось коричневе) замотану в обгортку цукерки можна цукеркою назвати? Чесне слово, Ви такий довірливий, що в документації не бачете "

все дополнительные библиотеки Vue

"

ядром библиотеки

. «библиотеки»- не фреймворк.

Надобраніч, з мене вистачить. =)

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

Большинство проектов на React используют базовый набор библиотек, поэтому говорить о том, что осваивание проекта на Angular займет меньше времени, по моему мнению, нецелесообразно.

А ведь когда-то вы доказывали что ExtJS и Flex — наше все и с их помощью можно сделать все, что можно сделать с ангуляром :)

Я не доказываю, а рассказываю то, что думаю сейчас. Через 3 года может выйти фреймворк XYZ, который лучше Ангуляра. Напишу новую статью :)

С Flex такие мысли действительно возникали. С Ext — в целом да, но ценой определенного гемора. С Angular пока такого чувства нет.
Непонятны Ваши претензии к Якову — когда Google забьет на Angular, как Adobe забила на Flex а Sencha почти забила на Ext, все точно также перелезут на что-то новое и неудобное, но будут добрым словом вспоминать Angular (если будет за что).
К тому же, подозреваю, что вы припоминаете Якову времена 1-го Ангуляра, и когда еще не совсем был мертв Flex. Нуу, я Вам скажу — мне как раз довелось их сравнивать, и я не могу подобрать не матерные эпитеты для этого экспириенса.

сравните TypeScript-код слева со сгенерированным эквивалентом на JavaScript (ES5) справа. Не знаю, как вам, а мне больше нравится версия на TypeScript.

Бо так ніхто не пише на js.. на то він і є згенерований код! Та й extends треба тільки 1 на аплікуху, тому таке порівняння далеко не об’єктивне:)
Думаю Angular справді більше підходить для «кровавих ентерпрайзів» про які говорить автор, так як там часто ФЕ код пишуть бекендщики, які не дуже розбираються в фронтенді, але я б добре подумав чи хочу зациклюватись тільки на ньому, так як він диктує свої правила і вам постійно доведеться думати як зробити «in Angular way» і шукати «правильні» рішення проблем замість того щоб придумувати свої.

Отличная статься. Читается «на одном дыхании». Спасибо.

Поправьте пример из раздела Dependency injection — в текущем виде экземпляр сервиса не будет доступен через this. В конструкторе не использован шортхэнд, например private.

Спасибо, поправлю.

промо код на покупку книги не работает gyazo.com/...​0e90a7f1ffc6435be1ada1d1f

Должно быть fccfain

Подписаться на комментарии