Javascript-фреймворки: должен остаться только один

Сергей Аверин ( XEK)


Сергей Аверин

Изначально я хотел сделать доклад про сравнение фреймворков, но потом подумал, что закидают помидорами, поэтому доклад — просто адский троллинг, как водится у меня. И он, скорее, не про HighLoad, а про менеджерскую задачу, которая стоит над всем этим делом, включая фронтенд.

Про что же, все-таки, получился доклад? Доклад про то, как выбирали новый фреймворк, почему выбирали, и какие задачи решали.

5b2de888bdf8cba7cbdea4999552b9f2.png

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

А вот теперь настало время очешуительных историй.

Немного про компанию:

77141ba44fc24b2a0ec4a1cf9a695249.png

Acronis — очень большой российский бизнес, который обслуживает 5 млн. пользователей, из которых примерно процентов 10 — это корпоративные клиенты, которым их работы покупают лицензии. Соответственно, компания сама по себе тоже очень большая, у нас 17 разных офисов, RND находятся в трех разных странах, и самый большой RND находится в Москве. Но при этом разработка у нас распределенная, и есть удаленщики, которых я здесь не посчитал.

Масштаб разрабатываемого софта самый разный: есть у нас коробочный софт под Windows, есть коробочный софт с веб-интерфейсом, который мы продаем на предприятия, есть софт, который мы сами продаем и сами внедряем, и это смесь и коробочного и cloud-софта. Есть и cloud-софт, который мы продаем по подписке и домашним пользователям, и корпоративным. Есть даже софт, который мы продаем сначала крупным хостинг-компаниям, которые уже от своего имени продают его под своим брендом их конечным юзерам. И у всего этого дела есть огромное количество веб-интерфейсов. Речь идет именно о веб-продуктах, а не о веб-сайтах, как таковых.

7788c1581a68145163ba970ee3eed2fe.png

Когда я пришел в компанию, стал разбираться, чего же у нас есть, как же все происходит, выяснилось, что внутри компании есть веб-админки разного рода, которые мы делаем сразу на куче разных технологий, начиная от true-фронтенд типа Ext JS или AngularJS, заканчивая сайтами, которые пишутся на Ruby on Rails и в которых jQuery просто переключает страницы или графики.

Перед коллективом стояли такие проблемы.

76722feb19ff36b86b7ef857f3313293.png

Во-первых, технологий много, они все разные, разработчиков из одного отдела в другой не перетащить, не помочь какому-то проекту, потому что Ruby on Rails разработчики, которые пишут на jQuery, про AngularJS ничего не знают. Во-вторых, выяснилось, что существенное количество людей работают part-time — то бэкенд-разработчиками, то фронтенд-разработчиками. У нас, например, есть ребята, которые на PHP пишут, и они же делают на AngularJS сайт, который работает с ним как с бэкендом. Их не очень много, у них проект маленький, и смысл заводить им отдельного фронтенд-разраба отсутствует.

В итоге я насчитал, что у нас есть java-люди, ruby-люди, python-люди и php-люди, которые все делают фронтенд. И при этом в компании нет верстальщика, ни одного. Т.е. есть несколько людей, которые экспертно знают эту область, но обычно они работают кодерами на AngularJS. В итоге в этих проектах совершенно разный стиль кода, совершенно разный стиль комментариев, они по-разному деплоятся, в каком-то месте, с помощью Ruby on Rails мы собираем AngularJS приложения с помощью ruby«шного сборщика. И в итоге — везде разный зоопарк. В каждом отделе зоопарк свой. А еще, короче, получается так, что наш самый флагманский продукт, в котором написан Ext JS, это огромная админка, там сотни экранов, он сейчас построен на базе версии 4, а в 2015-ом году, совсем недавно, зарелизилась уже версия 6 этого фреймворка и, вроде как, мы отстаем аж на 5 лет от версии фреймворка, которую мы используем. Возможно, тоже надо что-то с этим делать.

Пришло, конечно же, начальство и поставило задачу. Задача была дана сверху:

