Я уверен, большинство из вас, кто использует react используют jsx. Благодаря своему лаконичному синтаксису jsx улучшает читабельность шаблонов. Сравните:


render() {
    return React.createElement('div', { className: 'block'}, 'Text of block');
}
// vs
render() {
    return <div className='block'>
        Text of block
    </div>;
}

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


Чем плох jsx


Все бы хорошо, если бы jsx был бы стандартной возможностью javascript, но это не так. Для работы с jsx вам потребуется транспилятор. Решив использовать jsx вы навечно становитесь зависимы от транспиляции. Еще недавно, такая зависимость никого не пугала, так как для использования новых возможностей из ecmascript 2015 вам в любом случае необходим транспилятор. Но все меняется, уровень поддержки es6 близок к 100%


По крайней мере, в develop-окружении уже можно избавляться от транспиляции. Представляете, какие возможности это открывает? Не нужно при дебаге ковыряться в выходе babel, который многое изменил, не нужны source map, после изменения файла нет необходимости ждать, пока закончится пересборка. И jsx в данном случае будет главной помехой… Есть ли альтернативы jsx?


Альтернативы jsx


Стандарт ecmascript 2015 определяет тегированные шаблонные строки. Пример, выше можно переписать так:


render() {
    return es6x `<div className='block'>
        Text of block
    </div>`;
}

Более сложный пример:


import Input from './input';

