Привет, читатели Хабра. Решил написать пост о том как мой выбор вэб фреймворкабиблиотеки пал именно на React. Это лично моё субъективное мнение и найдутся многие, кто с этим не согласен.
Программировать я начал в 2006 году. Нет, конечно ещё году в 1999, помню, игрался с Delphi, ну там аналоговые часы, блокнот, наподобие тому, что в Винде, видеоплейер с плейлистом (тогда кстати во встроенном в систему плейлиста не было). В 2006 году в израильской армии начал строить веб-систему, которая автоматически распределяла солдат в зависимости от большого числа различных показателей. И естественно на тот момент это был ASP.NET с C#. Тогда ещё он не назывался Web Forms.
Вэб технологии менялись, каждый раз производя революцию в моём мозгу: ASP.NET MVC, JQUERY, AngularJS. И вот последний совершил наиболее серьёзное влияние, ибо только тогда я узнал, что возможно построить вэб аппликацию без серверных вьюшек (aspx, cshtml). А плюс к этому я узнал про Node JS ("Что? JavaScript на сервере? Не верю!"). И тогда я принял решение, в которое бы не поверил раньше: оставить C#, которому был "предан" в течение 9 лет, и полностью погрузиться в JavaScript.
Мне очень нравилось писать на новом вэб фреймворке от Google. Очень быстро получались вещи, для которых раньше мне нужно было сильно постараться с jQuery. SPA это был уже стандарт, ниже которого, казалось, стыдно опускаться вэб разработчику.
Писать на angularjs было одно удовольствие. Не было cli, но создать и сконфигурировать новый рабочий проект с 0 можно было минут за 20. На чистом es5, без babel, traceur, wepback (последнего ещё и не существовало вроде бы). Тогда уже и появлялись слухи о скором появлении angular 2 и его абсолютной несовместимости с первой версией. Google поставили разработчиков в сложное положение: с одной стороны руки чесались попереписывать системы с ASP.NET на новый классный фреймворк. С другой стороны вопрос: это вот мы сейчас перепишем, а потом снова переписывать?
Лично я, когда увидел примеры кода на angular 2, очень надеялся, что такое не взлетит. Я недоумевал зачем они всё на столько усложнили. И с каждым meetup'ом, посвящённом новой версии, на котором мне пришлось побывать, желание переходить на вторую версию было всё меньше и меньше.
И вот с release candidate было решено начать создавать новый проект (а по сути переписывать старый немного по-другому) уже используя angular 2. Я даже не говорю о том, что с обновлением этих release candidate приходилось переписывать большие участки кода. На angular 2 было на столько не комфортно писать, что я чувствовал боль, когда переписывал код. Поднял вопрос по поводу того, стоит ли это делать или же может продолжить писать на angular 1. Но несмотря на то, что до сих пор было много проблем и непонятных багов (помню, что описание ошибки в консоле было очень детальное... Вот только абсолютно не о том, где на самом деле была ошибка), куча непонятной функциональности (помню много времени взяло, пока мы поняли, что за forChild в описании модуля), все понимали, что оставаться на первой версии нельзя, нужно было идти вперёд. То есть переход на новый фреймворк был уже не потому что мы так хотели, а потому что Google нас вынуждали, выбора не было. Тогда ещё у меня пронеслась в голове мысль, что лучше бы уже на самом деле перейти на React. Но мысль эту я отогнал, ибо чувствовал, что следовать нужно за Google ).
Со временем я конечно привык. Привык и к идее того, что Observable - это новый Promise. Код пытался писать так, чтобы везде они были, как можно больше async в шаблоне. А большое количество операторов в цепочке (это ещё до pipe) заставляло думать, что код выглядит очень круто.
Со временем я смотрел на этот код и в голове представлял, как бы это всё выглядело с Promise и понимал, что так код был бы на много понятнее и читаем. Но я себя уверял в том, что Promise - старьё и следовал за тенденциями.
А тенденции были такие, что вдруг оказалось, что код нужно писать с помощью ngrx и вообще все компоненты делать OnPush. Я несколько раз смотрел на пример todo списка через ngrx с недоумением: "ЗАЧЕМ??". Ведь всё же было так просто и удобно. Я понимал, что ничего не осталось от того самого angularjs, на котором я начал писать не потому, что так надо, а потому что я в него просто влюбился.
Повсеместное использование rxjs где надо и где не надо. Со временем я уже не наблюдал в коде ни объектов данных, ни функциональной логики. В глазах просто мельтешил набор операторов типа: mergeMap, switchMap, mergeAll, switchAll, combineLatest, combineLatestAll... ну, Вы меня понимаете. Мне кажется, что все остальные, кто писал этот код, сами не понимали, что там происходит, но продолжали возводить эти "сочинения" на пьедестал эталона идеального кода.
А http запросы? Ну почему, если я хочу принести данные и вызываю функцию getData, я должен делать subscribe? Подписываться на что? Это же не websockets. Обратился к серверу - принёс данные. И я даже не говорю о том сколько раз бывало, что вызываешь функцию, а данные не приходят. И думаешь, гадаешь в чём же дело? А дело именно в отсутствии subscribe. getData теперь Observable возвращает. Ну и вообще по-новому теперь пишешь так
this.data$ = getData()
А потом в самом шаблоне
{{data$ | async}}
И вот это да, всё работает! А потом чешешь затылок и думаешь: и как теперь принести вторую страницу? Ну или просто обновить данные? Снова вызывать getData? Так зачем? Оно же не запускает запрос, а возвращает Observable, и он то у нас уже есть в руках. Вроде уже не получается. Значит нужен subscribe? И тут ещё многие стараются делать unsubscribe запросу в onDestroy. Видимо не понимают, что observable "заканчивается" после запроса. Но как меня уверял приверженец http запросов на observables, что когда пользователь, например зашёл на страницу и запрос застрял, то он может нажать назад (о как) и запрос... прекращается! Ну да, это конечно оправданный сценарий использования observable вместо promise (которые кстати тоже можно abort'ить на минуточку)
Я почувствовал будто Google меня обманули. Хитро и пошагово подменили мне то, что когда-то понравилось, на что-то другое, что они посчитали правильным. Но я продолжал писать на angular, потому что верил в этот путь, отгоняя "грешные мысли".
И тут мой team leader, перейдя в новую фирму, через несколько месяцев предложил присоединиться к нему. Аргументов было 3 (не считая незначительное повышение зарплаты, которое мне и так предлагали, на нынешнем месте, чтобы я остался): ближе к дому (примерно минус час в день на дорогу), наконец-то получить nodejs на бэке (у нас были попытки ввести его, но не нашли уважительной причины для этого) и... Попробовать React. Я подумал, посовещался с людьми, которые пробовали и то и другое и все однозначно предпочитали react, сравнил популярность фреймворков (npmtrends, популярные сайты на react/angular). И решился на ответственный шаг в своей жизни: кинулся с головой в мир нового.
И тогда я понял чего мне так не хватало в новом angular: простоты. Всё элегантно и легко. Код был похож на JavaScript больше, чем в случае с angular. Чувствовалось больше свободы, возможности выбора различных библиотек, стилизации компонентов, выбора стэйт менеджмента, в конце концов.
Да, по началу было не привычно писать html внутри JavaScript, пока я не понял, что это уже не html, а JSX. Неудобно было и то, что теперь, когда я к примеру строил компоненту дерева, я не мог как раньше свернуть/развернуть узел:
node.expanded = !node.expanded
Но в чём-то это и правильнее, когда речь идёт не о быстром примере, а о готовой функциональности.
Сейчас я пишу проекты на реакт. Благодаря функциональным компонентам и хукам код выглядит очень минималистично и максимально читаемо, на сколько это возможно. В то же время приходиться иногда возвращаться к старым проектам, написанным на ангуляре. И код написан максимально не читаемо (но это уже зависит от криворукости тех, кто этот код писал до моего прихода в фирму. Просто на мой взгляд современные практики ангуляра, дали возможность, "криворукому" написать всё таким образом). Попытки разбираться в этом коде и добавлять туда функциональности доставляют мне боль
Подводя итог, почему не ангуляр по моему мнению:
Google поначалу сделали что-то одно, чем привлекли внимание и сердца веб-программистов. А потом дали совершенно другое, пользуясь названием и репутацией полюбившейся платформы
Повсеместное использование rxjs там где он вообще не подходит
С каждой версией рассказывают об улучшении производительности. Но видимо это достигается тем, что по умолчанию теперь OnPush (эх, где мой 2 way data-binding из 2014)
Ощущение, что загружается в браузер огромная махина
В качестве UI библиотеки толкают Material с элементами на пол-экрана (Мне нравится material design на android, но не в вэбе же). За то, понимаешь ли, всё, что нужно для разарботки, на одном сайте и ходить больше никуда не надо, всё-всё там, на angular.io.
После того как Google убили AngularJS (и не только его) гарантировать вечную жизнь Angular они вряд ли могут.
Нет свободы выбора. Google как бы говорят: мы сами знаем, что Вам надо и как Вам лучше. Хотя многие (поклонники ангуляра) отсутствие этой свободы представляют, как отсутствие "Дикого Запада". Будто бы держать программиста в рамках выровняет ему руки
Ну и конечно в данном случае на меня повлиял невероятный скачок популярности реакта. Хотя этот фактор скорее дополнительный. Иначе бы я пользовался redux
А вообще у меня немало коллег, которые обожают angular, ngrx, считают этот путь единственным и не повторимым и самым лучшим и с моим мнением не согласны. Поэтому выбирайте то, что Вам нравится, что удобно. Главное не забывать, что скорее всего Ваш код будет читать ещё кто-то и возможно Вы не хотите, чтобы Вам в этот момент икалось ;-)