Сейчас во фронтенде среди фреймворков есть три явных лидера: Angular, React и Vue. Думаю, мы можем судить о любви разработчиков к проекту по количеству звезд на GitHub. На момент написания данной статьи у Vue уже 161 тысяча звезд, на втором месте находится React с 146 тысячами, а на третьем месте — Angular со своими скромными 59.6 тысячами. С первого взгляда может показаться, что Angular не настолько популярный, как другие фреймворки, но если обратиться к результатам исследования статистики с портала Tecla, то мы увидим, что Angular занимает довольно большую долю рынка. Например, по данным исследования Angular работает на более чем 400 тысячах сайтов, в то время как Vue — на 100 тысячах. Предлагаю в этом разобраться. Рассмотрим, за что разработчики любят Vue, почему много приложений написаны на Angular и какие выгоды может получить разработчик при использовании фреймворка от Google конкретно для себя.  Чаще всего выделяют следующие пункты особенного удобства Vue (они перечислены не в порядке приоритета): Хотел бы обратить ваше внимание, что достаточно большая часть — это Developer Experience, то есть комфорт работы с фреймворком. Думаю, что теперь причина любви стала вполне очевидной. Если обобщить, то вы можете сесть, запустить vue-cli, сконфигурировать проект как вам нужно и сразу же начать делать классные вещи, не думая о рендеринге, оптимизации, сборке и многом другом. Но если работа с Vue — это сплошное удовольствие, то почему в больших компаниях Angular используется гораздо чаще? Когда одно из самых важных в разработке — это простота, комфорт и скорость, то тогда вам нужен Vue. Но когда речь заходит уже о крупном проекте с большим количеством разработчиков, сложной работой с данными и разнообразным API, то ситуация меняется. И давайте подробнее разберемся почему. Наверное, один из определяющих факторов при выборе фреймворка большой командой является наличие готовых подходов. Angular разработан таким образом, что для решения практически каждой проблемы уже существует какой-либо паттерн и готовая библиотека/сервис к нему. Предлагаю все рассматривать на примерах. В каждом SPA-приложении требуется работа с API. Как будет реализована работа в каждом из фреймворков? Стандарты и практики, принятые в сообществе Angular не только декларируют как писать хороший код, сохранять грамотную архитектуру, но и позволяют другим разработчикам быстро включаться в работу, понимать что происходит фактически с первого дня на проекте. Плюс, это избавляет вас от обсуждений внутри команды, которые практически со 100% вероятностью возникнут в проектах на Vue. Думаю, что это вообще один из основных плюсов подобных крупных решений — вам не нужно думать о части работы, вы можете потратить время на что-то другое (и это не обязательно работа). Итак, давайте рассмотрим что в Angular еще есть. Мы уже поговорили о сервисах, интерсепторах и клиенте для работы с API. Предлагаю рассмотреть что вы можете получить еще. "Из коробки" во Vue работать с формами очень сложно. Вам нужно сформировать начальные данные, передать их в инпуты, ловить изменения и отражать их в данных. А если нужна валидация? Куда вы будете выводить ошибки? Как будете понимать, что форма еще не была "потрогана" пользователем? Да, есть классные сторонние библиотеки вроде Vuelidate. Но, вам как минимум нужно о них знать. В Angular “из коробки” реализована потрясающая работа с формами. Вы просто создаете FormGroup, передаете начальные значения, ставите нужные валидаторы и… Все. Далее вы можете управлять формой как угодно. Сбрасывать значения, ставить состояние dirty или принудительно указывать состояние валидности. То есть вам нужно думать исключительно о бизнес-логике. DI — это механизм управления зависимостями, который выносит логику управления экземплярами из класса вовне. Можно сказать, что это самое важное отличие Angular от других фреймворков. Давайте представим, что у нас есть компонент, который выводит данные о пользователях социальной сети. Чтобы все было красиво, мы вынесем логику работы с API в специальный класс или функцию. В контексте Angular лучше выносить все в классы, поэтому мы создадим некий UserService. Теперь мы будем использовать наш сервис в коде компонента. Во Vue: В Angular: При создании компонента в Angular вы просто указываете в конструкторе, что вам нужен UserService. После этого вы можете спокойно его использовать, не думая о лишних создаваемых экземплярах, о ленивой загрузке модулей и прочем. Если вам понадобится специальный экземпляр с определенными параметрами, то это тоже очень просто сделать. На самом деле, это довольно поверхностное описание работы механизма DI. Он позволяет очень удобно работать с зависимостями. Есть множество статей, которые описывают данный механизм, в том числе и моя. Если интересно, то можно ознакомиться. CLI — это инструменты командной строки, которые помогают автоматизировать какой-либо процесс. Как правило, это типичные и даже рутинные задачи. Vue CLI позволяет быстро сконфигурировать и создать проект, а затем с его помощью собирать приложение, запускать тесты, линтеры и так далее. Но на этом его возможности заканчиваются. Так как в мире Vue нет уже готовых паттернов решения проблем, то и CLI не может его предложить. В мире Angular же CLI позволяет не только сконфигурировать и создать проект, но и сгенерировать сервисы, модули, компоненты, директивы и даже целые библиотеки. При создании компонента не только формируются все необходимые файлы, но и импортируются в нужные модули. Этот процесс происходит с помощью специальных библиотек-схематиков. При необходимости вы можете сами написать свой схематик с помощью специального мини-фреймворка. Например, вы можете написать свою библиотеку и использовать автоматическое создание корректных компонентов с принятыми в вашей организации правилами, генерировать автоматические файлы тестов или даже составлять базу для документации. Возможностей действительно масса. Angular CLI избавляет вас от массы рутинных операций, позволяя не думать о процессе создания файлов и прописывания импортов. Лучше потратьте сэкономленное время на архитектуру, отдых или на чтение Хабра. Давайте представим, что у нас есть приложение с довольно сложной бизнес-логикой. Во Vue нет строгих паттернов и поэтому вы можете поступать как хотите — вынести логику в специальные классы, в экшены стора или оставить ее прямо в компоненте. А в Angular уже начиная с обучения нам говорят, что компонент должен отвечать только за демонстрацию данных, а работа с ними должна происходить в сервисах. Это повышает чистоту и надежность кода, вносит ясность и упрощает понимание. TypeScript — это статически типизированный язык, "JavaScript that scales", как называют его создатели. Он привносит в JavaScript типы, позволяет писать красивые классы, как в "больших" языках программирования. О его возможностях и преимуществах в сравнении с JavaScript написано много статей и книг. Angular использует TypeScript по умолчанию, у вас просто нет возможности выбрать JavaScript или перейти на него вручную. Фреймворк использует множество конструкций TypeScript, без которых просто невозможно обойтись. Например декораторы, перечисления, интерфейсы и так далее. Vue также может работать с TypeScript. Более того, Vue CLI даже опционально предлагает выбрать TypeScript на этапе создания проекта. Единственным минусом является не совсем удобная реализация декораторов, вычисляемых значений и прочего. Например, вы можете указать свойства компонента или хуки жизненного цикла как в декораторе класса, так и в самом классе. Но это можно считать делом вкуса. Стоит также отметить, что TypeScript не заставляет вас писать компоненты в виде классов. На сегодняшний день сложно представить себе SPA-приложение без Lazy Loading'а. Если раньше мы реализовывали это с помощью Webpack'а, копались в его настройках и устанавливали плагины, то теперь фреймворки делают это за нас. Нам достаточно только написать одну конфигурацию. Для Vue существует библиотека Vue Router. Да, она поставляется отдельно, но тем не менее ее можно считать частью экосистемы Vue. Vue Router позволяет получить доступ к параметрам адреса, управлять навигацией, ставить классы для активных ссылок и многое другое. Angular имеет свой встроенный RouterModule, который позволяет делать все то же самое, но к тому же добавляет возможность отслеживать множество событий навигации (если быть точным, то 16), позволяет установить стратегию предзагрузки. В общем, имеет немного более широкий функционал. Во Vue при обновлении значения в поле data автоматически происходит обновление связанных данных и перерисовка шаблона. Вам не нужно принудительно вызывать метод render() компонента или вообще как-то думать об этом процессе. Но как же это происходит? Здесь все просто — значения обновляются реактивно. Любое поле в данных — это Observer, то есть реализация паттерна "Наблюдатель". Давайте представим, что есть объект, у которого есть какое-то значение. И есть другие объекты, которые "наблюдают" за первым объектом. При изменении значения первого объекта наблюдатели узнают об этом и производят какие-то действия. Angular использует этот паттерн не только для отрисовки шаблона или обновления данных, но и вообще повсеместно. Он использует библиотеку для реактивного программирования RxJS, без которой также обойтись нельзя. Она позволяет представить любые операции с данными в поток. Все, что вам нужно сделать — это подписаться на этот поток данных и делать с результатом все, что захотите. Давайте подведем итог и посмотрим что вы, как разработчик Vue, можете получить при работе с Angular: А теперь я предлагаю реализовать компонент с одинаковым функционалом на Vue и Angular. Давайте напишем простой пример с основными механизмами. В коде компонента ниже есть параметры, состояние, вычисляемые значения, хуки и методы — все, что требуется для нормальной работы. Здесь мы также видим данные, обработку событий, динамические свойства и директивы. Чтобы использовать данный компонент, достаточно просто импортировать его в родителя: Шаблон родителя будет выглядеть так: Предлагаю реализовать такой же по функциональности компонент на Angular и посмотреть как он будет выглядеть. Код класса будет выглядеть так: Данному компоненту будет соответствовать следующий шаблон: Что касается компонента, то это все. В Angular есть целое множество возможностей переписать этот компонент по-другому. Например, используя потоки данных. Если интересно, то код компонента на потоках я представил ниже. На данном же этапе я хочу продемонстрировать схожее в двух фреймворках, поэтому реализовал все таким же образом, как и во Vue. В Angular используется модульная система. Модуль может включать в себя набор компонентов, сервисов или даже других модулей. Чтобы иметь возможность использовать компонент внутри модуля, достаточно его туда импортировать: В данном примере у нас есть главный модуль, и мы просто говорим, что используем новый компонент здесь. Он будет доступен для указания в шаблоне AppComponent. Но есть и другой способ. Например, наш компонент использует другие модули. Чтобы не импортировать все в AppModule, мы создаем специальный модуль и импортируем компонент уже в него. Чтобы компонент стал доступен вне модуля, нужно его экспортировать. Выглядит это так: После того, как мы подготовили наш модуль, его достаточно просто импортировать туда, где мы его будем использовать: Такой способ работы позволяет инкапсулировать всю специальную логику в одном месте и при импорте не думать об этом. Плюс, разделение на модули позволяет удобно управлять Lazy-Loading'ом. В шаблоне родителя использование компонента вне зависимости от реализации декларации будет выглядеть одинаково: Вот как можно реализовать тот же самый компонент, но уже на потоках: В данном примере все считается декларативно. Что это нам дает: Итак, давайте подведем итог. Почему большие проекты, скорее всего, будет удобнее писать на Angular: Что вы можете получить как разработчик: Стоит также отметить, что вы не лишаетесь всех плюсов, что есть в работе со Vue. В Angular 9 благодаря новому движку Ivy разработка идет так же быстро, дебаг стал более удобным, размер бандла стал еще меньше, а процесс рендеринга работает еще быстрее за счет нового механизма. Поэтому просто могу порекомендовать вам попробовать. Frontend Developer