34e982de4817df8d9c8a31849519a4d9.png

Нам нужен толстый клиент на фронтенд-технологиях, который будет общаться со stateless backend API максимально везде, где мы можем это внедрить. Нужна единая библиотека UI-компонентов, единый look and feel для всей компании, потому что мы немножко страдаем от того, что у нас шрифты где-то разные, где-то по пикселям верстка поплыла, и в итоге получается так, что у нас два соседних отдела рисуют какие-то общие элементы для всех наших админок, которые дизайнерами нарисованы одинаково, немножко по-разному — где-то верстка на HTML, где-то верстка запихана в JS-код в каком-то собственном шаблонизаторе. И CSS-слой тоже принципиально разный, где-то он накладывается из трех-четырех файлов поверх друг друга, заскиневая существующих фреймворк.

Очень хочется, чтобы мы, наконец-то, могли подключить нормального верстальщика и нанять разработчика с меньшей зарплатой, который бы отвечал, с одной стороны, за общение с дизайнерами, подготовку дизайнов, а с другой стороны java-скрипторам приносил и говорил: «Вот, они хотят этого, здесь нужно анимировать этот интерфейс…». И при этом мы бы могли нанимать JS-кодеров в проекты не топового уровня. Сейчас у нас работает достаточно много ребят, которые прошли огонь и воду, они знают Java, они знают .Net, и в этом плане для них любой javascript-фреймворк — это не проблема, потому что они, в принципе, очень опытные. Поэтому хочется как-то иметь возможность нанимать не одного из ста, а хотя бы двух из пятидесяти.

И есть такой еще отдельный pqrity. У нас большая часть людей, которая делает фронтенд, это либо бывшие, либо текущие бэкендеры, поэтому очень хочется, чтобы все это было понятно бэкенд-разработчикам. Менеджмент, когда видит код на JS, он начинает говорить, что «Блин, мы ничего не понимаем, все плохо, давайте перепишем», а зачастую все это не так.

a170ef89a3f1412f33202704a9607c5c.png

Посмотрели, что же, на самом деле, мы имеем в компании. Оказалось, что у нас есть партнерский продукт, который написан на Dojo. Для него мы пишем плагины на Dojo, это очень древний фреймворк, очень особенный, он работает как компонентная модель. Это не совсем MVS, но с этим мы решили ничего не делать, потому что мы не можем никакой другой фреймворк использовать, иначе мы не сможем с этой партнеркой работать.

Для сайта, собственно, у нас почти нет никакой динамики. Нам важно, чтобы его индексировали поисковики, и нам важно, чтобы он работал быстро. Нам там Javascript особо не нужен. Поэтому какой-то суперфреймворк для него, вообще, не уперся. Это задача, которую мы не должны решать.

Из оставшегося, из чего на самом деле делаются админки, это Angular JS первой версии, это Ruby on Rails, плюс генерирующие страницы на бэкенде, плюс какие-то jQuery-дописки, которые делают некую динамику. И большая часть продуктов написана на ExtJS 4. Это очень высокоуровневые фреймворки, которые больше всего напоминают .Net или CuTI, на котором большая часть продуктов компании — серьезных и взрослых — написана.

18ec5ec0dfd781f089bca635eda8530f.png

Полез я разбираться, что же такое этот ExtJS. Оказалось, что это огромная махина, локомотив кода. На главной странице 395 классов этого фреймворка описаны.

bc9492130064893977a56974ecdfc989.png

Каждый класс имеет очень глубокое дерево наследования, т.е. в этом плане очень сильно слизано с того, как строится CuTI, .Net и прочие MVC фреймворки, которые работают где-то в винде или в линуксе под десктоп. В итоге получается, что зачастую код, который ты дебажишь, находится где-нибудь на три уровня выше, чем тебе сейчас надо. Разобраться в этом действительно сложно.

Класс Ext.panel:

5ff2b3b7ed399c64e132ae759a5c6c92.png

Это только методы из него. Там еще столько же событий, столько же свойств разных. Совершенно понятно, что ни один разработчик запомнить все эти методы не может. Поэтому постоянно приходится работать с документацией, чтобы понять, как сделать даже самую простую штуку, потому что размер какого-нибудь компонента… Там есть аж три разных метода, и они три разных размера возвращают — каждый по-своему.

9fab8849a56fd96c3e4f02a998ecad37.png

В итоге мне было печально, очень. Я первое время вообще ничего не понимал, смотрел на все это дело и задавал себе такой вопрос: «Господи, зачем же вы все это написали?».

Индексная страница флагманского приложения была мною напечатана на листах А0 и занимала 51 лист шрифтом 6.

218b550a2ffd83c9d78a6a8ae63ad605.png

Вот увеличенное это дело:

67a96677f4f9da97ee6153ba543e3276.png

Это DOM-дерево, в нем было 32 с чем-то тысяч нод. Это просто индексная страница, сгенерированная фреймворком, т.е. мы еще ни на одну кнопку не нажали. Это просто загрузилась страница и все отрисовала. Стало очевидно, что, блин, что-то тут странное происходит, явно есть какая-то фигня с этим.

615f59cf124f48c9adb9b5a5a5414d17.png

Полезли смотреть, как же делается UI в этом фреймворке. Оказалось, что пользователь получает сразу библиотеку UI компонентов, которая скинится CSS«ом. Ты должен CSS«ом дописать поверх, тогда получишь свой кастомный скин. И много компонентов, которых не было, их пришлось реализовать с нуля. В итоге зачастую, не везде, но очень часто, я натыкался на что-нибудь такое. Это javascript класс, который с одной стороны UI компонент, но с другой, зачастую видно, что в нем аж три разных сущности смешивается — это javascript-код, html-код и это какие-то очень странные директивы местного шаблонизатора, эти xindex, xcount или этот tipeof values string, запиханные в фигурные, квадратные скобки…

Конечно, разобраться в этом всем очень трудно и поддерживать это все очень трудно, а еще выяснилось, что зачастую компоненты, когда наследуются друг от друга, они умеют кусочки этого шаблона вырезать и их перескинивать по кусочкам. Т.е. есть таблица, у нее есть шаблон ячейки, есть шаблон заголовка, и существуют компоненты, которые два-три раза друг от друга наследуются. В одном что-то меняется, и все ломается. Или выходит новая версия фреймворка, а компоненты, которые поверх этого сделаны, перестают работать.

741747fbd7c658ec98ebacc0e4630c66.png

Дальше выяснилось, что это единственный видимый мною фреймворк, в котором есть такая шутка, как layouting. Полезли посмотреть, что же, как же, почему, откуда эти теги? Оказалось, что при изменении размеров окна, при изменении размеров какого-то компонента фреймворк так же, как это на декстопе, вычисляет сам размер блоков и вставляет их inline CSS«ом. Типа left, right, width, height. Мало того, там очень хитрый алгоритм, который берет текст и оценивает его размеры, запихивает его в невидимый div, и смотрит, какого размера этот div получился при заданной ширине. И так он мимикрирует под функции оценки размеров текста, сколько этот текст займет в этом блоке, и вычисляет эти блоки. А потом выяснилось, что алгоритм этот, еще и древовидный, т.е. он по 6–7 проходов делает, потому что он, как браузер, тоже натыкается на какой-то компонент, который не влазит, начинает его увеличивать и родительский компонент тоже пересчитывать. В итоге, начинаешь двигать правую страницу браузера и четко видишь затупы его про изменения размера этого фреймворка. Но, с другой стороны, это дает тебе типа бенефис, что во всех браузерах это работает абсолютно одинаково, и про проблемы совместимости между браузерами ты не паришься, потому что максимально тебе этот вопрос закрыли.

6d2595603761263a44f82f34104f48e9.png