render() {
    return <div className='block'>
        <Input name='name1'
            value={this.props.value}
            {...this.props.inputProps}
            checked
        />
        {this.props.items.map(item => <span {...item.props}>{item.text}</span>}
    </div>;
}
// преобразуется в:
render() {
    return es6x `<div className='block'>
        <${Input} name='name1'
            value=${this.props.value}
            ${this.props.inputProps}
            checked
        />
        ${this.props.items.map(item => es6x `<span ${item.props}>${item.text}</span>`)}
    </div>`;
}

Как подключить


npm install --save es6x

Пакет es6x поддерживает разные движки. Среди них react, hyperscript (h), а также (по умолчанию) универсальный вывод в json вида:


{
    tag: 'div',
    attrs: {
        className: 'block'
    },
    children: ['Text of block']
}

Чтобы использовать совместно с react нужно указать метод вывода перед первым вызовом (в одном месте проекта):


import React from 'react';
import es6x from 'es6x';

es6x.setOutputMethod(React.createElement);

Особенности пакета es6x


  • размер в сжатом виде около 2 кб
  • шаблоны кешируются — во время первого исполнения создается кеш, который используется при повторных вызовах
  • решена проблема пробельных символов внутри шаблонов, которой страдает jsx:

return <div>
    {'some text'}
    {' '}
    <b>strong</b>
    {' '}
    <i>emphase</i>
</div>

В примере выше, в jsx требуется добавлять уродливую кострукцию {' '} между словами "text", "strong" и "emphase" а в es6x этого не потребуется:


return es6x `<div>
   ${'some text'}
   <b>strong</b>
   <i>emphase</i>
</div>`;

Производительность


es6x поддерживает кеширование, благодаря чему, при повторном вызове с тем же шаблоном не происходит парсинга и вызов происходит намного быстрее. Повторный вызов по результатам тестирования в 10 раз быстрее первого (в случае универсального парсинга в json, в случае парсинга для react разница меньше — менее чем в 2 раза). Так же я производил сравнение с конкурентным пакетом t7 при парсинге для react. Результаты:


jsx-выход: 15683 ops/sec ±1%
es6x: 11187 ops/sec ±1%
t7: 10253 ops/sec ±1% (не поддерживает многих плюшек jsx)


То есть падение производительности около 30%. Что оказалось меньше, чем я ожидал. Объясняется тем, что метод createElement достаточно тяжелый.


Пользуйтесь, сообщайте мне о багах. Всем спасибо за внимание.

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

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


  1. Akuma
    09.12.2016 16:46

    Так и не понял, зачем отказываться от JSX?
    Просто, удобно, «стандартно». Всякими бабелями/вебпаками все равно пользуемся.


    1. dyakov
      09.12.2016 17:09
      +3

      Всякими бабелями/вебпаками все равно пользуемся.

      Пока пользуетесь, да. Вам все равно.
      Я в ближайшем будущем планирую все сделать, чтобы избавиться от их необходимости в develop-окружении. Это даст плюсы — 1) в дебаггере виден неизмененный сборщиком код, номер строк будет совпадать, 2) не надо будет ждать пересборки на любое изменение (в большом проекте с вебпаком это может занимать пол минуты и больше)
      Ну и jsx не входит в язык javascript, вряд ли войдет. Стандартно (а теггированные строки — часть стандарта) все же правильнее, имхо. Особенно, если остаются все плюшки и необходимы минимальные изменения по сравнению с jsx.
      Кстати, для скорости в проде, возможен плагин к babel, который на выходе будет давать все тоже что сейчас дает jsx.


      1. Akuma
        09.12.2016 18:02

        Хм. Как вы например без дев-окружения будете вырезать из кода отладку?

        Вообще, идея хорошая, не спорю. Чем меньше «шагов» к сборке, тем быстрее и проще. Но на текущий момент вебпак и бабель позволяют делать то, что без них я не могу. А JSX банально удобнее, чем ваше (и многие другие) предложения.


        1. vintage
          09.12.2016 19:46
          -1

          А зачем её вырезать? Очень удобно прямо на проде, включить логи и посмотреть что там идёт не так.


          1. justboris
            10.12.2016 12:45

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


            1. vintage
              10.12.2016 12:55
              -1

              1. Капля в море.
              2. Код им и так доступен.


              1. faiwer
                10.12.2016 13:05

                Да нет, не капля. Некоторые библиотеки добавляют довольно много debug-кода. К примеру knockout, react. На одной из связок недавно проверял сколько будет, вышло в р-не 10-15% выигрыша.


                1. vintage
                  10.12.2016 13:23
                  -1

                  Что же они такого туда добавляют?


                  1. faiwer
                    10.12.2016 13:52

                    Не ко мне вопрос. Наверное инструменты для отладки, примешивают dev-поля к своим объектам, ну и т.д… Могут даже альтернативные алгоритмы подключать, такие что позволят легче дебажить к примеру. Вы об этом лучше их самих спросите.


                    1. vintage
                      10.12.2016 14:18
                      -1

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


                      1. faiwer
                        10.12.2016 14:58
                        +1

                        При желании можно подключать не-debug версии скриптов и в dev-е. В чём проблема? Или вы замечаете "фатальные недостатки" уже во всём? :) Даёшь всем $Mol?


                      1. demiazz
                        12.12.2016 01:29
                        +1

                        Аргумент в принципе логичен с первого взгляда, но упускает множество моментов.


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


                        Во-вторых, тот же React в development режиме вырезает не только отладочную информацию, но и например, вырезает проверку propTypes. А еще при сборке, их можно вообще вырезать из кода тем же плагином.


                        В-третьих, вы упускаете момент, что например, есть, например, минификатор babili, который построен поверх babel. Babel и подобные инструменты — это не только полифилл для новых версий языка.


                        В-четвертых, ECMAScript в отличии от ранних версий, сейчас активно развивается, и говорить о том, что сейчас все фичи будут во всех мажорных браузерах, и нам не нужен будет transpiler — преждевременно. Transpiler используется для проверки и реализации новых возможностей языка (в том числе, посмотрите на процесс TC-39). Во-вторых, новые возможности можно использовать уже с Stage 3 (когда допускаются только критические исправления). Но есть еще Stage 4. И это только до момента внедрения в браузеры (этот процесс тоже не равномерен по времени). То есть, transpiller позволяет подготовить ваш код к будущему переходу на нативную поддержку в движках языка до того момента, как эта поддержка настанет.


                        В-пятых, отсылка на отказ от source map также преждевременна. Вы можете отказаться от babel, но вы же минифицируете код? Значит, уже нужны source map.


                        В-шестых, отладка в production… Ну как бы это сказать. Этот этап должен предварять этап сбора отладочных сведений путем таких инструментов как Sentry, TrackJS, Honeybadger, и других. И потом уже можете воспроизводить неисправность локально, зная условия, которые приводят к ошибке. В 99.99% случаев, проблема будет не в сборке.


                        Transpiler'ы — это данность, поэтому и отказ от JSX, только потому что он требует transpiler'а, который скоро будет не нужен — это слабый, на самом деле, аргумент.


                        Я уже не говорю о том, что, экономить килобайты важно до сих пор. По очень многим причинам. Странно это вообще объяснять фронтенд-разработчику, не находите?


                        1. demiazz
                          12.12.2016 01:48

                          Кстати, еще пока вспомнил, и касательно конкретно React. В dev и production режиме, JSX транспайлится по разному. createElement против непосредственно JS объектов. Первый дает больше возможностей для отладки, второй — быстрее работает.


                          Что касается разбора шаблонов непосредственно на клиенте — мы хотим дать лучший UX. Если мы можем отказаться от дополнительных шагов, и быстрее показать страницу пользователю — почему это не делать? Зачем дополнительный шаг? Есть ведь мобильные, есть простые пользователи с не совсем производительными устройствами.


                          На секундочку, Angular 2, компилирует шаблоны в императивный JS-код непосредственно.


                          Или вот https://svelte.technology/ от Рича Харриса (автора Rollup). Фреймворк компилирует компоненты в непосредственно императивный код.


                          Технологии двигаются в сторону оптимизации, тут же предлагается компилировать шаблоны на клиенте (даже во времена классических строковых шаблонизаторов, хорошей практикой была прекомпиляция шаблонов Jade/Pug/etc в функции).


                          Я уже не говорю о том, что современные редакторы умеют в подсветку JSX синтаксиса, и его легче читать, чем HTML шаблон в строке со вставками.


                          Еще один момент — компиляция JSX шаблона быстрее покажет ошибку в шаблоне (просто банально не сможет распарсить структуру), нежели мы получим ошибку в runtime при попытке отрендерить страницу. В конце концов, редакторы, вполне себе уже поддерживают JSX и укажут на несоответствие синтаксиса. Это конечно, по большому счету лирика, но тем не менее.


                          1. vintage
                            12.12.2016 09:02
                            +1

                            createElement против непосредственно JS объектов. Первый дает больше возможностей для отладки

                            Это какие такие возможности?


                            Зачем дополнительный шаг? Есть ведь мобильные, есть простые пользователи с не совсем производительными устройствами.

                            Странно слышать это от человека, генерирующего html яваскриптом :-D


                            На секундочку, Angular 2, компилирует шаблоны в императивный JS-код непосредственно.

                            Это не быстрый процесс. И результат достаточно сложно отлаживать.


                            автора Rollup

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


                            Фреймворк компилирует компоненты в непосредственно императивный код.

                            Попробуйте допустить в коде хоть одну ошибку — концов вы не найдёте.


                            JSX синтаксиса, и его легче читать, чем HTML шаблон в строке со вставками.

                            Ага, HTML внутри JS читать куда легче, чем JS внутри HTML :-) Я вот как-то особой разницы не вижу — и там и там каша получается из разных синтаксисов.


                            компиляция JSX шаблона быстрее покажет ошибку в шаблоне (просто банально не сможет распарсить структуру), нежели мы получим ошибку в runtime при попытке отрендерить страницу.

                            Если вы считаете это полезным, то почему используете JSX, а не TSX?


                        1. vintage
                          12.12.2016 08:38

                          В конце концов, вы же не рассказываете условным C++-разработчикам, что сборка бинарных файлов с отладочной информацией — это плохо

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


                          Во-вторых, тот же React в development режиме вырезает не только отладочную информацию, но и например, вырезает проверку propTypes. А еще при сборке, их можно вообще вырезать из кода тем же плагином.

                          propType — это рантайм эмуляция статической типизации. Что мешает использовать полноценную статическую типизацию в виде TSX, которую не нужно "вырезать"?


                          есть, например, минификатор babili, который построен поверх babel

                          Есть много разных минификаторов. Сейчас они используются скорее по инерции, так как на фоне gzip практически ничего не дают.


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

                          А я этого и не говорил. Яваскрипту давно уже надо было перейти на байткод :-)


                          В-пятых, отсылка на отказ от source map также преждевременна.

                          А это вы откуда взяли? У меня сорсмапы кладутся в отдельный файл. А вы вкомпиливаете их прямо в код? Зачем?


                          Этот этап должен предварять этап сбора отладочных сведений путем таких инструментов как Sentry, TrackJS, Honeybadger, и других. И потом уже можете воспроизводить неисправность локально, зная условия, которые приводят к ошибке.

                          Хорошо там у вас наверно в идеальном мире? :-)


                          Я уже не говорю о том, что, экономить килобайты важно до сих пор. По очень многим причинам. Странно это вообще объяснять фронтенд-разработчику, не находите?

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


                          1. demiazz
                            12.12.2016 10:41

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

                             Круто, расскажите как отладочную информацию положить в отдельный файл в случае обсуждаемых выше задач? Кроме source maps.


                            propType — это рантайм эмуляция статической типизации. Что мешает использовать полноценную статическую типизацию в виде TSX, которую не нужно "вырезать"?

                            А я не отметал возможность использования TSX, только вот, TypeScript не всем нужен и не всем нравится. Так то и FlowType есть. Но как и в случае с TS — не все используют.


                            Есть много разных минификаторов. Сейчас они используются скорее по инерции, так как на фоне gzip практически ничего не дают.

                            Ну не знаю. У меня почему-то, даже zopfli дает ощутимо разные результаты после и без минификации. Вы делаете слишком обобщенный вывод.


                            А это вы откуда взяли? У меня сорсмапы кладутся в отдельный файл. А вы вкомпиливаете их прямо в код? Зачем?

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


                            Хорошо там у вас наверно в идеальном мире? :-)

                            Идеальный мир — делаем мы сами. TrackJS умеет в телеметрию, например. Так что, он не такой идеальный, а скорее реальный. Вы же используете, например, console.log. Ну так же вместо него можно сообщения отправлять в трекер. Лучше, чем искать ошибку на продакшене, не так ли? =)


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

                            И как это связано с размером результирующего бандла приложения? Ну можно и System.import вспомнить, и асинхронную догрузку кусков приложения. И многих подходов. $mol тут чем особо выделяется? Тем что минималистичен?


                            1. vintage
                              12.12.2016 18:44
                              -1

                              Круто, расскажите как отладочную информацию положить в отдельный файл в случае обсуждаемых выше задач? Кроме source maps.

                              Расскажите, что это за информация.


                              только вот, TypeScript не всем нужен и не всем нравится.

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


                              TrackJS умеет в телеметрию, например.

                              Он передаёт на сервер слепок памяти? Или как обычно — лишь создаёт видимость в духе "ну браузер такой-то, ось такая-то"?


                              Вы же используете, например, console.log. Ну так же вместо него можно сообщения отправлять в трекер.

                              Ваш трекер не умеет перехватывать console.log?


                              Лучше, чем искать ошибку на продакшене, не так ли? =)

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


                              Ну можно и System.import вспомнить, и асинхронную догрузку кусков приложения.

                              Да не стоит.


                              $mol тут чем особо выделяется?

                              Микромодульностью.


                              1. demiazz
                                12.12.2016 20:25

                                Расскажите, что это за информация.

                                Да банальная отладочная информация. Например, отладочные сообщения, ворнинги. Которые имеют смысл мне локально, но не имеют смысла в продакшене для пользователя. Мы же с этого начинали. Или опять таки propTypes, или те же типы (они бесполезны в рантайме в случае JS, увы). Мы кажется с этого начали — зачем пихать отладочную информацию, чтобы потом удалять её сборкой, разве нет?


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

                                Какая-то странная ультимативность. Type checker выявит ошибки типов (большинство, не все — он в рантайме не защитит от кривых входных данных — ошибка отловится, но уже где-то глубже, а не на точке входа). Но типы не поймают ошибку, если в es6x будет неправильный шаблон, и сборка не поймает. Так что разглагольствовать есть о чем. Кроме того, есть trade off между TS/Flow, и выразительностью, например https://twitter.com/dan_abramov/status/808020948750397441


                                Он передаёт на сервер слепок памяти? Или как обычно — лишь создаёт видимость в духе "ну браузер такой-то, ось такая-то"?

                                Вы отлаживаете клиентский JS по слепку памяти? =) Нет, конечно, речь идет не о банальном environment'е, что трекеры умели в бородатые годы. Речь идет о формировании лога событий, предшествующих ошибке https://trackjs.com/assets/images/tour/telemetry-full.png Я могу ошибаться (давно не пользовался), но кажется в sentry подобная штука называется Breadcrumbs.


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

                                Правильно. Если она воспроизводится локально — то лучше её там и искать. Трогать продакшн конечно же нужно, но если можно этого избежать — почему не воспользоваться этим? =)


                                Микромодульностью.

                                Честно, пробежался по репозиторию, и магической микромодульности не увидел. Просто свой набор утилит + компоненты, только самописные и интегрированные между друг другом, а не с npm. Крутое решение для класса задач, но я не вижу как им заменить React, и кастомизируемую сборку. И да, я люблю конечно, convention over configuration, но так же я люблю явные зависимости. Если бы, у вас был dependency injection, аля Angular — это было бы интереснее, но у вас просто парсинг своих соглашений в поисках зависимостей, вместо import/export из es6. Ну как бы, это не микромодульность, ну или не чем-то выделяющаяся, извините.


                                Что касается $mol вообще. В Питере целых два сообщества проводят митапы по фронтенд разработке. Почему бы вам не рассказать о нем на митапе? Не все пишут на React, в общем-то. Вполне вероятно вы найдете идею/критику/пользователей на них, рассказав о своем инструменте.


                                1. vintage
                                  14.12.2016 10:43

                                  Например, отладочные сообщения, ворнинги.

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


                                  типы (они бесполезны в рантайме в случае JS, увы). Мы кажется с этого начали — зачем пихать отладочную информацию, чтобы потом удалять её сборкой, разве нет?

                                  Типы несут полезную нагрузку. Неиспользуемые модули — бесполезную. При этом типы вырезаются при любой сборке, а не требуют для продакшена делать отдельную.


                                  Но типы не поймают ошибку, если в es6x будет неправильный шаблон, и сборка не поймает.

                                  Речь шла про TSX, он поймает.


                                  Так что разглагольствовать есть о чем. Кроме того, есть trade off между TS/Flow, и выразительностью, например https://twitter.com/dan_abramov/status/808020948750397441

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


                                  Речь идет о формировании лога событий, предшествующих ошибке

                                  Пользователь ввёл абракадабру, сделал 100500 действий, потом поскроллил пальцем и всё сломалось. Чем вам помогут последние действия пользователя?


                                  Трогать продакшн конечно же нужно, но если можно этого избежать — почему не воспользоваться этим? =)

                                  Вы зашли на продакшен, видите багу. Что к ней привело — не понятно. Ваши действия?


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

                                  А что вы ожидали увидеть? Что вы вкладываете в понятие микромодульности, помимо отсутствия монолитного ядра?


                                  Крутое решение для класса задач, но я не вижу как им заменить React

                                  Реакт заменяется модулем $mol_viewer.


                                  кастомизируемую сборку

                                  Что вы хотите там кастомизировать?


                                  И да, я люблю конечно, convention over configuration, но так же я люблю явные зависимости.

                                  Там вполне явные зависимости. Когда вы пишете $mol_defer в бандл включается модуль $mol_defer. Куда уж явнее? То, что вы имеете ввиду — не явные зависимости, а зависимости вынесенные в начало файла. Объявления переменных вы тоже в начало файла выносите?


                                  Если бы, у вас был dependency injection, аля Angular — это было бы интереснее

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


                                  Почему бы вам не рассказать о нем на митапе?

                                  Потому же почему и тут карму сливают — я не Дэн Абрамов, $mol — не React, а работаю я не в Google.


                                  1. demiazz
                                    14.12.2016 13:39

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

                                    То есть, сообщения об использовании deprecated классов/модулей/функций, различные warnings, например — это признаки плохого инструмента? Выбирая из 20Мб отладочных сообщений, и модулей ля упрощения разработки в development, и отсутствие оного, зато не требующим шага при сборке — я выберу первый. Потому что, мне это ничего не стоит. Зато это сэкономит мне время, когда палка выстрелит.


                                    Типы несут полезную нагрузку. Неиспользуемые модули — бесполезную. При этом типы вырезаются при любой сборке, а не требуют для продакшена делать отдельную.

                                    Да. Я понимаю вашу позицию. Типы вырезаются при любой сборке, а вот сделать dead code elimination, или tree shaking — это уже в самописной build системе не получится сделать за пять минут и на коленке. Поэтому это сложно, а значит не нужно. Лучше делать отладку на production с пользовательскими данными, верить в то, что используемый инструмент идеально написан, и отладочная информация для слабаков, а настройка сборки — не нужна, потому что наш инструмент ее не умеет и вообще время, и вообще сложно.


                                    Речь шла про TSX, он поймает.

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


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

                                    Это не костыль, это всего лишь синтаксис языка. Конечно сломается, но когда оно сломается — тогда и код перепишется. Да и тесты помогут. К типизации это относится ровно так, что TS/Flow не идеальны, и к тому, что краткость синтаксиса, не всегда доступна вместе с типизацией, и нужно выбирать.


                                    Кстати, насчет TS. Как думаете, вот этот код TS поймет как неправильный: function filterArray(a: any[]): number[] { return a.filter(i => typeof i === 'string'); }? Можете в Playground даже попробовать. Надеюсь, банальный filter вы костылями не назовете?


                                    Речь идет о формировании лога событий, предшествующих ошибке

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


                                    Вы зашли на продакшен, видите багу. Что к ней привело — не понятно. Ваши действия?

                                    Так это вам непонятно, что к ней привело. Я то как раз использую "ненужные модули" и "логи про то, как пользователь поскроллил", и могу довольно быстро локализовать ошибку. У меня на руках есть исключение, привязанное к source maps (если это было исключение), у меня есть примерный сценарий поведения пользователя (потому что пользователь никогда вам не скажет, что он сделал, что привело к ошибке), и у меня есть локальная система, где я могу попытаться воспроизвести ошибку, и задействовать бесполезные модули, которые нужно вырезать на этапе сборки. Так что, первым моим действием, будет анализ данных, а не гадание на production, как воспроизвести, и почему так получилось.


                                    А что вы ожидали увидеть? Что вы вкладываете в понятие микромодульности, помимо отсутствия монолитного ядра?

                                    Я ожидал увидеть нечто из ряда вон. Я ожидал, какой-то магической "микро"-модульности. А на деле, простой компонентный подход, разделение на модули (откуда тут взялось микро — не понимаю, отсылка к модным ныне микросервисам?), который у многих уже давно.


                                    Реакт заменяется модулем $mol_viewer.

                                    Я имел ввиду не в рамках $mol, а как инструмент для решения класса задач.


                                    Что вы хотите там кастомизировать?

                                    Например, я хочу кастомизировать используемые PostCSS плагины (а кто-то использует вообще Less/Sass/Stylus — и это их право). И знаете. Не просто кастомизировать. У меня в рамках приложения, может быть допустим, несколько разных типов страниц — основные разделы для пользователя, пара SPA, админка, и пара лендингов. И для каждого я хочу свой набор PostCSS плагинов, потому что у них могут быть разные требования, или нужны по разному настроенные плагины. Или, я хочу импортировать CSS в JS, например. Я хочу, чтобы моя сборка считала зависимостью не только JS/CSS файлы, но и статику, которые те используют. И желательно, это дело тоже как-то оптимизировать. Я хочу прокидывать флаги NODE_ENV, например, но мы это проходили, да. Я хочу контроллировать, как будут собираться бандлы и иметь возможность оптимизировать стратегию их сборки и компоновки под нужды приложения. Я хочу, чтобы сборщик умел кешировать и умел в инкрементальную сборку в development, чтобы было быстро, и может быть умел hot reload. Хотел бы иметь сервер, который бы отдавал ассеты в development режиме, без нужды сбрасывать их каждый раз на диск, а отдавать прямо из памяти. Чтобы было быстро.


                                    Там вполне явные зависимости. Когда вы пишете $mol_defer в бандл включается модуль $mol_defer. Куда уж явнее? То, что вы имеете ввиду — не явные зависимости, а зависимости вынесенные в начало файла. Объявления переменных вы тоже в начало файла выносите?

                                    Ну это так себе — как явные зависимости. Если допустим, я напишу $mol_defer, но такой модуль не будет существовать — ваша сборка скажет мне об этом? А если, не будет существовать не JS файл, а какая-то другая зависимость — я об этом узнаю? Dependency Injection — механизм не явных зависимостей конечно. Но у него есть свои benefits, о которых много копий сломано, и рассказывать то, что можно прочитать в десятке мест — я не хочу. Кстати, этот же механизм есть и у Ember. И он тоже отчасти на соглашениях построен.


                                    Потому же почему и тут карму сливают — я не Дэн Абрамов, $mol — не React, а работаю я не в Google.

                                    Ну может карму сливают не потому, что вы не Абрамов (и он не всегда в FB работал), а потому что, вы можете быть не правы? Или ваше мнение не совпадает с большинством? Роману Дворнову, вот ничего не мешает рассказывать про basis.js, при этом не имея огромной аудитории как у React.


                                    1. vintage
                                      14.12.2016 22:50

                                      То есть, сообщения об использовании deprecated классов/модулей/функций, различные warnings, например — это признаки плохого инструмента?

                                      Такое обилие deprecated говорит о плохом дизайне. Стал ли он лучше — большой вопрос. В любом случае сообщения эти обычно вставляются в одно единственное место определения, а не в каждое место использования. Так что расти объёму сборки тут особо не с чего.


                                      Выбирая из 20Мб отладочных сообщений, и модулей ля упрощения разработки в development, и отсутствие оного, зато не требующим шага при сборке — я выберу первый. Потому что, мне это ничего не стоит.

                                      А я вот выберу встроенный в браузер инструментарий. А не работающий только с одним единственным фреймворком, только на локальной машинке.


                                      dead code elimination

                                      Мёртвый код надо не при сборке удалять, а ещё до коммита. TS, например, ругается на мёртвый код.


                                      tree shaking

                                      Этот костыль не нужен для микромодульной архитектуры. Ну вот совсем.


                                      Но речь как раз шла не об ошибках типов, на что вы сказали, что только типизируемый язык такие ошибки словит (хотя при чем тут типы).

                                      Речь шла про синтаксические ошибки.


                                      Это не костыль, это всего лишь синтаксис языка. Конечно сломается, но когда оно сломается — тогда и код перепишется.

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


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

                                      Только выбирать приходится между временем отладки и "краткостью синтаксиса". Вы делаете выбор в пользу второго?


                                      Кстати, насчет TS. Как думаете, вот этот код TS поймет как неправильный: function filterArray(a: any[]): number[] { return a.filter(i => typeof i === 'string'); }?

                                      Пока нет, а что?


                                      Такие логи — дополнительный ключ к пониманию, почему произошла ошибка и где ее искать.

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


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

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


                                      откуда тут взялось микро — не понимаю

                                      Редкий модуль превышает 3КБ исходников. И любой из них может не попасть в бандл, если не используется. Безо всяких роллапов и тому подобных костылей.


                                      Я имел ввиду не в рамках $mol, а как инструмент для решения класса задач.

                                      Что за "класс задач"?


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

                                      Это зачем? Чтобы всех запутать?


                                      Или, я хочу импортировать CSS в JS, например.

                                      Есть какая-то рациональная причина засовывать утку в зайца?


                                      Я хочу, чтобы моя сборка считала зависимостью не только JS/CSS файлы, но и статику, которые те используют.

                                      Зависимостью считаются все файлы в директории. Это одна из удобнейших особенностей MAM-архитектуры — оперирование не отдельными файлами, а целыми наборами файлов. Например, карта зависимостей "приветмира".


                                      а кто-то использует вообще Less/Sass/Stylus — и это их право

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


                                      оптимизировать стратегию их сборки и компоновки под нужды приложения

                                      Что конкретно вы хотели бы оптимизировать?


                                      Я хочу, чтобы сборщик умел кешировать и умел в инкрементальную сборку в development, чтобы было быстро

                                      Он это уже умеет.


                                      может быть умел hot reload

                                      Приложения на $mol запускаются достаточно быстро, чтобы hot reload не требовался.


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

                                      Сбросить пару файлов на диск — не такая уж и затратная операция.


                                      Если допустим, я напишу $mol_defer, но такой модуль не будет существовать — ваша сборка скажет мне об этом?

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


                                      Dependency Injection — механизм не явных зависимостей конечно. Но у него есть свои benefits, о которых много копий сломано

                                      Dependency и прочие injection в $mol делаются простым переопределением свойств при создании объекта. Получается весьма удобно. Есть, правда, и минус — реализация по умолчанию тянется в любом случае. Но я не думаю, что требование делать по отдельному интерфейсу на каждый класс стоит полученной экономии.


                                      Или ваше мнение не совпадает с большинством?

                                      Ага, так и есть. Но большинство ведь всегда право, да?


                                      Роману Дворнову, вот ничего не мешает рассказывать про basis.js, при этом не имея огромной аудитории как у React.

                                      Ага, у себя на сайте. А на конференциях то про CSSO, то про удалённую отладку.


                1. justboris
                  10.12.2016 14:57

                  Капля в море.

                  Сейчас проверил React 15.4.1
                  45.33 KB — в production-mode
                  63.25 KB — в development-mode
                  Разница на треть имеет значение.


                  Добавляют много разной иструментации и оберток, чтобы более явно указать на ошибку в пользовательском коде. Что конкретно — можно посмотреть в этом файле.
                  А еще warnings об использовании устаревших API, которые будут или уже удалены.


                  1. vintage
                    10.12.2016 19:50
                    -2

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


                    Ну и необходимость в этом инструментарии — следствие кривой архитектуры, с которой плохо дружат стандартные отладчики.


                    1. Anarions
                      12.12.2016 12:28

                      Реакт в дебаг-моде добавляет вещи которых нет в стандартных отладчиках — проверка типизации параметров в «шаблонах» (propTypes) — первое что приходит на ум, но вообще там много полезных инструментов.


                      1. vintage
                        12.12.2016 18:46

                        С проверкой типизации куда лучше справляется TS и Flow, которые не нужно "вырезать при релизной сборке". Какие ещё там есть "полезные инструменты" и что они забыли в одном бандле с остальным кодом?


                        1. Anarions
                          13.12.2016 07:30

                          TS справляется «слишком» хорошо, и не всем нравится типизация повсеместно. React решает этот вопрос более гибко. Они не в банде с основным кодом — они в дебаг-сборке. Собираете прод версию — и всё нормально. В компилируемых языках вас билд-конфиги тоже смущают?


              1. justboris
                10.12.2016 14:58

                Код им и так доступен.

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


                1. vintage
                  10.12.2016 19:57

                  Может вы ещё и код обфусцируете и вешаете намертво браузер при открытии отладчика?


            1. bigslycat
              14.12.2016 06:41

              Если очень нужно, то можно и не включать отладочный код в общий бандл, а подключать по запросу. А доступ к самому файлу можно ограничить на бэкенде, хоть на уровне приложения, если там такое предусмотрено, хоть как-либо ещё.


      1. Shifty_Fox
        09.12.2016 18:50
        +4

        Странно, на ноутбуке (i7 конечно, но мобильный и 2013 года), сборка сотен js файлов с babel занимает полсекунды. Номера строк у меня всегда совпадают, это же source maps, для этого они и нужны. Как то же люди работают на type script и coffee script. Как ни крути, браузер содержит в себе jit компилятор js, который конечно быстрее babel, но на мой взгляд логично заниматься импрувом производительности babel, а не пытаться избавляться от него. В конце концов, еще на development можно сделать ту же inline транспиляцию.


        1. Alternator
          09.12.2016 19:46

          Подскажите, пожалуйста что такое inline транспиляция.
          А то гугл выдает ссылку на ваш же коммент.


          1. Shifty_Fox
            10.12.2016 00:54

            Я имел ввиду подключить в браузер babel, чтобы он компилировал js на лету.


        1. faiwer
          09.12.2016 21:42
          +7

          Не знаю как вы готовите sourceMap-ы и транспайлеры, но у меня они пока что вызывают только боль. Особенно в купе с regenerator-ом. Попросту я уже привык, что Chrome Dev Tools часто показывает погоду на Марсе, вместо реальной строки при отладке, не позволяет трассировать код без боли (например уходит в дебри какой-нибудь proxy-функции обёртки из babel-я), попросту падает иногда. А ошибки от JSX приходится отлаживать с console.log, т.к. стек трейс всегда показывает всё что угодно кроме полезной информации, и остаётся только сама ошибка. Отдельную боль доставляет постоянно тут и там вылезающие ссылки в стек трейсах и ошибках на не smap-версии файлов (т.е. настоящие). В случае webpack-а они ещё и невыносимо большие (чёрт ногу в этих бандлах сломает). Ух… Я стал просто повсюду вешать console.log, привык к постоянным тормозам (webpack часто не успевает пересобрать достаточно быстро даже маааленький проект с зависимостями), и почти мёртвому debug-у. Радуюсь только возможности использовать async/await и jsx.


          В итоге склоняюсь к таким схемам:


          • gulp и транспайлинг файлов по одному в dev-режиме (раз в 100 быстрее), а webpack с bundle-ми на выходе на продакшне
          • и в правду подключить какой-нибудь jsx-строковый шаблонизатор и вообще работать без транспайлинга. А на прод всё так же webpack.

          Пока останавливает лень, меньшие возможности, и тот факт, что баги на production-е могут сильно отличаться от dev-версии.


          1. faiwer
            09.12.2016 21:46
            +1

            Хотя, с другой стороны, немного поработав со Scala, я понимаю, что ребята из мира Java готовы ждать и по 15 секунд на изменение и пересборку. Это у них норма. Это мы "скриптовики" разбалованы до-babel-ми временами. Но у java-разработчиков хоть stack-trace-ы не разъезжаются. А асинхронностью головного мозга они куда реже страдают, что упрощает отладку.


          1. gearbox
            09.12.2016 22:17
            +1

            >А ошибки от JSX приходится отлаживать с console.log, т.к. стек трейс всегда показывает всё что угодно кроме полезной информации, и остаётся только сама ошибка.

            Вот я создал ошибку:
            image

            Вот так я провалился (в typescript код, обратите внимание):

            image

            webpack, typescript, tsx, все дела. не то что бы я настаивал, но как бы — а что не так?


          1. Shifty_Fox
            10.12.2016 02:20

            Вы знаете, да, мне пришлось повозиться с source maps. Я использую browserify, babelify, uglify. А, и exorcist для извлечения source maps из bundle в отдельный файл. И в общем-то вся проблема с этим была именно в путях — нужно повозиться, поиграть с опциями путей, basePath к исходниками, чтобы source maps корректно их цепляли. Я потратил на это где-то день, зато теперь просто копирую настройки из проекта в проект.


      1. vintage
        09.12.2016 19:40

        Код, сгенерированный из шаблонных строк всё-равно ведь не будет "совпадать".


        1. faiwer
          09.12.2016 21:46

          Ну дык и JSX-код как монолит, разве не так?


      1. auine
        09.12.2016 22:12

        1) в дебаггере виден неизмененный сборщиком код, номер строк будет совпадать

        лол что? sourcemap не слышал?
        Ну дык и JSX-код как монолит, разве не так?

        Какие проблемы? Это же не php с html :)


    1. salex772
      10.12.2016 16:08

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


  1. norlin
    09.12.2016 16:55
    +8

    Второй вариант даже в таком простом примере выглядит намного понятнее

    Вот этот jsx – главное, что отталкивает лично меня от React. Всю мою сознательную дейятельность JS-разработчика вокруг твердили "нехорошо смешивать логику и представление". А тут вдруг – новая мода – давайте будет писать html прямо в js коде!


    1. jMas
      09.12.2016 17:00
      +6

      Потому что React-компонент — это и есть View, конечно его можно перемешать с данными, но это на усмотрение самого разработчика. Держите данные в сторе — это будет Model, а все представление в React-компонентах — это View / View. На вход подаешь данные — получаешь видоизмененное представление, все как в PHP templates с if, foreach.


      1. norlin
        09.12.2016 17:23
        -4

        render() {
            return <div className='block'>
                Text of block
            </div>;
        }

        В данном примере, в моём понимании, "представление" это только следующая часть:


        <div className='block'>
            Text of block
        </div>

        А вся остальная обёртка – это, грубо говоря, логика (т.к. там может быть любой js код).


        Но это лишь моё видение, не более того.


        1. jMas
          09.12.2016 18:04
          +3

          PHP template:


          <?php foreach ($items as $item): ?>
          <a href="<?= $item->url; ?>"><?= $item->name; ?></a>
          <?php endforeach; ?>

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


          В React-приложении:


          render() {
              const items = this.props.items;
              return items.map((item) => <button type="button" onClick={ this._handleClick }>{ item.name }</button>);
          }

          вы сами занимаетесь обработкой логики нажатия на кнопку, браузер лишь показывает вам результат который apply-ит React.


          React полезен для SPA, потому что позволяет проще контролировать изменение контента, дает больше контроля над тем, что происходит в вашем приложением, дулает обновления DOM практически безболезненными. Но это не значит что его нужно пихать везде.


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


          1. norlin
            09.12.2016 20:02

            <button type="button" onClick={ this._handleClick }>
            вы сами занимаетесь обработкой логики нажатия на кнопку

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


            1. faiwer
              09.12.2016 21:49
              -1

              Вот это и есть смешение логики и представления

              Времена меняются. Теперь это норма. Во всяком случае для SPA.


              Что делать, например, если мне на кнопку надо несколько обработчиков повесить?

              Вы знаете, но с React и другими реактивными системами, необходимость сразу нескольких обработчиков на один элемент и одно событие ? событие исключительной редкости. Природа сего явления та же, что и у отсутствия необходимости $.fn.live. С таким подходом этого просто не нужно делать. Области влияния, видимости и прочего разделены так, что нет необходимости в этом.


            1. auine
              09.12.2016 22:17
              -5

              Что делать, например, если мне на кнопку надо несколько обработчиков повесить?

              Иди прочитай книжечку по js и не пиши ересь
              Если тебе надо там несколько обработчиков на клик, тебе никто не мешает их вызвать на onClick


            1. mrLk
              09.12.2016 22:50

              А в чем здесь смешение логики и представления? Как мне кажется это наоборот, позволяет отделить мух от котлет. Фактически работа представления заключается в предоставлении интерфейса для отображения данных и оповещение контроллера о событиях, в то время контроллер совершенно не обязательно знать внутрянку вью — простые хтмл-инпуты там, какие-либо богатые компоненты или просто заглушка в тестах. То есть this._handleClick теоретически может подготовить данные при необходимости, или сразу оповестить контроллер о неком событии. Если по простому, то в контроллере это может выглядеть примерно так:

                 doAddUser(fData) {
                     /* validate data */
                     /* other work */
                 } 
                 let tForm = new EditUserView(tUserData, this.doAddUser)
              


              При этом контроллеру совершенно всё равно, он не должен быть в курсе того, какие элементы используются, Button это или кнопки вообще нет, и событие срабатывает по нажатию на клавишу ввода — это не работа контроллера. И вью, при этом, не содержит никакой другой логики, кроме логики представления.


              1. jMas
                10.12.2016 03:38

                Контроллер в SPA — это Action Creators + Flux / Redux сторы — они ответственны за создание и мутацию состояния приложения, React-компоненты просто (в идеале) должны заниматься репрезентацией того что вернул стор. Вот банальное разделение логики, данных и отображеня.


                1. VolCh
                  10.12.2016 03:47

                  Где, по-вашему, должна быть логика отображения?


                  1. jMas
                    10.12.2016 04:10

                    Что вы имеете ввиду под "логикой отображения" — реакцию на "Button Click"?
                    Клик по Button создает Action, который попадает в стор, мутирует его состояние, состояние из стора попадает в React компонент, применяется новое состояние. Судя по всему, логика реакции на "Button Click" находится в сторе.
                    Но конечно же, какая то мелкая логика будет присутствовать в React-компонентах.


                    1. mrLk
                      12.12.2016 09:44

                      Имменно про обработчик клика мы и говорим, см. комментарий @norlin. this._handleClick в данном случае и должен/может подготовить данные/запустить событие. Аналогично можно рассмотреть простую html-форму, обычно ее работа принимается как должное, но если присмотреться, там есть и выбор файлов для <input type='file' .../> и подготовка данных, с погрузкой их в хттп-запрос и т.д. Так или иначе это остается логикой представления и свои аналоги this._handleClick там присутствуют.


            1. js605451
              10.12.2016 02:37
              +2

              Что делать, например, если мне на кнопку надо несколько обработчиков повесить?

              Написать _handleClick таким образом, чтобы он дёргал несколько обработчиков. Вы вопрос неправильно ставите. Обработчик всегда один: нажатие кнопки означает, что юзер "даёт команду" вашему аппликейшну. Как вы там будете эту команду обрабатывать — одним хендлером или десятком — ваше дело. Кнопка со своей задачей справилась — донесла до вас что её нажали.


    1. GIum
      09.12.2016 17:03
      -8

      Всю мою сознательную дейятельность JS-разработчика вокруг твердили «нехорошо смешивать логику и представление»

      А зачем Вы себе взяли это утверждение за догму? Разработчики из facebook обосновали почему такой подход в сегодняшних реалиях не всегда работает.


      1. norlin
        09.12.2016 17:26
        +2

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


        1. auine
          09.12.2016 22:19
          -6

          Логично и удобно ложить в разные файлы декларатив и императив? Боже ну ложи если тебе так удобней. Но я не вижу вообще никакой необходимости в этом, так как все четко и в одном файле компонента. Композируй их как хочешь. Как это вообще может быть удобно? jquery бой


    1. gearbox
      09.12.2016 17:06
      +7

      >нехорошо смешивать логику и представление

      Нехорошо смешивать БИЗНЕС логику и представление. Логику вью и само вью смешивать можно и нужно.


      1. norlin
        09.12.2016 17:21
        -4

        В том-то и дело, что в представлении не должно быть никакой логики, помимо отображения данных. А вот какие данные и где отображать – это должно решаться в коде. Но это лишь моё мнение и я не хочу устраивать холивар на тему.


        1. faiwer
          09.12.2016 21:53
          +3

          Не представляю себе как можно организовать отображение достаточно сложного шаблона вообще без логики. Если вырезать из шаблонизатора все логические вветления, то вы просто будете вынуждены эту часть логики отображения данных выносить из шаблона на уровень выше. И, вероятно, это будет то же место, где у вас и модель лежит. Ерунда же получается. Чего вы этим добились, кроме как испортили себе модель?


          Скорее в шаблонизаторах вредна возможность применения неодносложных выражений. Идеальный шаблонизатор полностью декларативен и достаточно прямолинеен.


          1. norlin
            09.12.2016 22:39
            -5

            В качестве примера, посмотрите на шаблонизатор DustJS, например. Там есть некоторая логика (if, циклы), но она используется исключительно для отображения ("есть данные – показываем одно, нет данных – другое").


      1. vintage
        09.12.2016 20:00
        +2

        Также не стоит смешивать императивное и декларативное описание, а не только доменную и презентационную логику. Если смешивать, то теряются все преимущества декларативного описания. Например, возможность применять различные логики к одному и тому же описанию. Например, из одного и того же декларативного описания можно получить как минимум:


        1. Код для отображения данных.
        2. Файл локализации.
        3. Информацию о структуре для визуального конструктора.
        4. Список и типы параметров.
        5. Список зависимостей.


      1. vintage
        09.12.2016 22:46

        -


    1. k12th
      09.12.2016 17:16

      Я вот открыл для себя VueJS и рад.


    1. js605451
      10.12.2016 02:34
      +1

      Всю мою сознательную дейятельность JS-разработчика вокруг твердили "нехорошо смешивать логику и представление"

      1. Вы путаете "логику" и "бизнес-логику". Спрятать кнопку или показать в зависимости от аутентифицированности пользователя — это как раз "логика представления". Будет это if внутри jsx, или это будет непонятная закорючка в handlebars — вообще никакой разницы.


      2. Вы путаете "представление" и "мой любимый шаблонизатор". Представление — это часть кода, которая "оформляет" ответ прежде чем ответ уйдёт к тому, кто прислал запрос. Код сериализации объекта в JSON — это такое же представление, как и натягивание модели на шаблон с целью получить HTML. Даже больше — когда вы пишете код, который через HTTP возвращает 200 — это тоже представление.


  1. ThisMan
    09.12.2016 17:12
    +4

    С нынешней схемой развития js, всегда будет необходимость в babel-e (других транспиляторах).Каждый раз всегда будет esX, которым хотят пользоваться, но которые еще не поддерживается в браузерах. К тому же, думаю и babel не такие дураки. уже сейчас есть babel-preset-env, где можно указать версию браузера, для которого билдится код и так уменьшить количество изменений.


    1. faiwer
      09.12.2016 21:56

      Лично я, искренне надеюсь, что разработчики браузеров пойдут на встречу хипстерамweb-программистам и позволят, хотя бы с каким-нибудь флагом при запуске браузера, примешивать что-то своё в runtime-код загрузки скриптов. Тогда эти трансформации можно будет делать на лету, да ещё и на каком-нибудь быстром c++. Это сильно бы упростило работу :)


      1. norlin
        09.12.2016 22:41

        WebAssembly в процессе разработки/внедрения, например.


        1. staticlab
          10.12.2016 16:28

          А причём тут WebAssembly?


          1. norlin
            10.12.2016 18:14

            Тогда эти трансформации можно будет делать на лету, да ещё и на каком-нибудь быстром c++

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


            1. staticlab
              10.12.2016 22:13

              И всё равно ведь придётся компилировать :)


              1. norlin
                10.12.2016 22:41

                Ну можно один раз скомпилировать код, который будет быстро компилировать скрипты на лету, вместо того, чтобы каждый раз перекомпилировать скрипты "вручную" :)


                1. staticlab
                  10.12.2016 22:42
                  +1

                  Но ведь это, по сути, будет тот же webpack-dev-server, только написанный на wasm.


      1. staticlab
        10.12.2016 16:29

        webpack-dev-server и сейчас делает пересборку на лету


        1. faiwer
          10.12.2016 17:06

          Вот именно от него и хочется убежать. Мне сильно не нравится результат.


  1. Frozik
    09.12.2016 17:20
    +4

    Честно говоря не вижу профита, одни минусы:

    • Дополнительная зависимость
    • Дополнительное потребление памяти, под кеширование + процессорное время на компиляцию
    • Сокрытие кода JSX от линтеров
    • Вопрос с поддержкой Typescript / новых фич JS
    • Ну и вопрос с отладкой


    1. dyakov
      09.12.2016 17:51
      +1

      Дополнительная зависимость

      Пакет имеет только одну зависимость — на пакет для парсинга, который не имеет зависимостей. В сумме около 500 строк кода, в сжатом виде около 2кб
      Дополнительное потребление памяти, под кеширование

      Не очень много, какие-то несколько мегабайт на тысячу шаблонов. Сравните с гигабайтами, которые потребляет запущенный вебпак.
      Сокрытие кода JSX от линтеров

      Вопрос времени — появятся плагины к линтерам для парсинга кода в шаблонных строках.
      Ну и вопрос с отладкой

      Парсер не молчит об ошибках а кинет exception. Вы знаете удобный способ отлаживать выход jsx? Или вы про ошибки во время транспиляции?


  1. vintage
    09.12.2016 22:54
    -1

    Не хотите ли добавить свою реализацию в сей бенчмарк?


  1. EugeneGavriloff
    10.12.2016 14:05

    Прочел статью, посмотрел поддержку ES6 на ПК и мобильными устройствами. На мобилках всё печально до сип пор, плюс ко всему, лично я уже пользуюсь ES Next, поэтому отказаться от транспиляции, похоже никогда не представится возможности xD