Бешеные псы: Angular 2 vs React: доклад Евгения Гусева и Ильи Таратухина

    Angular2 отрелижен, React и подавно. Копья поломаны, мечи перекованы на орала, страсти уже поутихли и, вроде как, статус кво восстановлен. Кто-то использует один инструмент, кто-то другой, разве что, иногда раздаются возгласы: «А у них...!»



    Однако не всё так просто. В конце концов, мы не только пишем код, но и решаем однотипные проблемы:

    • Как сделать наше приложение быстрым?
    • Как писать понятнее и проще?
    • Как писать быстрее?

    Кто-то может сказать: «Эту тему уже миллион раз обсасывали, зачем опять?». Но, все же, если вы запускаете новый проект или решили переписать старый, перед вами всё равно встанет проблема выбора. И даже если вы считаете, что всё очевидно — это далеко не так.

    Вот уже год как Wrike использует Angular 2 в бою. И вроде всё хорошо, но иногда закрадываются сомнения: “А вдруг мы свернули не туда?”

    В этом докладе мы постараемся быть «ближе к земле». Никакой зауми, слов «ну, в теории...». Возьмём реальный пример, за который вам заплатят денег, и будем смотреть на него с разных сторон, пытаясь выжать весь сок из двух конкурентов.

    Мистер Красный (Евгений Гусев) и мистер Синий (Илья Таратухин) спорят, доказывают, демонстрируют примеры, пытаясь понять, что же лучше.

    Будет боль, будет спор, будет вывод (видеозапись доклада с фестиваля РИТ++, Москва 5.06.2017).

    Wrike
    161.35
    Wrike делает совместную работу над проектами проще
    Share post

    Similar posts

    Comments 44

      +4
      Кажется на все эти 3 вопроса отвечает vue.js, хотя по поводу быстродействия можно долго спорить.
        0
        я за vue.js, но однозначно он не отвечает на эти три вопроса, главное проблема его в том, что любой компонент знает о store, и ты можешь в компоненте кнопки написать this.$store.dispatch('addComment'), и как тогда переиспользовать компоненты, в ng есть DI, в реакте есть redux connect, которые выносят логику из компонента
          0

          Я думаю эта проблема может решаться обращениям к стору только из high order компонентов, причем здесь вроде бы все ок со стором — ведь его можно подменять на любой другой. redux-овый connect ведь тоже пробрасывает dispatch. Мне импонирует больше redux, так как он эксплуатирует функциональный стиль.

      • UFO just landed and posted this here
          –1

          Для сравнения, полный код приложения с прогнозом погоды на $mol:


          /my/weather/weather.view.tree


          $my_weather $mol_page
              title \Weatcher app
              api_base \http://weather.example.org/
              body /
                  <= City $mol_string
                      hint \City name
                      value?val <=> city?val \
                  <= Forecast $mol_view
                      sub /
                          \Forecast: 
                          <= forecast \

          /my/weather/weather.view.ts


          namespace $.$mol {
          
              export $my_weather extends $.$my_weather {
          
                  forecast() {
                      const uri = new URL( this.api_base() )
                      uri.searchParams.set( 'city' , this.city() )
                      return $mol_http.resource( uri.toString() ).json().forecast
                  }
          
              }
          
          }
            +3
            /my/weather/weather.view.tree


            Если смотреть это с точки зрения читаемости, то выглядит оно не очень
              –3

              Какие мы нежные :-) А конкретней, что не так?

                0

                Боги, да все не так. Вам уже пол года, если не больше, об этом говорят.

                  0

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

                    0

                    Ну просто мы неправильные пчелы.


                    А если серьезно, изучать что-то должно нравиться, либо под дулом заказчика. Так как $mol не про второе, то остается только первое, но ваши шаблоны не вызывают чувства эйфории. Вы их разработали, вам с ними хорошо и просто, а мне (как и остальным) — нет. Попробуйте поменять синтаксис на что-нибудь более… спокойное, возможно как плагин к парсеру.

                      0

                      Кроме того, крайне большим шагом к адаптации станет плагинчик-хайлайтер к тому же vscode/atom, чтобы не нужно было ломать глаза среди забора торчащих в разные стороны слэшей и стрелок.

                      0
                      ваши шаблоны

                      Какие ещё шаблоны? У нас нет никаких шаблонов. Всё, что у нас есть — это компоненты и описание их коммуникаций.


                      Попробуйте поменять синтаксис на что-нибудь более… спокойное

                      "Спокойное" — это как? Вот тут я пробовал описывать одно и то же в форматах Tree, XML, JSON. Какой вариант вам больше по душе?

                        0
                        Какие ещё шаблоны? У нас нет никаких шаблонов. Всё, что у нас есть — это компоненты и описание их коммуникаций.

                        Называйте, как хотите. Представление у вас живет отдельно от логики.


                        Вот тут я пробовал описывать одно и то же в форматах Tree, XML, JSON.

                        Ну так а почему вы об этом не говорите никогда? Вот слушал я вас на РИТ++ — ни слова, даже вопрос вам задали, а где разметка то?


                        Явно меньше углов для перехода у html-подобного варианта. Именно поэтому JSX такой популярный, в отличие от формата, используемого в elm/purescript (обычные функции).

                          0
                          Называйте, как хотите. Представление у вас живет отдельно от логики.

                          Структура живёт отдельно от логики, а вместе со стилями они образуют представление.


                          Ну так а почему вы об этом не говорите никогда? Вот слушал я вас на РИТ++ — ни слова, даже вопрос вам задали, а где разметка то?

                          Так доклад про реактивное программирование, а не про разметку был :-)


                          Явно меньше углов для перехода у html-подобного варианта. Именно поэтому JSX такой популярный, в отличие от формата, используемого в elm/purescript (обычные функции).

                          Только вот во view.html ещё сложнее разобраться, чем во view.tree, так как используемые идиомы очень криво ложатся на html. Можно отказаться от идиом, но тогда получится ещё один клон Ангуляра — зачем оно надо?

                            0
                            Так доклад про реактивное программирование, а не про разметку был :-)

                            Неправда, доклад был про $mol, хоть и назывался по-другому :)


                            Только вот во view.html ещё сложнее разобраться

                            Ну не знаю, мне все стало кристально ясно. Но писать везде bind тоже не очень. Но я уверен, что все-равно можно накрутить html-подобный DSL с удобным неявным связыванием.

                              0
                              Неправда, доклад был про $mol, хоть и назывался по-другому :)

                              Примеры были на $mol_mem, а доклад был про ОРП и бонусы, которые он даёт. Половину этих бонусов вы можете получить с MobX, например.


                              Ну не знаю, мне все стало кристально ясно. Но писать везде bind тоже не очень. Но я уверен, что все-равно можно накрутить html-подобный DSL с удобным неявным связыванием.

                              Не знаю, что там вам стало "кристально ясно", но суть bind вы так и не поняли :-) Суть его в том, что у каждого элемента (как и у любого другого свойства компонента) должно быть уникальное имя, по которому к нему можно обратиться. И имя это может быть задано только программистом вручную.

                                0
                                Примеры были на $mol_mem, а доклад был про ОРП и бонусы, которые он даёт. Половину этих бонусов вы можете получить с MobX, например.

                                Может, тогда не стоило приводить примеры на $mol? Потому что проблема не в "ОРП", а в нем.


                                Суть его в том, что у каждого элемента (как и у любого другого свойства компонента) должно быть уникальное имя, по которому к нему можно обратиться. И имя это может быть задано только программистом вручную.

                                Ну значит у вас кривые примеры. Если это не bind в привычном понимании (связывания значения элемента представления со значением поля модели), но поправьте доки. Понять, что это такое из примера в виде .tree вообще невозможно. С доками кстати тоже большая беда, да, много всего, но что с этим делать — не понятно ну вот совсем.

                                  0
                                  Может, тогда не стоило приводить примеры на $mol? Потому что проблема не в "ОРП", а в нем.

                                  Какая проблема?


                                  Ну значит у вас кривые примеры. Если это не bind в привычном понимании (связывания значения элемента представления со значением поля модели), но поправьте доки.

                                  Да нет, это bind. Просто значением является вложенный компонент. Это очень мощная идиома, позволяющая динамически отрендерить что угодно во что угодно. Без плясок с бубном как в Ангуляре и не ломая переиспользование узлов, как в Реакте.

                                    0
                                    Какая проблема?

                                    Жуткий синтаксис и отсутствие хорошей документации с хорошими примерами.


                                    Да нет, это bind. Просто значением является вложенный компонент. Это очень мощная идиома, позволяющая динамически отрендерить что угодно во что угодно. Без плясок с бубном как в Ангуляре и не ломая переиспользование узлов, как в Реакте.

                                    Мне кажется, что стоит написать статейку разжевывающую именно этот момент. Потому что в Реакте я делаю


                                    const Wrapper = ({Child}) => (
                                      <div>
                                        Hi, <Child/>
                                      </div>
                                    );

                                    и прекрасно себя чувствую...

                                      0
                                      Коллеги, ветка как-то переросла в оффтоп-обсуждение темы, мало связанной с постом. Может, это достойно отдельной публикации?
                                        0
                                        Жуткий синтаксис и отсутствие хорошей документации с хорошими примерами.

                                        В моём докладе не было ничего про "жуткий синтаксис".


                                        Потому что в Реакте я делаю и прекрасно себя чувствую...

                                        А стилизуете/локализуете вы это дело как?

                                          0

                                          l10n/i18n через react-intl
                                          Стилизация/темизация через те же HOC/HOF и react-css-themr


                                          Ладно, тут Wrike уже жалуется на оффтоп

                                            0

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


                                            import React, { Component } from 'react';
                                            import { themr } from 'react-css-themr';
                                            import { FormattedMessage } from 'react-intl'
                                            import { SuccessIcon } from 'icons';
                                            import successTheme from './SuccessButton.css';
                                            
                                            @themr('MySuccessButton', successTheme)
                                            class Button extends Component {
                                            
                                              render() {
                                                const { theme, icon, title } = this.props;
                                            
                                                return (
                                                  <button className={theme.button} >
                                                    { icon || <SuccessIcon /> }
                                                    <span className={theme.text} >{ title || <FormattedMessage id='SuccessButton.title' /> }</span>
                                                  </button>
                                                )
                                            
                                              }
                                            
                                            }
                                            
                                            export default Button;

                                            .button {
                                                padding: .5rem;
                                            }
                                            
                                            .text {
                                                margin-left: .5rem;
                                            }

                                            На "жутком синтаксисе" всё куда проще:


                                            $my_button_success $mol_button
                                                sub /
                                                    <= Icon $mol_icon_success
                                                    <= Text $mol_view
                                                        sub /
                                                            <= title @ \Success 

                                            [my_button_success] {
                                                padding: .5rem;
                                            }
                                            
                                            [my_button_success_text] {
                                                margin-left: .5rem;
                                            }
                                              0

                                              Где костыли-то? То, что вы называете "костылями", на деле является инкапсуляцией стилей и управлением зависимостями через css-модули, чего, судя по всему, ваш $mol лишен.


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

                                                0
                                                Где костыли-то?

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


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

                                                Ну и какая польза от параноидальной инкапсуляции и ручного управления зависимостями?


                                                css-модули, чего, судя по всему, ваш $mol лишен.

                                                В $mol нет css-модулей или js-моделей. Есть просто "модули", внутри которых код может быть на самых разнообразных языках и все действуют по одним и тем же правилам.


                                                изначальный посыл был про документацию вашего $mol и кривейший синтаксис

                                                А давайте по существу? Чего конкретно вы не смогли найти в документации? И в чём именно кривизна синтаксиса? Я бы с радостью восполнил пробелы и улучшил синтаксис.

                    0

                    Синтаксис вообще незнакомый. Если у ng всё же ближе к html, у JSX тоже как-то входит стандартный код для шаблонизаторов, то тут вообще новое. Нету ассоциаций с привычными вещами. Тут нужно с нуля по факту учить синтаксис. Я именно из-за привычности в своё время выбрал Pug (ранее haml) вместо Slime.

                      0
                      Вроде как PUG ранее был Jade
                        0

                        Да, совершенно забываю… Сейчас то он называется pug, но я и им уже не пользуюсь...

                        0

                        pug очень похож на html?

                          +3

                          Он похож на не совсем стандартный CSS, но похож, а tree просто изобилует разными спец символами и нет ничего похожего на теги, css-классы или атрибуты.


                          Поэтому без глубокого погружения невозможно оценить на сколько лучше стало или как хоть это сопоставить с кодом на другом FW.


                          Напишите же в конце концов статью, где будет описан процесс создания простой «Кнопки» с нуля, без использования уже готовых $mol_*-компонентов.


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


                          Затем показать, как добавить такой кнопки title/disabled, кастомные атрибуты, запихать внутрь текст + иконку и сделать возможность, чтобы при передаче href свойства, кнопка использовала тег a, вместо button.


                          Финальный шаг, как интегрировать эту кнопку в уже готовое приложение не на $mol.


                          P.S. В конце можете написать, что ничего этого делать не надо, 99% компонентов уже имеют стандартную реализацию, например вот Кнопка.

                            0

                            Вот именно, я, честно говоря, так до сих пор и не понял, как вообще на нем верстать обычную верстку.

                              0

                              На самом деле, где-то vintage мне уже отвечал, что в $mol просто нет «обычной верёстки», на этом мы и попрощались ;]

                    +2

                    А вы всё со своим $mol всё бегаете… Заканчивайте уже, только вы его рекламируете, а не он себя.

                    –1
                    Заметил, что участники подобных дискуссий с завидной регулярностью забывают рассмотреть возможность быстрого порта логики на мобильные устройства. И вот тут (да не заминусют меня ангулярщики) Ionic проигрывает по скорости и удобству(субъективно), тогда как React Native заметно шустрее. А для пишущих, что Vue.js — вообще сказка, соглашусь, но только в том случае, если вы бэкендщик и вам нужно быстро накидать приличный фронт особо не влезая в js (gitLab — отличный пример использования Vue.js на фронте).
                      +1

                      А почему вы сравниваете React Native с Ionic'ом, а не с Native Script'ом?

                        0
                        NativeScript?
                          0
                          Велика ли разница, если что Ionic, что Native не используют внутри нативных компонентов, а используют вебвью? Для баланса добавлю, что для React Native видимо регулярно необходимо допиливать на нативных языках для той или иной платформы, но это уже совсем другая история.
                            +2

                            Справедливости ради, вступлюсь за NS — там нет WebView, все честно.

                              0

                              Там есть webview, как один из нативных компонент :-)

                                0

                                Я имел в виду, что сам NS не внутри WebView работает, в отличие от Ionic

                        0
                        Господа, а где-нибудь есть слайды докладов или их текстовая некая расшифровка?

                      Only users with full accounts can post comments. Log in, please.