Попутно выяснилось, что компонентов очень до фига. И все эти компоненты, каждый из них — это инстанс javascript«ового класса, у которого от трех до пяти уровней наследования, а то и до семи-восьми. Для каждого из них этим волшебным layout«ером оцениваются размеры, они высчитываются и выставляются. У родительских потом высчитываются размеры, и в итоге все это дело генерирует такие веселые штучки — inline css«ы, которые вставляются прямо в div«ы этих компонентов, прямо в теги. Поэтому получается такое огромное DOM-дерево, странное.

af819aa69827d97c1778487f321ce2f1.png

В попытке понять, как же этот layouting работает, я наткнулся на такое совершенно страннейшее место.

78b438a1efe53adffc461dc7904f8b11.png

В этот момент мне стало совсем плохо, и я понял, что я не пойму никогда, как это происходит.

a8ad6f0d25d7117bf199e28519db4b60.png

Вы все еще помните, что речь идет о производительности?

f652c80fbbd310c545ecafdecad44fe7.png

Все это дело занимает почти 2 Мб уже в пожатом виде, поэтому совершенно неудивительно, что на каких-то тестах типа «а как это будет работать на мобиле?» выдает веселые времена загрузки. Но, тем не менее, это не такая большая проблема для нас, потому что большинство клиентов корпоративные, и они лезут в админку, когда им нужно либо что-то настроить, т.е. в первую неделю после покупки продукта, либо когда адский пипец, т.е. нужно достать бэкап. И человек, у которого адский пипец, готов подождать 16 секунд, пока, наконец, загрузится админка. Тем более, здесь речь идет о достаточно тонком канале.

19f151182d7dbd3636c39b2bb09475f4.png

С фреймворком понятно, очень сложно и запутано. А сам приложение? Полезли в код приложения.

d41b01623164437c31402dc63e5f0ae0.png

Получается так, что в коде мало комментариев. Какие-то трудные места не объяснены. Все приложения жестко связаны. Вместо одного класса — длинного, на 2,5 тыс. строк, мы имеем дело обычно с тремя-четырьмя классами по 1000 строк, которые очень жестко знают друг про друга и так по кольцу, общаясь, пересылают себе события, меняют состояния внутри себя. И у нас внутри очень большие проблемы с границами между моделью и бизнес-логикой, и между бизнес-логикой и view. Получается так, что у нас есть view-классы, которые называются как-нибудь типа «волшебная реализующая определенный функционал панель», которая и одновременно отрисовывает себя и отрисовывает дочерние компоненты, и еще у нее до фига бизнес-логики, которая умеет переключать какие-то панели внутри, и которая умеет отсылать уведомления, даже зачастую они из view-классов лазят на сервер.

0807639967331c46ee068c87db3bb8d9.png

Поэтому (очень условно) получилось так, что у нас такой не mvc, а M+CV.Т. е. граница между контролем и view очень не определена. Получилось так, что и в моделях есть бизнес-логика, и в контроллерах есть бизнес-логика, и во view есть бизнес-логика, и UI логика, и состояние приложения тоже размазано по всем трем видам классов. Поэтому трудно, например, понять откуда пришли эти данные, или кто является авторитативной точкой, откуда эти данные взялись, и кто хранит на текущий момент самую достоверную копию этих данных, потому что она есть в нескольких частях приложения.

5200ff0c181a1b9ae809408640cf6f50.png

А еще получилось так, что сам фреймворк Ext JS всех очень толкает к архитектуре построенной на publish/subscribe, потому что, в принципе, у него все UI компоненты завязаны на этот механизм, и программисты невольно выбирают то, что предлагает фреймворк. И, вроде как, publish/subscribe — правильный паттерн, но когда ты начинаешь смотреть на приложение, в котором типа 100 страниц, в итоге получается, что ты пытаешься разобраться: «Блин, а к чему же приводит нажатие вот этой кнопки в этой панели, и что же она дергает?».

ddb2bfbbf66161d90c7bb232709eb74a.png

И выясняется, что, во-первых, события могут неявным образом попадать в родительские классы, которые, в свою очередь, генерят вторичные события, которые попадают в какие-нибудь классы с бизнес-логикой, которые в свою очередь генерят еще события. Затем часть событий игнорируется фреймворком, потом меняется какая-то модель, эта модель генерирует события о том, что «данные во мне поменялись». Появляется еще пяток классов, которые подписаны на ее изменения, и в себе меняют какое-то состояние, которое зависит от состояния этой модели.

В итоге, через три часа ты, наконец, строишь стройную картину и понимаешь, что у всех событий названия очень похожи, и везде есть onclick. И тебе нужно понять, это onclick от этой кнопки, которую ты нажал или onclick от соседней кнопки, которую ты нажал. Потому что фреймворк не запрещает подписку любого компонента на любой. Т.е. ты можешь добраться из кого-нибудь суперконтроллера до кнопки в конкретной панели и подписаться на нее onclick. И это будет просто onclick в кавычках. И такие дела очень трудно дебажить, потому что нет какой-то уникальной селективности этих компонентов. Т.е. там есть свой механизм, называется ComponentQuery, похожий на XPath, в котором можно написать RegEx-запрос, который тебе говорит: «Найди мне там все кнопки, которые вложены в определенную панель с определенным названием». Поэтому, когда ты пытаешься чего-то отрефакторить, очень трудно найти все, вообще, места, где мы реагируем на конкретное событие. Зачастую у нас это даже приводило к циклам событий, когда приложение зависает, потому что постоянно появляются дочерние события, оно начинает их обрабатывать, и этот цикл бесконечен. Пока ты не напишешь какой-нибудь хитрый if типа «если ко мне это событие уже приходило, я его не обрабатываю», то мы дальше его не обрабатываем. Т.е. речь идет о запутанной архитектуре.

Все нормально.

3501b3cce5b140e6ecc52a1113ab103b.png

А теперь у меня большой вопрос. В коде крупных приложений с жесткой связанностью между логикой view, между размазанностью функционала по разным классам и очень плохим разграничением зон ответственности между языками, технологиями и прочим, чего обычно нет?

6c2fd3ed4772f7b2823349308c8dd164.png

Вот так вот получилось. Причем непонятно, на самом деле, почему получилось. Потому что, на мой взгляд, могло быть лучше. Но, короче, объекты Arrays мы проверили, остальное — как получится. И вечная эта история про то, что когда ты начинаешь писать тесты, ты многое узнаешь про свое приложение, что на самом деле ни фига не надо было делать такое количество связей, потому что замокать 15 объектов ради вызова одной функции, очень геморройно. И в этом плане получили тесты «давай, до свидания».

Какие выводы? Как бы, вот такие, конечно, выводы…

88597448e2b7bc1a5251af4a8d1d8f98.png

Но на самом деле, настоящие выводы в чем?

ee6fcc48cf78fd1456112701e7e93f70.png

Что фреймворк очень сложный для понимания разработчиков, особенно разработчиков, которые до этого не защищали докторскую диссертацию по Java. Во-вторых, код, который получился, очень запутанный. В нем очень много связей, все классы друг про друга знают, и события, которые появляются, никем не контролируются, и это приводит к фейерверко-образным взрывам изменения стейтов приложения, когда 15 мест подписаны на какой-нибудь стейт, события потом генерируют свои дочерние события, и еще какие-нибудь другие места начинают обрабатывать эти события… В этом плане фреймворк жутко асинхронный, и эта асинхронность взрывает мозг. Получается так, что компоненты правят люди, которые понимают одновременно язык шаблонизатора, намешанный JS-код, html, CSS и все это в одном файле. Обычного верстальщика нанять? Я не знаю… Сколько сейчас получает верстальщик? За 40–60 тыс. невозможно найти верстальщика и посадить его за простую рутинную работу «в этой панели убери эту кнопку», потому что сборка всего UI происходит в JS-коде методом созданий инстансов JS-классов. Т.е. ты описываешь большое дерево, какую кнопку в какую панель вложить, какие параметры передать, какие ссылки, на какие события потом подписаться.

Соответственно, главный мой вопрос был — виноват ли в этом фреймворк? На самом деле, конечно, виноват. Частично. Потому что он подталкивает тебя к publish/subscribe, потому что он подталкивает тебя к такому mvс, который они сами делают, псевдо mvc. Потому что в нем нет dependency injection из коробки, потому что он не говорит тебе, как тестировать это все дело…

b3a5ec9b4c4753e35c375a557d63725b.png

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

Нужно четкое разделение работы по людям: одни люди делают верстку, другие люди в верстку вдыхают что-то, третьи люди ответственны за работу с API, четвертые– с дизайнерами. Нужно разделение языков и технологий, желательно по-файлово, чтобы можно было каким-то людям, которые не разбираются в JS-коде давать какие-то вторичные задачи, например, переводы, т.е. локализацию на нужный язык.

Конечно, хочется менее связанную архитектуру, потому что тестировать это нереально, написать тесты для этого очень трудно. Поэтому хочется какой-то изоляции. Понятные микрокомпоненты, каждый из которых ответственен за свой маленький кусочек. И проще UI слой.

43df044c00bfb04d82b906aa1275fd43.png

К чему главный посыл всей этой презентации (а это самый главный слайд) — что все ваши песни про производительность фронтенда превращаются в лапшевидный код, отсутствие стандартов и «мы наняли нового чувака, а он четыре месяца правит одну багу». Давайте сначала улучшим производительность разработчиков, дадим им в руки нормальные, а не гнутые инструменты, и они сделают код, который будет намного лучше работать, потому что эти задачи были решены на уровне фундамента. Т.е. мы будем стоять на плечах гигантов.

Соответственно, решили, что нужно что-то как-то менять, нужно чего-то выбирать, конечно, нужно как-то независимо и непредвзято оценить все это дело.

Конечно, я полез в Интернет. Ну, а что делать? Тут все бы полезли в Интернет.

d6dc1864fd7477bf4f87245629198d2c.png

Выяснилось, что за пять лет, пока я управлял и работал на PHP, в мире JS многое поменялось, в этом плане пришлось многое выучить заново.

edabf20b88277cf9e1d2e8f70e4b69be.png

И эти тысячи фреймворков, каждый из которых как две капли воды зачастую похож на друг друга, особенно во flux фреймворках — это прямо «придумай свое название точка JS». И из этого ада там, где Google Web Toolkit уже давно умер, надо как-то выбрать. Блин, что делать? Конечно, надо было что-то подумать, как бы посмотреть, как другие где-то что-то выбирают в Интернете, залезть и где-то спереть результат.

В итоге, выяснилось, что спереть результат у меня не получится ни фига, придется делать честную оценку, потому что они все очень разные. Поэтому для начальства был сделана целая большая серьезная презентация, в которой была попытка реально и непредвзято оценить, какими же, на самом деле, фреймворками пользуются разного рода компании и сайты.

dd2d76a533b31d295a92ddd16048a88c.png

Именно про компании и сайты я оттуда слайды вырезал, остаются именно честные цифры. Это количество строчек кода, написанных вообще с момента появления Github на разных технологиях. Плюс-минус.

ba348d7e34cb33cbaf1cfb7bb8d34561.png

Это слайд рассказывает о том, сколько было докладов по каким технологиям на каких крупных конференциях, посвященных именно фронту, в 2015 году за рубежом.

И везде картинка разная.

36e55a2badb5f7c57614050917349393.png

На этой картинке тренд популярности запросов в гугле. Их тут несколько… Здесь, если присмотреться, видно, что все технологии идут на самом деле на спад, кроме React js и Angular js.

8651a5cc5a0a138bb3cb10a019fc3575.png

Если взять какие-нибудь старые более-менее фреймворки дипа Dojo, Yahoo ui и нашего любимого Ext js, то тоже все идет на спад. В этом плане с React js и Angular js никто не поборется, потому что это единственное, что идет вверх.

Мы дальше смотрели такое исследование, где 2,5 тысячи разработчиков было опрошено, каждый из которых выбрал одну технологию.

8f0eee710fe72b1083ff0a2d317ecbde.png

Это американская компания, которая делает и продает cloud IDE. Получилась вот такая картина, совершенно другая. Т.е. те разработчики, которые поддерживают продукты, у них еще силен, например, Backbone, который по большому счету устарел, но, тем не менее, есть много проектов на нем, которые еще доделывают.

69eb64eb61349a3f4c32045287d73115.png

А это уже российский рынок. Мы пытались оценить, кого же мы можем нанять, потому что очевидно, что мы не в космосе работаем, и нам нужно делать продукты в компании, продуктов много и планов — громадье, поэтому кого-то надо нанять. Здесь, вообще, картина другая. Выяснилось, что так или иначе с какой-то из версий ExtJS (поскольку он достаточно долог) и с какой-то из версий Backbone (поскольку он тоже родился в 2008 году) так или иначе кто-то имел дело. Т.е. это никакой гарантии не дает на то, что этот человек прямо сейчас готов чего-то делать realtime на этом фреймворке, но, тем не менее, выяснилось, что среди растущих технологий React js и Angular js, появились внезапно Backbone и ExtJS, причем вакансии по ним есть, и их достаточно много. Вакансий по Backbone больше, чем со знанием React. Вот какая удивительная картина на российском рынке.

49e16eb6f41b33df0dd6ff88bfbcd631.png

В итоге мы все эти исследования максимально скрестили и оставили то, что нам интересно. Туда добавили еще Dojo и добавили ExtJS 6, на который изначально хотели переходить. А Dojo, потому что его используют Parallels, с которым мы тесно интегрируемся, и на котором у них кое-что написано.

8f590094a78170bf373c11dd9543498d.png

Здесь нагло было вырезано пять слайдов. Я не буду рассказывать про то, почему нам это все не подошло, потому что рассказ там очень скучный. Я не буду на этом останавливаться. Если вы полезете изучать для себя, то сформируете и какую-то картину для себя. Мы оценивали, исходя из наших задач. Одна из задач была в том, что технология должна быть более-менее встраиваемой по частям в существующий код, т.е. нам нужен не монолитный фреймворк, а, скорее, набор каких-то методик и библиотек, которые мы можем потихоньку внести. В этом плане оказалось, что Knockout — это вообще не фреймворк, а UI библиотека, Dojo — это просто мамонт, а ExtJS 6, хоть и привносит новую архитектуру, но на самом деле мало чем отличается от ExtJS 4. Т.е. там появилась поддержка какая-то, более хорошая работа с мобильными устройствами, но концепция не поменялась. Там чуть лучше стала архитектура, но для нас, как мы оценили, примерно одинаковая, что мы на ExtJS 6 будем переписывать честно архитектуру, прямо так, как они предлагают, что мы будем на любом другом фреймворке переделывать — примерно одинаково по затратам. В итоге отказались, потому что все тот же UI слой, все тот же publish/subscribe.

Истинных кандидатов, на самом деле, было только два.

7364129cf5217e6b2aae1ec9d42fdccc.png

Первый — AngularJS — по понятным причинам, который еще очень активно отстаивали и несколько отделов компании, и некоторые внешние советчики. Но с ним возникла очень интересная дилемма. С одной стороны, это выглядело действительно очень хорошим решением, с другой стороны, я видел очень много статей на Хабре и, вообще, в англоязычном Интернете, в которых обсуждают некие допущенные при его проектировке именно концептуальные ошибки, приводящие к тому, что все, как бы, очень круто, но мы запутались.

Наше собственное зрение на это дело такое, что если брать версию 1, на которой у нас в компании есть два проекта, и посидеть-покурить исходники, то у этого фреймворка реально хорошая модульность разделения на отдельные кусочки, каждый из которых делает свой маленький функционал — вот это очень полезно и хорошо. Но нет единого стиля раскладки по файлам, нет единого стиля именования каких-то переменных и единого стиля форматирования кода, т.е. это та вещь, которую хотелось бы как-то получить до кучи с фреймворком, но ни фига не получится. И со временем этот стиль раскладки меняется. Также от себя добавлю, что зачастую находятся места в коде, которые по-хорошему должны бы быть отдельными классами, но почему-то их в виде объекта с функциями туда пихают. Трудно дебажить, очень много разной хитрой «магии», очень сложно интегрировать с какими-то новыми технологиями, потому что стандарты абсолютно все свои… Как собирать это дело — тоже не очень понятно, однако этот вопрос можно решить. Но самая беда, что начальству я это продать не мог, потому что мы все говорили, что «Ребята, они делают новую версию, и код будет несовместим». Что делать дальше — непонятно.

39174c26a1858426459c4186c5036e25.png

ОK, полезли смотреть версию 2. Версия 2 прямо вообще отлично выглядит, как то, что нужно, такой бэкендно-ориентированный подход, все разложено по полочкам, хороший очень синтаксис на TypeScript — то, что надо. Но, блин, нет шансов на релиз, вообще, нет. Я, самое главное, не понимаю, эта супер-мега гугл корпорация, она давно работает с python… Пример того, как python переходит с версии 2 на 3 — это просто хрестоматийный пример того, как надо это делать. Надо поддерживать синтаксис старой версии, надо быть backword compatible. А здесь какой-то адский ад просто. Он будет несовместим. «Мы сейчас что-то новое делаем. Вот альфа-версия, для нее ни хрена нет документации. Когда мы запустимся — непонятно и, самое главное, у нас во всех трех языках еще разный синтаксис». Ну, зашибись, блин!

Это что, это решение? Вы извините меня, это локомотив фронтенд-разработки, это, типа, самый крутой фреймворк, который все страшно любят? И что мне делать с админками, которые сейчас пишет четыре человека на AngularJS? Прийти и сказать: «Ребята, вы знаете, мы просто садимся и все переписываем. У нас ничего не станет лучше, мы просто переезжаем на новую версию». — «А зачем переезжаем?» — «Ну, потому что старую забросили». А они меня, конечно же, спросят: «Слушай, а есть такая штука, как в python, типа, «by 2 to 3». Т.е. давай натравим какой-то парсер, и он нам сейчас переформатирует код, и оно хоть как-то начнет собираться». Ты говоришь: «Извините, нет. Причем, мало того, что нет, оно сейчас еще все поменяется. Завтра у нас будет другой синтаксис». И это продать тоже никому невозможно. Совет директоров на меня посмотрит и уволит на завтра и все. Т.е. что делать с AngularJS — непонятно.

47496111d026d0b6cec5247a038e1c02.png

Мы дальше стали смотреть, и было второе решение — это React JS, который сделал Facebook. C удивлением оказалось, что это не фреймворк, а всего лишь UI библиотека. У нее очень четкая понятная структурность, четко понятно, что это единый data flow, который только получает данные, только их отрисовывает. Каждый компонент изолирован, у каждого компонента есть декларация, чего он получает на вход, чего он в итоге отрисовывает, чего внутри он хранит в виде промежуточного стейта. Нет, вообще, каких-то магических фильтров и прочей фигни, которую надо откуда-то подключать, учить и знать, как работает… В этом плане все максимально предсказуемо и это очень классно. Мне понравилось, что есть очень простая возможность тюнинга производительности — четко понятно, как она работает, четко понятно, как ее использовать, ничего суперсложного в этом нет. Есть даже серверный рендеринг, который нам не нужен, но круто, что он есть.

8fdc8bd7d60f21d3d46fa36b861a44c3.png

До кучи к этому шла архитектура Flux, которую активно двигает Facebook. Мы посмотрели на все это дело, у нас, как бы, был so-so. С одной стороны то, что one-way data flow, и то, что синхронная обработка как у стейт-машины, где четко понятно определенное состояние приложения — это супер. Но как приложение делится на независимые блоки и как разделить его, как в Angular JS, на какие-то отдельные сущности, не очень понятно. Потому что, мне кажется, там явно есть антипаттерны в виде т

© Habrahabr.ru