Wrike переходит с Dart на новый стек. Какой?

    В первой части вы узнали, что по веским причинам мы были вынуждены выбрать новый технический стек для дальнейшего развития нашего продукта. Пора перейти к самому интересному: что же мы будем использовать вместо Dart? 

    Язык

    Основными критериями, которыми мы руководствуемся при выборе языка, являются, как и пять лет назад:

    • Строгая типизация, которая помогает большим (и даже огромным) командам более эффективно работать над единой кодовой базой.

    • Развитие и поддержка сообщества.

    • Наличие готовых решений, если не в виде библиотек, то хотя бы в виде паттернов, best practices и описанных подходов. Мы бы не хотели переизобретать велосипед.

    • Наличие систем сборки, которые будут работать с большими объёмами. Как показала практика, не всё, что хорошо работает для трёх-пяти разработчиков, хорошо скейлится до 100+.

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

    И, если анализировать рынок именно языков, то получится, что выбор-то и не такой большой. Dart, TypeScript, JavaScript с различными линтерами и всё. Более «маргинальным» выбором могут быть Clojure, Reason или даже Kotlin, но почти все они не отвечают какому-то одному из наших требований. А это значит, что в качестве языка разработки, кроме Dart, мы можем выбрать только TypeScript.

    Какой из фреймворков выбрать?

    Фреймворк

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

    Основные критерии, которые мы предъявляли к фреймворку, похожи на те, что мы использовали для выбора языка:

    • Поддержка сообщества.

    • Минимальные изменения в текущей инфраструктуре и подходах, чтобы цена переезда не превысила пользу от переезда.

    • Перформанс в большом приложении. Причём не только в рендеринге, но и в скорости разработки.

    Рассмотрим подробнее критерии, которые мы предъявляли к фреймворку, с примерами из Angular и React. Именно их мы брали в качестве основных претендентов на использование.

    Организация кода и сборка

    Под организацией кода подразумевается разделение кода по репозиториям и пакетам. 

    Так как за эти годы мы написали хорошо настроенную систему сборки, да и само приложение часто не «переваривается» стандартными средствами, от фреймворка нам нужна была максимальная гибкость и производительность. Код на Dart мы организуем в мульти-репозиторий, в котором сейчас уже больше 350 библиотек. Именно на такой подход настроены все наши инструменты сборки, и переход на mono-repo может стоить достаточно дорого.

    NB: В Dart мы используем пакетный менеджер pub с публикацией исходного кода пакетов. Это позволяет очевидным образом использовать мульти-репозиторий и уметь изменять сразу несколько пакетов: достаточно прописать оверрайды на git-ветку и получить доступ к исходникам.

    Один из главнейших плюсов React для нас здесь в том, что ему ничего не нужно знать о твоем flow разработки, фреймворк можно настроить более-менее как угодно.

    Angular, в свою очередь, больше похож на enterprise систему — много что дает из коробки (angular cli), но конфигурируется это плохо — надо либо брать Angular flow, или не брать этот фреймворк вовсе.

    React позволяет нам остаться на мульти-репозитории и получить DevExp + CI/CD, аналогичные текущим. Для Angular в его текущем состоянии реалистичным выглядит только моно-репозиторий. 

    Data flow

    Под data flow подразумевается модель организации (потока) данных в приложении. Это определяет абстракции, с которым разработчик будет сталкиваться каждый день.

    В React и Angular в обоих случаях ключевой абстракцией является компонент, у которого есть свои входные параметры (props/inputs) и собственное состояние. Перерисовка идет сверху вниз по дереву компонентов. Основное отличие — в React перерисовка идет от узла с новым состоянием вниз, в Angular — от рута до компонентов, для которых (явно или нет) вызван markForCheck, а затем вниз.

    Из-за того, что механизм change detection в Angular никуда не девается и выполняется от рутового компонента, перерисовка изменений в отдельных компонентах выполняется не так быстро, как в React. Это закрывает целый ряд возможностей, которые предоставляет React — такие как controlled <input>.

    В React нет и никогда не было зон — глобального контекста, который влияет на работу всего приложения. Это приводит к тому, что требуется меньше времени на отладку и профилирование приложения, т.к. проблемы «локальны» для определенного поддерева компонентов. Тем не менее, Angular для TS позволяет отказываться от использования zone.js, но эта возможность до сих пор считается экспериментальной.

    Композиция компонентов

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

    React значительно обходит Angular по возможностям композиции компонентов. Для React отсутствует такие понятия как статичный шаблон или динамическая подгрузка компонентов. Всё по умолчанию «динамичное»: есть возможность передавать одни компоненты в другие, выполнять обработку отрендеренного шаблона кодом. Это позволяет создавать более гибкие компоненты, не зашивать все визуальные элементы и логику внутри одного компонента, разделять компоненты на UI-only и компоненты с логикой, писать и тестировать их в изоляции.

    Итог

    Если подвести итог, Angular даёт достаточно большие возможности «из коробки», но при этом встраивание его в существующую экосистему будет равнозначно переписыванию её с нуля. Это выглядит нецелесообразным. React же достаточно гибок и позволяет переиспользовать элементы нашей инфраструктуры.

    Таким образом, на сегодняшний момент мы приняли решение выбрать связку Typescript + React в качестве основных инструментов разработки клиентской части нашего приложения.

    План миграции

    Language agnosticism

    Множество актуальных крупных фич останутся написанными на Dart еще долгое время, поэтому Dart для нас не превращается в Legacy. Бессмысленно переписывать то, что разрабатывалось годами и нормально работает.

    Но чтобы разработка была эффективной и консистентной на обоих стеках: Dart и TS, мы начинаем действовать по двум направлениям: 

    1. Вовлечение и повышение экспертизы у разработчиков компании. Если инженеры приступят к переходу на TS в начале работы над первой продуктовой разработкой, то от этого пострадает качество и сроки реализуемой фичи. Чтобы этого не произошло, наращивание экспертизы необходимо провести до начала разработки большой фичи.

    2. Развитие и поддержка однотипного инструментария для обоих стеков. Переключение между стеками разработки в рамках одного приложения приводит к тому, что разработчики вынуждены терять время на адаптацию. Чтобы времени терялось меньше, необходимо обеспечить использование инструментов (библиотеки, парадигмы, архитектурный подход и т.п.) максимально похожими на Dart / TS.

    Более детальный план по внедрению работы на TS для нас выглядит следующим образом:

    1. Обеспечить схожий Dev Experience на обоих стеках. Правила линтинга, архитектурный подход для Dart/Angular и TS/React, unit-тестирование, локализация.

    2. Обеспечить единый процесс деплоя для приложения на разных стеках. Процесс доставки приложения до production единый и автоматизированный вне зависимости от стека разработки

    3. Обеспечить консистентный набор библиотек для разработки. Те кейсы, которые закрывались на Dart-стеке с помощью библиотек, так же закрываются на TS-стеке аналогами таких же библиотек. Например, работа с сессиями пользователей, маршрутизация, разные виды транспорта, генерация контрактов и т.п. При этом развитие таких библиотек гарантирует feature parity между реализациями на Dart и TS.

    4. Обеспечить консистентность интерфейса. На одной странице могут оказаться два приложения на разных стеках. Интерфейс обоих приложений должен состоять из одинаковых компонент. Для этого гарантируется поддержка и развитие визуальных компонент с соблюдением feature parity на обоих стеках.

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

    Помимо этого, мы движемся в сторону micro-frontends. Но это большой и сложный вопрос, который можно обсудить в наших будущих статьях.

    Острые вопросы

    Q: Будете ли вы писать на Dart дальше?

    A: Поддержка и развитие существующих фич на Dart продолжится. А также вполне возможно, что некоторые новые фичи тоже будут написаны на Dart, например, те, для которых уже существует большое количество готовых модулей.

    Q: Будете ли вы требовать от новых разработчиков знания Dart?

    A: Мы не делали этого и раньше. Наш подход состоял в обучении и онбординге новых инженеров, так как, стоит признать, Dart-разработчики весьма редки на рынке. С переходом на TypeScript ничего не поменяется, ведь у нас по-прежнему остаётся большое количество кода, написанного на Dart, и разработчики рано или поздно должны будут столкнуться с ним. Так как мы ещё в самом начале пути, то наши инженеры будут сочетать написание кода на Dart и на TypeScript. 

    Q: Почему вы не взяли фреймворк X или Y (Vue, Svelte etc)?

    A: В свете микро-фронтендов выбор фреймворка не является чем-то, что высечено в камне. Однако, делая выбор, нам хотелось иметь максимально пологую кривую обучения. Большое количество наших инженеров уже знали и работали либо с React, либо с Angular, поэтому мы делали наш выбор в основном между этими двумя фреймворками. Но при микро-фронтендной архитектуре ничего не мешает нам в будущем рассмотреть и Vue, и Svelte, и остальные фреймворки.

    Q: Будет ли Wrike в дальнейшем проводить конференцию DartUP?

    A: Несмотря на то, что конференция основана благодаря инициативе и помощи Wrike, сегодня это событие вышло далеко за пределы компании. В России образовалось большое активное сообщество, а сам DartUP в 2020-ом году вышел на международную арену, организовав параллельный поток для англоязычных участников. Мы надеемся, что конференция продолжит жить и развиваться силами сообщества и компаний, не равнодушных к Dart и Flutter (в том числе и нашей), привлекая новых дартизан и флаттеристов со всего мира.

    Заключение

    Из-за причин, описанных выше, Wrike постепенно меняет свой стек для фронтенд разработки и движется в сторону TypeScript + React. Это не значит, что Dart плохой язык! Мы благодарны команде Dart и AngularDart за всё, что они делали и делают. Это было долгое путешествие, и Dart всё ещё остаётся важной частью нашего продукта. Мы желаем языку развиваться и достигать новых высот!

    Подписывайтесь на наши социальные сети, если вам интересны более глубокие технические подробности и вы хотите следить за нашим путешествием в страну TypeScript.

    Wrike
    Мы делаем совместную работу проще

    Комментарии 31

      +5
      Интересно узнать мнение автора по поводу Kotlin? Кажется что он подходит под все пункты из списка про выбор языка.
        +10

        Для web? Очень сомнительно, хотя бы даже в плане сообщества.

          +1

          А какие большие проекты на Kotlin.js вы знаете? Я в курсе только про JetBrains Spaces, а за пределами JB, есть что-то?

        +1

        Спасибо за то что поделились опытом!
        А вы не думали форкнуть Angular CLI, если в нем был основной камень преткновения?

          0
          тоже задавался этим вопросом, вроде как открытый продукт, чего то не хватает возьми и допиши, но это нужно прям программировать, думать, язык развивается нужно и фреймворк держать в актуальном состоянии, а кто это будет делать? у них там дашбордики да панельки…
            0

            Очень много накладных расходов, поддержка большого фреймворка требует безумного количества ресурсов. И при этом это не свободное развитиие, что можно принимать любые решения, а придётся постоянно оглядываться на "большого брата" — Angular (TS)

              0

              У вас же там были/есть специалисты, которые умеют делать маленькие фреймворки, решающие все те же проблемы, что и большие.
              И как я без огромного количества ресурсов справляюсь с большим фреймворком… ума не приложу.

                +2

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

                  0

                  Комьюнити, помогающее с поддержкой, это разве не сказки?

              +1
              Добавлю еще, что мы действительно рассматривали вариант форка, но при замерах производительности TS ангуляра стало понятно, что мы ничего особо не выигрываем, синтаксис оказался не настолько схож, чтобы разработчики могли быстро переключиться, что в итоге привело к тому, что плюсы не перевесили минусы.
              –7
              image
                +2
                Женя, а какая судьба теперь у DartUP?
                  0
                  Q: Будет ли Wrike в дальнейшем проводить конференцию DartUP?

                  A: Несмотря на то, что конференция основана благодаря инициативе и помощи Wrike, сегодня это событие вышло далеко за пределы компании. В России образовалось большое активное сообщество, а сам DartUP в 2020-ом году вышел на международную арену, организовав параллельный поток для англоязычных участников. Мы надеемся, что конференция продолжит жить и развиваться силами сообщества и компаний, не равнодушных к Dart и Flutter (в том числе и нашей), привлекая новых дартизан и флаттеристов со всего мира.
                    +1

                    Да, энтузиасты Дарта есть и в компании и снаружи, так что шоу будет продолжаться!

                    • НЛО прилетело и опубликовало эту надпись здесь
                  +3

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

                    +1
                    Будем делиться в статьях и докладах.
                    –1

                    Жаль, что некомпетентность+имя на слуху убивает здравое отношение к angular

                      0

                      Помню в ~2014 как раз чуть не попал в вашу компанию, с переходом на Dart. Возможно к лучшему, а может и нет, но менять город не хотелось.
                      Недавно изучал что там в этом мире сейчас… и, судя по тому что увидел, по сути Dart теперь язык для Flutter. Бекендовые фреймворки на Dart мертвы, недавно тут Aqueduct официально закрылся (https://stablekernel.com/article/announcing-the-sunsetting-of-aqueduct-our-open-source-server-side-framework-in-googles-dart/ ). Я конечно так, по большей части мимо проходил, но вижу что судьба Dart очень не линейна.


                      Так или иначе — TypeScript — хороший выбор, React тоже, желаю вам успехов.

                        –3

                        Инструмент надо выбирать под задачу, и разговоры о SSR и SEO на фоне вашей отлично работающей годами Wrike выглядят непонятными.
                        Вас купила большая кампания и насала внедрение своих практик. Тайпскрипт это 2 шага назад, по сравнению с dart вместе с flutter вы теряете any smartdisplay клиентов ваших будущих сервисов, которым точно плевать на SEO

                          +1
                          Тайпскрипт это 2 шага назад, по сравнению с dart вместе с flutter
                          Так не работает же. Ну нельзя Flutter for Web использовать в нашем случае. Не предназначен он для этого. И что прикажете делать?
                            0
                            зафигачить свой фреймворк с блекджеком и ночными бабочками…
                          +2
                          Расскажите как-нибудь какие еще технологии затащите в проекты, я про экосистему вокруг ts+react, было бы интересно почитать, что и почему вы выберите
                            +1

                            Конечно напишем!

                            0

                            Интересно, dart с ts как-то можно подружить? Вроде и то, и другое в js компилируется.

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

                              Вот как раз это было б интересно!

                              Вопрос. А почему не разделить сразу бек и фронт? Будет бОльшая гибкость в языках\стеках технологий. Как по мне — TS — шаг на месте.
                                0
                                А почему не разделить сразу бек и фронт?

                                Что вы имеете в виду? Бэк у нас исторически на Java, фронт на Dart. Есть небольшие компоненты бэка на серверном дарте, но в общей массе кода – не существенные.
                                +1
                                «Страшную весть принес я в твой дом, Надежда! Зови детей!»
                                  0

                                  Можно рассмотреть preact. Живем с ним в проде 4 года, дает сильный буст по перфомансу и весу. Никаких проблем со сторонними либами

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое