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



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

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

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

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

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

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

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

Поделиться с друзьями
-->

Комментарии (40)


  1. Neyury
    27.06.2017 12:01
    +4

    Кажется на все эти 3 вопроса отвечает vue.js, хотя по поводу быстродействия можно долго спорить.


    1. igontarev
      27.06.2017 13:58

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


      1. jMas
        28.06.2017 10:13

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


  1. Alexeyco
    27.06.2017 13:48

    Как писать понятнее и проще?
    Как писать быстрее?
    Лучше быть богатым, но здоровым, чем бедным, но больным (с)


  1. vintage
    27.06.2017 14:36
    -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
            }
    
        }
    
    }


    1. Kikun
      27.06.2017 18:26
      +3

      /my/weather/weather.view.tree


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


      1. vintage
        27.06.2017 19:21
        -3

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


        1. raveclassic
          27.06.2017 23:43

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


          1. vintage
            28.06.2017 08:47

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


            1. raveclassic
              28.06.2017 10:58

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


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


              1. raveclassic
                28.06.2017 11:03

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


                1. vintage
                  28.06.2017 11:51

                  Для Атома есть. Правда ставить его сейчас приходится через клонирование репозитория :-(


                  Ещё есть плагин для WebStorm, но в репозитории он для старой версии Tree. К сожалению JetBrains что-то сломали и новые билды плагина не хотят работать.


              1. vintage
                28.06.2017 11:46

                ваши шаблоны

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


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

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


                1. raveclassic
                  28.06.2017 12:57

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

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


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

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


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


                  1. vintage
                    28.06.2017 14:00

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

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


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

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


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

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


                    1. raveclassic
                      28.06.2017 14:43

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

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


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

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


                      1. vintage
                        28.06.2017 15:21

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

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


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

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


                        1. raveclassic
                          28.06.2017 15:29

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

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


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

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


                          1. vintage
                            28.06.2017 15:40

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

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


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

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


                            1. raveclassic
                              28.06.2017 16:03

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

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


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

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


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

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


                              1. Wriketeam
                                28.06.2017 16:10

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


                              1. vintage
                                28.06.2017 16:19

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

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


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

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


                                1. raveclassic
                                  28.06.2017 16:32

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


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


                                  1. vintage
                                    28.06.2017 17:20

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


                                    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;
                                    }


                                    1. raveclassic
                                      28.06.2017 18:09

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


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


        1. bano-notit
          28.06.2017 00:43

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


          1. eXtReeM
            28.06.2017 04:02

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


            1. bano-notit
              28.06.2017 18:43

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


          1. vintage
            28.06.2017 08:42

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


            1. RubaXa
              28.06.2017 09:57
              +3

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


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


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


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


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


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


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


              1. raveclassic
                28.06.2017 11:00

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


                1. RubaXa
                  28.06.2017 11:51

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


    1. bano-notit
      28.06.2017 00:43
      +2

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


  1. hlebbobulka
    27.06.2017 18:58
    -1

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



    1. DeeUA
      27.06.2017 21:28
      +1

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


    1. Finsh
      27.06.2017 21:29

      NativeScript?


      1. hlebbobulka
        28.06.2017 12:33

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


        1. raveclassic
          28.06.2017 13:00
          +2

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


          1. vintage
            28.06.2017 14:01

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


            1. raveclassic
              28.06.2017 14:44

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