Порівнюємо React, Angular і Vue — найпопулярніші бібліотеки й фреймворки у 2022 році
Всім привіт! Мене звуть Олександр, і я Team/Technical Lead, Senior Front-end Engineer у компанії TechMagic.
Протягом останнього часу з’явилась й продовжує з’являтись величезна кількість доволі цікавих і різноманітних фронтендних бібліотек і фреймворків для роботи з DOM, зокрема таких як Svelte, Lit, Solid і т.д.
Попри те, що в кожного з цих молодих фреймворків є хороший потенціал, більшість з них є ще доволі «сирими», в плані розміру ком’юніті, кількості доступних бібліотек (розмірі екосистеми), й навіть банальної можливості щось нагуглити у випадку, якщо у вас з ними виникнуть проблеми не описані в документації.
У цій статті, я розповім вам про основні переваги й недоліки React, Angular і Vue. Чому саме цих трьох бібліотек і фреймворків?
- З усіма ними мені довелось працювати лише за останній рік.
- Саме ці три бібліотеки зустрічатимуться вам у переважній більшості Outsource/Outstaff проєктів.
- В них найбільша кількість аудиторії і завантажень на GitHub i NPM.
Порівняння може бути корисним тим з вас, хто досі думає, яку з добре підтримуваних і наймасовіших (читати також, як «найпопулярніших») бібліотек обрати для наступного комерційного проєкту.
React
React або «ReactJS» являє собою бібліотеку для значного спрощення побудови й маніпулювання DOM елементами. Творцем цієї бібліотеки виступає компанія Facebook. Спочатку її розробляли й використовували лише для внутрішніх потреб (тобто безпосереднього написання своєї соцмережі), й лише згодом зробили публічною, надавши до неї доступ широкому загалу програмістів.
У своєму чистому вигляді React і справді є нічим більшим, аніж звичайнісінькою бібліотекою для написання простих фронтендних додатків (при цьому, навіть не Single Page Application), оскільки не містить ані Routing, ані інших додаткових можливостей. Лише відносно нещодавно отримав офіційну можливість використовувати Context API для реалізації доволі простенького state management.
Щоб користуватись React, достатньо додати посилання на бібліотеку у `index.html` сторінку. Найпростіший додаток/компонент з виводом тексту «Hello World» на React наразі виглядає наступним чином:
const HelloWorldComponent = () => { const message = "Hello world"; return <div>{message}</div>; }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(AppComponent);
Для того, аби це запрацювало, також необхідно додати один елемент <div id="root"></div>
, щоб нашому застосунку було до чого підв’язатись. Він слугує кореневим елементом для зображення усього нашого застосунку.
По суті всі компоненти у React є функціями, які приймають аргументи й повертають розмітку. Також, варто відзначити, що все, що є нижче за визначення функції AppComponent буде вказуватись лише раз — виключно у файлі «точці входу» застосунку.
Також тут є ще один цікавий момент. Якщо придивитись, функція повертає щось схоже на HTML. React використовує особливий синтаксис — JSX (Javascript Extended). JSX є синтаксичним цукром, котрий приховує набір методів і функцій, покликаних будувати репрезентацію DOM в Javascript (Virtual DOM), під виглядом максимально подібним на побудову HTML DOM дерев.
Також JSX дозволяє «змішувати» HTML i Javascript. До прикладу, ось так може виглядати промальовування списку елементів:
<ul> { unorderedListItems.map((item) => <li key={ item.name }>{ item.name }</li>) } </ul>
Тобто ми просто беремо і «промальовуємо» кожен елемент до <li>
з item.name, як ключ і контент цього елемента.
Плюси:
- Синтаксис є максимально зрозумілим, якщо вам знайомі Javascript i HTML.
- Крива входу у користування React є максимально пологою.
- Функціональний підхід до написання компонентів.
- Основним з найважливіших підходів, які пропагує React, на мою думку, є принцип Immutability. Тобто все, що робиться в межах компонентів, в жодному випадку не має мутувати стану або даних, а лишень створювати нові екземпляри на основі вже наявних.
- Компоненто-центристський підхід до написання застосунку (тут все є компонентами).
- Вага бібліотеки — 2.5Kb мінімізована Gzip версія.
- Підхід до створення екосистеми застосунку — від меншого до більшого. Тобто тут лише ви вирішуєте, що потрібно брати з додаткових бібліотек і пакетів, а що — ні.
- Стан DOMу зберігається й обчислюється у віртуальному DOMі, що робить React дуже швидким в плані рендерінгу.
- Юніт тестування є максимально простим, оскільки не потрібно налаштовувати жодного «додаткового» оточення і браузерів для відрендерювання компонентів.
- Величезна кількість різноманітної інформації про помилки і основні проблеми.
- Окрім великої кількості бібліотек, призначених спеціально для React, до нього також можна «докрутити» будь-яку Javascript-бібліотеку, було б бажання.
- Відмінна документація, зокрема доступна й українською мовою, з хорошими прикладами й достойним описом.
- Велике ком’юніті.
- Велика кількість різноманітного тулінгу для полегшення процесу роботи й дебагу.
- Широкий вибір бібліотек під будь-яку задачу і смак.
- Повноцінна підтримка Typescript при використанні React Create App або ж інших React CLI бібліотек.
- Регулярно оновлюється і вдосконалюється.
- Підтримується Facebook.
Мінуси:
- Оскільки «з коробки» React не включає практично жодних додаткових можливостей, окрім роботи з DOM, необхідно знати або ж вміти добре гуглити потрібні й надійні бібліотеки для тих чи інших завдань.
- В простоті React криється й головний його недолік — тут можна запросто напартачити, не знаючи best practices передачі пропсів (у Angular — це Inputs і Outputs), декомпонентизації, структурування файлів React додатків, масштабування застосунку в цілому і решти нюансів. Що, з часом (й збільшенням кількості коду), може призвести до вкрай складної структури застосунку для її підтримання й подальшого розширення.
Angular
На відміну від React, Angular, що є продуктом компанії Google, вже є не просто бібліотекою для роботи з DOM, а цілим повноцінним фреймворком, котрий керується принципами MVVM побудови застосунків, й «з коробки» містить зокрема такі можливості, як:
- CLI для генерування структури файлів різних Angular-конструкцій, структури npm бібліотек, тестування, лінтування і т.д.
- Ряд бібліотек для самих різноманітних завдань — router, бібліотеки для роботи з формами, анімацією й інші.
- При ініціалізації проєкту можна доволі тонко налаштовувати те, що з доступних бібліотек буде додано до нього.
- Засоби лінтування.
- Karma + Jasmine для Unit i End to End тестування.
Історично, Angular хоча й виник трішки пізніше за React, фактично є переписаною з «нуля» версією фреймворку AngularJS, котрий існував раніше за нього. На початку серед фронтендщиків навіть виникали деякі непорозуміння, оскільки ніхто не розумів різниці між назвами Angular i AngularJS.
Як наслідок, команда розробки фреймворку почала використовувати назви Angular першої версії (для AngularJS) i Angular другої версії (для Angular), аби чіткіше їх розрізняти.
Якщо порівняти Angular з React, то його структура є значно складнішою. Окрім компонентів, тут також з’являються наступні елементи, кожен зі своїм призначенням:
- Пайпи — свого роду допоміжні функції для трансформації візуального вигляду даних у HTML темплейтах. Наприклад: форматування чисел, дат, валют тощо.
- Директиви — класи, котрі використовуються для надання додаткового функціонала іншим елементам застосунку. І також поділяються на кілька видів, в залежності від форми взаємодії з елементами (цей момент я пропущу, аби не вдаватись в подробиці). В основному застосовуються у вигляді користувацьких атрибутів елементів розмітки.
- Компоненти — є елементом для візуального зображення даних. Поєднують в собі стилі, HTML-файл з розміткою, а також JS або TS з логікою компонента.
- Сервіси — для можливості централізованого зберігання даних і утилітарних методів. Можуть використовуватись Пайпами, Директивами, Компонентами й навіть іншими Сервісами, додаючи їх за допомогою Dependency Injection.
- Модулі — спосіб згрупувати всі вищеперелічені елементи. В більшості випадків, по функціоналу або ж сторінках.
Аби трішки візуально розбавити цей потік інформації, далі буде приклад того ж простенького «Hello World» застосунку, що й у секції про React, але реалізованого засобами Angular.
Варто відзначити, що тут простим додаванням посилання на бібліотеку в index.html не обійдеться. Прикладу передували ініціалізація структури проєкту за допомогою Angular CLI. Структура вже має в собі всі необхідні файли (зокрема кореневого компонента AppComponent, який я побудував як простий приклад) з підв’язуванням застосунку до DOM, а також налаштуваннями лінтерів, тестів, Typescript і тому подібного.
Також для простоти розмітку було написано в межах властивості template, на противагу винесенню її в окремий html файл з подальшим вказанням шляху до нього у властивості templateUrl.
src/app/app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `<h1>{{ message }}</h1>` }) export class AppComponent { public message = 'message'; }
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule], bootstrap: [AppComponent] }) export class AppModule { }
Що ви щойно побачили?
- Створення простенького AppComponent компонента з розміткою і текстом «Hello World» за допомогою Javascript Class і спеціального декоратора @Component()
- Декларування (визначення) цього компонента в модулі AppModule, а також його реєстрацію в якості «вхідної точки» нашого застосунку, шляхом додавання його посилання в масив bootstrap.
На відміну від React JSX, який дозволяє вставляти по суті будь-який валідний JS код в розмітку напряму, Angular здійснює маніпуляції з DOM за допомогою вбудованих директив.
Для прикладу, ось як виглядатиме промальовування списку елементів в HTML шаблоні Angular:
<ul> <li *ngFor="let item of unorderedListItems">{{ item.name }}</li> </ul>
Тобто ми створюємо кілька <li>
елементів використовуючи директиву «ngFor», що дозволяє отримати елемент, на який ми його навісили unorderedListItems.length кількість разів.
Аналогічним чином досягається умовне зображення або ж приховування DOM елементів й інші подібні операції.
Плюси:
- Можливість чітко групувати елементи, використовуючи модулі.
- Є повноцінним фреймворком, що має все необхідне для написання сучасних вебзастосунків і навіть більше.
- Підтримка Typescript «з коробки». По суті фреймворк є побудованим з прицілом на підтримку Typescript, як однієї з головних ідей.
- Використання MVVM принципів побудови застосунків, що дає змогу чітко розмежовувати реалізацію бізнес-логіки від її представлення.
- Завдяки наявності модулів — чудово масштабується, якщо попередньо чітко планувати структуру застосунку й слідувати їй.
- Dependency Injection — чудовий спосіб передачі лише необхідних залежностей (у вигляді сервісів), у компоненти й інші елементи Angular. Особливо розквітає, коли починаєте писати всілякого роду тести для ваших компонентів, бо дозволяє легко підмінити будь-яку з цих залежностей необхідною вам імплементацією.
- Документація актуальна і вичерпна, в плані доступних класів, методів і типів. Також містить масу додаткової інформації, зокрема такої, як:
- Angular coding style guide — офіційний гайд по рекомендованому синтаксису, конвенціях, структурі застосунку.
- Best Practices, як рекомендації з написання Безпечних і Доступних застосунків, а також підходів для розбиття коду на множину окремих бандлів — Lazy-loading feature modules.
- І багато чого ще, з повним переліком доступної інформації можна ознайомитись тут.
- Кількість інформації, доступної в інтернеті щодо будь-якого аспекту роботи, чи певної бібліотеки.
- Велике ком’юніті.
- Широкий вибір бібліотек під будь-яку задачу і смак.
- Регулярно оновлюється і вдосконалюється.
- Дуже просунуте CLI, котре при цьому також піддається деякій кастомізації (для прикладу Blueprints, для кастомізації генерації компонентів та інших елементів і файлів).
- Підтримується Google.
Мінуси:
- Оскільки структура передбачає доволі великий обсяг знань, яким необхідно володіти аби почати писати на Angular, крива входу є доволі крутою. Як наслідок, мінусом є висока складність, порівняно з іншими фреймворками й бібліотеками.
- В документації подекуди катастрофічно бракує прикладів використання того чи іншого функціоналу, оскільки знання його сигнатури буває недостатньо.
- Офіційна документація доступна лише сімома мовами. Українська в їх переліку відсутня.
- Інколи низька швидкість роботи, яку дуже просто «зіпсувати». Але при цьому, якщо знати про те, як працює Angular Change Detection і як в цілому оптимізувати швидкість роботи й завантаження вебзастосунків, стає більш ніж конкурентною.
- Також мінусом, на мою думку, є пряме мутування властивостей класу для зміни або оновлення стану компонента.
Vue (v2.6.x і трішечки v3.x.x)
Наймолодший з цієї трійки бібліотек/ фреймворків і замикальний — Vue (читається як View). Я навмисне взяв для порівняння саме версію 2.6.х, оскільки це — основна версія, котру зараз використовують на проєктах.
Також більшість нових проєктів, з якими я стикався, створювалась саме на ній, а не Vue 3 (попри те, що його реліз вже місяць чи два як відбувся, станом на той час). Аргументувалось це тим, що третя версія була вкрай сирою й за відгуками дуже нестабільною. У зв’язку з цим, оновлення виходили доволі часто й нерідко містили Breaking Changes.
Vue є свого роду сумішшю Angular i React. З одного боку, у своєму чистому вигляді — це бібліотека для роботи з DOM, та з іншого боку — це фреймворк, в якого навіть є свій офіційний Vue CLI й певна екосистема бібліотек навколо нього.
Vue широко використовує й наполягає на підході Single File Component, щодо написання компонентів, як основному. Його суть полягає в тому, що стилі, розмітка і логіка компонента мають знаходитись в одному файлі. Хоча вона й надає можливість і засоби для розбиття компонента на кілька різних файлів.
Чому, як на мене, Vue є своєрідною сумішшю Angular i React? Спробую відповісти кількома пунктами, котрі продемонструють деякі можливості цієї бібліотеки:
- Маніпулювання DOM елементами відбувається за допомогою прямого аналога Angular Директив (котрі, між іншим, також називаються Директивами).
- V2.6 використовує декларативний підхід до написання логіки компонента (так званий Options API). Тобто по суті ми створюємо об’єкт, що містить поля, спеціальні методи й конфігурацію нашого компонента. Та з третього релізу додалась підтримка Composition API, тобто декларація логіки компонента стала візуально максимально подібною на тіло функціональних React компонентів:
- визначаємо функції, котрі потім можемо використовувати у HTML темплейтах;
- з’явились хуки, за аналогією з React.
Тобто в сумі своїй Vue 3 дала можливість писати компоненти з синтаксисом написання логіки, як у React, й темплейтами, як в Angular.
- V2.6 ще використовувала міксіни, ті ж, що й React на ранніх етапах свого існування. Пригадую, що розробники React відкинули це тому, що їх було дуже важко використовувати, а звідси, й підтримувати. Внаслідок цього вони з часом стали поганою практикою й фактично відкинулись ком’юніті. Аналогічна участь, на мою думку, чекає й міксіни та Vue, оскільки використання «домішок», які непрямо додають функціонал компонентам — важко відстежувати й підтримувати.
- У Vue оновлення стану відбувається прямим мутуванням властивостей компонента. Не для порівняння, але просто факт :)
З огляду на вище описані пункти, пишучи на Vue, і при цьому вже маючи величезний багаж роботи з Angular i React, — з’являються доволі змішані відчуття.
Тепер трішки прикладів. Я згадував про Vue 2.х і Vue 3, тому прикладів буде два, аби покрити другу і третю версії. Та перед цим зазначу наступне: якщо ви хочете використовувати Vue 3 версії без білдів і збірок, тоді це вдасться лише у версіях браузерів, що підтримують Javascript Import, тобто усі сучасні браузери, за виключенням старого IE11.
Ось так виглядатиме наш мінімалістичний Vue 2.6.x застосунок:
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <div id="root">{{ message }}</div> <script type="module"> var app = new Vue({ el: '#root', data: { message: 'Hello World' } }); </script>
А ось так виглядатиме наш мінімалістичний Vue 3.х.x:
<script src="https://unpkg.com/vue@3"></script> <div id="root">{{ message }}</div> <script type="module"> const { createApp } = Vue createApp({ data() { return { message: 'Hello world' } } }).mount('#root') </script>
Плюси:
- Доволі висока швидкість збірки й роботи застосунку в цілому.
- Можливість писати додатки, як з білд бібліотеками, так і без них.
- Кількість тулів і бібліотек доволі обмежена, але мінімально допустима. Тому цей пункт в «плюсах», хоча й недалеко від «мінусів».
- Малий розмір бандлів після білда.
- Складність: щось середнє між Angular i React, але все ж значно ближче до React. Тому вивчити й розпочати щось писати на Vue мало б бути доволі просто.
Мінуси:
- Бібліотека підтримується зусиллями команди творця бібліотеки й більшою мірою — ком’юніті. Фінансується бібліотека лише з «пожертв».
- Наразі кожен Major реліз Vue супроводжувався змінами, несумісними з попередніми версіями.
- Доволі мінімалістична офіційна документація з обмеженою кількістю доступних мов, хоча й більшою ніж в Angular.
- У версії 2.6 я зіткнувся з проблемою неможливості зрозуміти деякі помилки, що виникали при розробці, або бодай нагуглити проблеми, котрі виникали по ходу розробки (а виникали вони доволі часто). Тому зазвичай це суттєво підвищувало час пошуку проблем. Тобто інколи консольні помилки не допомагали, а навпаки заважали, оскільки не відповідали причині.
- Підтримка Typescript у версії 2.6 практично відсутня. Хоча й можлива, але з надзвичайно замороченими способами його додавання, не сумісними з нормальною комфортною розробкою. Підтримка Typescript у версії 3.х стала кращою, але за відгуками досі не дуже позитивно сприймається Vue ком’юніті (принаймні судячи з тих людей, з котрими я мав справу, й статей, які читав на тему). Хоча, можливо, «не дуже позитивна підтримка» більше стосується самого Typescript, в плані «навіщо з ним, якщо можна без нього», аніж зручністю його використання з Vue 3.
Висновок
Ось тут буде дуже суб’єктивно, з яскравими персональними фаворитами й аутсайдерами.
Відверто кажучи, за той час, який я пропрацював з Angular, React i Vue, в мене сформувались наступні думки та враження від кожного з них:
React — супер комфортний, добре підтримуваний, простий в розумінні та написанні, й надзвичайно потужний, якщо старатись писати на ньому «правильно». Тобто, використовуючи класні тулзи, обов’язково Typescript, більш-менш «стандартизовані» й класно задокументовані бібліотеки (якщо це можна так назвати), й хороші підходи до структурування, по типу «Atomic Design by Bred Frost» розбавляючи це все юніт/e2e тестами (й обов’язково TDD, оскільки писати його з React — одне задоволення).
Підходить як для простих, так і для складних проєктів, в залежності від планування й дотримання структури компонентів і файлів. Також при дотриманні цих факторів, добре працює в масштабі.
Anguar — до певної межі комфортний, але потребує повного прочитання наявної документації. Добре підтримуваний з оновленнями, спрямованими як на новий функціонал, так і на вдосконалення комфорту розробки. Дуже потужний і неймовірно класно масштабується, якщо в команді наявний Senior Angular розробник, знайомий з тим, як структурувати такі проєкти правильно в залежності від потреб. Тулзи, Typescript, тестування від Unit до E2E/Integration тестів — буквально вшиті в фреймворк.
Підходить для проєктів вище середньої й високої складності. Зумовлено це тим, що для відносно простих і більшості проєктів середньої складності зусилля на написання модулів, компонентів, сервісів і використання Dependency Injection часто не виправдовує себе, чим лише починає заважати розробці.
Vue — в плані комфорту доволі неоднозначно, оскільки постійно щось сипалось, постійно гуглились помилки й наявні тулзи не дуже спрощували життя. Підтримки Typescript не було, що іще сильніше ускладнювало прослідковування типів й без того заплутаних структур даних. Сам по собі доволі сирий, хоча залишились виключно позитивні враження від швидкості того, як це все компілювалось і в кінцевому результаті — працювало.
Виходячи з виключно власних відчуттів і досвіду, котрими спробував поділитись вище, — ніколи не розглядаю його як бібліотеку чи фреймворк для одного з наступних комерційних проєктів, відповідно, не раджу нікому з клієнтів.
В цілому, при виборі фреймворку чи стеку бібліотек я завжди керуюсь принаймні наступними запитаннями:
- Наскільки популярною й стабільною є бібліотека?
- Наскільки надійною є підтримка бібліотеки?
- Наскільки хорошою є документація цієї бібліотеки?
- Наскільки широкою є екосистема допоміжних бібліотек і тулів бібліотеки?
- Як добре підтримується Typescript?
- Наскільки широким є ком’юніті й наскільки важко отримати ту чи іншу допомогу з можливими проблемами?
- Наскільки складно масштабується (в залежності від потенційного розвитку й розміру проєкту)?
- Наскільки просто підтримувати версію бібліотеки «свіжою»?
Й, на жаль, Vue, на мою скромну суб’єктивну думку, провалює щонайменше половину цих запитань, як і більшість «нових, хайпових й надзвичайно перспективних» бібліотек.
Тому порадити можу лише наступне — не слухайте нікого, хто каже, що «Angular or React or Vue — це найкраща бібліотека or фреймворк!». Обирайте виключно виходячи з вимог, котрі перед вами стоять, і надійності бібліотек, бо «для кожної задачі — свій інструмент».
76 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів