Сейчас формируем некий Isomorphic React App бойлерплейт на следующие 12 месяцев, с которым можно быстро стартовать новые проекты. Пока видим такой набор:
1. React 15.
2. На сервере — Node.js и Express.
3. CSS modules и isomorphic-style-loader для автоматической генерации Critical CSS при Server-side Rendering. Или всё-таки JSS?
4. Redux для взаимодействия внутри приложения. Или всё-таки Relay?
5. Модульное тестирование через AVA и Enzyme. Или всё-таки Jest с его автоматической генераций mock-объекта Browser?
6. UI-тестирование через Nightwatch.js + Browserstack.
7. Переводы через react-intl и react-intl-translations-manager.
8. Автоматическое определение языка на сервере через пакет accept-language.
9. Автоматическое определение геопозиции через пакеты maxmind и ipaddr.js.
10. Изоморфный логгер на базе node-bunyan.
11. react-document-title для динамического переключения заголовка вкладки.
12. isomorphic-fetch для отправки HTTP-запросов (“AJAX”).
13. webpack 1.x для сборки. Или всё-таки webpack 2?
14. webpack-dev-server и webpack/hot/dev-server для Hot Module Reload.
15. Long-term Caching статических ресурсов (например: /assets/logo-8cdab5da.png).
16. parallel-webpack для ускорения сборки JavaScript bundle для каждого языка перевода (например: 5 разделов и 10 языков = это уже 50 JavaScript bundles).
17. webpack DllPlugin для оптимизации размера JavaScript bundle.
18. react-router-redux в качестве роутера.
19. ESLint и eslint-config-airbnb с небольшим изменением — не использовать точку с запятой.
Какие пункты можно изменить? Какие добавить? Что можно сделать лучше? Поделитесь своим мнением в комментариях.
В ближайшие дни список может измениться. Да, что там, я обещаю — он изменится, поэтому следите за обновлениями на GitHub.
Комментарии (103)
karudo
29.08.2016 19:50+1Зачем ещё один?
Вот есть хороший, от создателя Redux: create-react-appNeXTs_od
29.08.2016 20:35+2Вы вникали в суть статьи? Или в суть create-react-app?
create-react-app это для совсем новичков, он урезан по самые яйцаkarudo
30.08.2016 09:55+1Вообще прежде чем выбирать набор библиотек на следующие 12 месяцев, нужно подумать, чем же мы собираемся заниматься в ближайший год. Много ли создадим изоморфных приложений? Или react будет нужен только на клиенте, а на сервере будет java или, прости господи, php?
В этом то и есть самое главное достоинство create-react-app, что урезан. Дает необходимый минимальный базис и далее есть возможность надстроить теми инструментами, которые нужны и вживить почти в любой проект.
Ну и кстати, там в документации по create-react-app есть список альтернативных бойлерплейтов на любой вкус, и урезанных и нет.
saggid
29.08.2016 19:57+1Я до сих пор в шоке от того, какой сложный этот вебпак. Для своих проектов начал юзать System.js + jspm, вполне доволен. Конфигурировать раз в десять наверное проще, чем вебпак,. Единственное нарекание в сторону system.js builder'а бандлов — то что он не оптимизирует автоматически бандлы, как это делает вебпак, за этим приходится немного следить вручную. Но всё равно он как-то проще вебпака будет, профиты по сути те же самые, плюс нативная поддержка ES6+ синтаксиса из коробки без каких-либо настроек.
Gugic
29.08.2016 20:22Webpack 2 умеет ES6 imports из коробки.
saggid
29.08.2016 20:37Да я знаю что он много чего там умеет. Только конфиги его меня немного в жар бросают :) С System.js+JSPM получаешь всё то же самое, только как-то более просто и очевидно.
baka_cirno
29.08.2016 21:04А как ему скормить эти импорты, если Babel их в require транслирует? Вторым вебпаком не пользовался, но давно интересует.
Gugic
29.08.2016 21:08+1const babelSettings = { ... 'presets': [ ['es2015', {'modules': false}] ] ... };
baka_cirno
29.08.2016 21:18О, спасибо. Может попробую второй вебпак на своем домашнем проекте, раз такое дело.
k12th
29.08.2016 22:07+3У JSPM есть свои недостатки: мутные проблемы за корпоративной проксей, два пакетных менеджера в проекте, изоморфные либы надо ставить два раза, тянет кучу своего барахла. Как лоадер SystemJS очень клевый, гибкий и мощный, но JSPM вызывает смешанные чувства.
Я попробовал и для себя выбрал либо browserify, либо rollup. Webpack это ад какой-то, зачем я должен из JS импортировать картинки, да еще с конфигом, который Хищники для Чужих писали.
saggid
29.08.2016 23:03-2Какие-то натянутые за уши «проблемы». Не знаю насчет проблем с прокси: он там как-то по другому запросы делает чтоли при скачивании пакетов?) Другой протокол какой-то использует вместо http чтоли?
Какие два пакетных менеджера? Npm и jspm? Так, npm особо и не нужен, можно всё держать в jspm. Зачем ставить два раза изоморфные либы? Jspm позволяет без проблем запускать весь ваш js стек как на сервере, так и в браузере, никаких проблем.
Тянет кучу своего барахла. Ну это вообще что за претензия?) А что сегодня не тянет за собой ничего?
Кажется, вы просто мало его изучали, просто не поняли какие-то моменты. Меня jspm очень радует, у нас в текущем проекте один и тот же код спокойно работает и на сервере, и в браузере, и всё это в том числе благодаря jspm.
k12th
29.08.2016 23:37Другой протокол какой-то использует вместо http чтоли?
Представьте себе, таки да. Желаю вам никогда не понять, о чем я говорю.
Так, npm особо и не нужен, можно всё держать в jspm.
Сам jspm тоже держать в jspm?:)
А что сегодня не тянет за собой ничего?
jspm тянет это в билд, вот в чем проблема. Почему-то когда я использую, например, browserify, у меня не загружаются полифиллы на половину стандартной библиотеки nodejs.
Jspm позволяет без проблем запускать весь ваш js стек как на сервере, так и в браузере
Насколько я помню, с этим были какие-то проблемы. Возможно, их уже решили, конечно. Например, в версии 0.17… которая в бете уже год:)
Меня jspm очень радует, у нас в текущем проекте один и тот же код спокойно работает и на сервере, и в браузере, и всё это в том числе благодаря jspm.
Меня npm очень радует, у меня в куче текущих проектов один и тот же код спокойно работает и там и там, и все это благодаря npm:)
Честно сказать, вы правы, jspm я знаю плоховато. Но первое впечатление было такое негативное, что изучать глубже не захотелось. Да и в чем профит? Tree-shaking там из rollup, который доступен отдельно. Загрузка и транспиляция на лету? так это медленно, каждый раз все с нуля компилять, а в browserify инкрементальные билды есть.
saggid
29.08.2016 23:57-1Сам jspm тоже держать в jspm?
Давайте всё-таки поговорим о реальных проблемах.
Почему-то когда я использую, например, browserify, у меня не загружаются полифиллы на половину стандартной библиотеки nodejs.
System.js весь же построен на теме динамичной подгрузки любого контента из любого доступного источника, соответственно и всякие полифилы в себе он тоже держит. Я не вижу особой проблемы в этом, но при желании вы можете попробовать упаковать всё свое приложение в sfx-бандл, который будет содержать только самый минимальный набор необходимого кода в 1.4 кб. Ну, я в свою очередь в данный момент ограничиваюсь обычными бандлами, вроде всё нормально.
Насколько я помню, с этим были какие-то проблемы. Возможно, их уже решили, конечно. Например, в версии 0.17… которая в бете уже год:)
Изначально мы в своём проекте использовали ветку 0.16. Ну, не знаю, я конечно поковырялся пару дней, но в итоге вроде как завёл всё это дело. Потом перешли на ветку 0.17, с ней тоже пока всё хорошо, хоть оно и в бете, но никаких проблем пока не возникало.
Меня npm очень радует, у меня в куче текущих проектов один и тот же код спокойно работает
Ну, это понятно, что код работает. Кто-ж с этим спорит, что он как-то там "работает" :) Но вот когда возникает необходимость наличия динамической подгрузки всего и отовсюду, тут я лично в других библиотеках вижу всякие разные странные и сложные решения, когда System.js весь построен вокруг этого, что меня и прельстило.
k12th
30.08.2016 00:09Давайте всё-таки поговорим о реальных проблемах.
Давайте. Я пока не услышал, какие реальные задачи jspm решает.
соответственно и всякие полифилы в себе он тоже держит
Угу, ставим (к примеру) angular, jspm качает npm:crypto.js (к сожалению, код сейчас не доступен, но зависимости примерно такие по нелепости). Как это связано с динамической подгрузкой из любого источника?
Окей, может, как-то и связано. Но, например, requirejs, светлая ему память, точно так же мог все динамически подгружать из любого источника, но обходился при этом без стандартной библиотеки nodejs. Значит, все-таки что-то не так в консерватории.
Ну, это понятно, что код работает. Кто-ж с этим спорит, что он как-то там "работает" :)
Вот насчет jspm у меня такие ощущения. Как-то оно там, из глины и палок, работает.
Потом, не путайте, пожалуйста, systemjs и jspm. За «динамическую подгрузку из любого источника» отвечает все-таки первое. Второе обещает только frictionless browser package management, но в моем опыте это было ни разу ни frictionless.
k12th
30.08.2016 00:40+1Давайте, в общем, сойдемся, что вас jspm устраивает, а меня нет. Я вполне могу с этим жить:) Ну а если судьба столкнет работать над одним проектом, уж договоримся как-нибудь:)
saggid
30.08.2016 01:15Проблем нет, давайте) Впрочем, я не называл связку System.js+JSPM идеальным решением. В этом мире вообще такого наверное не может быть, чтобы всё сразу было идеально.
k12th
30.08.2016 10:39Серебряной пули нет, это точно, поэтому просто выбираем фломастер (или кактус, как повезет) по вкусу:)
ArmorDarks
30.08.2016 17:04+1Давно используем JSPM в своем проекте и тоже весьма довольны. К сожалению, правда, что JSPM не без своих недостатков. В частности, к организации конфигов и путей в бете 0.17 много вопросов...
saggid
30.08.2016 18:03Какие вопросы по теме конфигов? На мой взгляд, в ветке 0.17 наоборот всё хорошо сделали в этом плане. По крайней мере, теперь наша личная конфигурация не смешана с конфигурацией и зависимостями других библиотек, которые мы просто подтягиваем из остального мира. Плюс, для браузера отдельный файл — тоже хорошо, там весь этот сгенерированный кеш зависимостей лежит, считай тоже не мешается в основном конфиге. Напишите какие у вас вопросы, возможно смогу что-то объяснить из своей практики.
Единственное что я не использовал в jspm 0.17 — это package configuration. Как-то не вижу смысла использовать его, когда наш код проекта не будет делиться на несколько пакетов.
heilage
29.08.2016 19:57+5…
47. Write some code :(
Какая разница, каков состав boilerplate, если его все равно необходимо осваивать? Оптимальный boilerplate для старта новых проектов — всегда и исключительно — _знакомый_ конкретному разработчику или команде boilerplate. Иначе старт может, мягко говоря, затянуться.Keyten
30.08.2016 10:23Некоторые инструменты (например, React) достаточно несложны и могут быть освоены в процессе. Ну лично я с ним так и познакомился )
Но перебарщивать с количеством незнакомых инструментов действительно не стоит.heilage
30.08.2016 10:31+2Говорить, что react несложный, это примерно как говорить, что java несложная. Несложно-то несложно, только без кучи дополнительных обвязок толку мало.
Akuma
29.08.2016 20:08+3О, появился второй вебпак. Надо будет глянуть. Кто-нибудь пробовал? Есть существенные улучшения?
В остальном статья бессмысленная. На год вперед что-то планировать в мире JS? Да тут через месяц может все резко поменяться.Gugic
29.08.2016 20:23Нативный ES6 imports, с оптимизациями, чанками и прочим, ну и по мелочи.
Akuma
29.08.2016 20:25Оу, так он еще бета официально. Ну посмотрим что получится.
Единственное, что в первом не нравится: большой проект долго собирается в продакшн.AlexanderG
30.08.2016 10:28Да и маленький тоже… Сборка Java EE бэкенда из дюжины модулей в четыре раза быстрее, чем небольшой SPA-фронт. Причем даже если все файлы уже лежат в кеше ОС.
Akuma
30.08.2016 10:301 секунда или 0.1 секунда — мне, например, нет разницы.
А вот 10 секунд и 100 секунд — уже большая разница.
В моем случае как раз второй вариант происходит на больших проектах.raveclassic
31.08.2016 00:42+1Попробуйте паковать неизменяющиеся куски между сборками (вендроные либи и т.п.) в DLL (DllPlugin, DllReferencePlugin). Нам очень сильно помогло.
CommonChunksPlugin не подходит, так как отрабатывает на каждой сборкеstas404
31.08.2016 01:46+1У меня тут ссылочка, как раз, под рукой оказалась:
Optimizing Webpack build times and improving caching with DLL bundles
Yozi
29.08.2016 21:09На год что-то планировать
А лучше совсем не планировать? Комменты к этой статье отлично зайдут как ответ на вопрос «как начинать здесь и сейчас?»Akuma
29.08.2016 21:14Не выдирайте слов из контекста.
«На год что-то планировать в мире JS» — вот полная фраза.
Реакту всего года 3 с копейками. Половине инструментов перечисленных в статье и того меньше. Ну не получится тут выбрать состав на12 месяцев. Он все равно через месяц сменится, если конечно захочется поддерживать актуальное состояние.
Именно это я и имел ввиду.Yozi
29.08.2016 21:31Да не, на год вполне еще можно планировать. Правильные технологии за год не протухнут окончательно, хоть и не будут уже вызывать энтузиазма.
alibertino
29.08.2016 20:18https://github.com/kriasoft/react-starter-kit неплохой и популярный starter kit для изоморфного реакта.
Yozi
29.08.2016 20:18+32. На сервере — Node.js и Express.
Почему не Koa? Точнее даже так: Koa
3. jss, и вообще локальные стили — хорошо
13. Webpack2 имеет приятные фичи, типа оптимизаций размера, из коробки
19. Чем точка с запятой не угодили? Жду развёрнутого увлекательного ответа для дискуссииNeXTs_od
29.08.2016 20:393. Локальные стили норм, но не инлайновые.
В issues material-ui люди бесятся от того как инлайновые стили тормозят рендеринг страницы
19. Лишний символ, без которого всё и так будет работать, зачем он?Gugic
29.08.2016 20:43+119. Для того, чтобы людей которые будут сопровождать ваш код не коробило.
NeXTs_od
29.08.2016 21:14+4let doThis = ({some}) => console.log(some)
let doThat = ({some}) => console.log(some);
В корне меняет делоGugic
29.08.2016 21:19В корне может и не меняет, но на больших объемах обеспечивает стабильное жжение в области поясницы у людей, которые пришли из менее свободных языков. А таких немало.
Плюс если вы работаете не один и принципиально не ставите точек с запятой, то ваши коллеги с большой долей вероятности будут их ставить, что приведет к неконсистентности кода в целом.
Конечно можно решить вопрос lint'ом, но в этом случае некомфортно (в моей личной статистике) будет все-таки большинству.
Yozi
29.08.2016 21:21+2const myFn = function () { alert("Surprise!"); } // <-- No semicolon! (function () { //... })();
NeXTs_od
29.08.2016 21:24;(function () { //... })()
привычка писать IIFE таким образом уберегает от подобных проблем
vintage
29.08.2016 21:26-1const myFn = function () { alert("Surprise!"); } // <-- No semicolon! void function () { //... }()
Yozi
29.08.2016 21:37void хорош, но довод был в целом не про то, что мы можем как то писать или не писать, а про то как писать так, чтобы не рисковать неоднозначной трактовкой кода.
Боюсь только тема слишком холиварная, а рассуждений обеих сторон вполне хватит на stackoverflow в тематических вопросах.
poxu
29.08.2016 23:35Вот в джаваскрипте точку с запятой действительно не стоит пропускать. Потому, что иногда её пропуск может привести к неожиданным результатам. Но вообще в стабильном языке отсутствие точки с запятой — добро.
Yozi
29.08.2016 21:00+23. Так тож не инлайновые, а локальные. Совершенно незачем каждый раз заново компилить css, поэтому тормозить совсем нечему, достаточно вынести stylesheet в отдельный файл.
19. Не фанат штучек в стиле «смотри как могу!» и «и так работает»
yefrem
30.08.2016 11:38+3Со временем пришел к выводу, что единственно правильный вариант чего-либо, где разные варианты подходят и работают (точки с запятой, скобки, именование переменных и т.д.) — тот, который принят в сообществе. На этом закончил свои метания в подобных вопросах раз и навсегда, чего и вам желаю.
vintage
29.08.2016 21:22Локальные стили — хорошо, пока пишешь один модуль. Когда исследуешь чужой легаси код и работаешь с кучей модулей одновременно, лучше иметь глобально уникальные имена.
Yozi
29.08.2016 21:26+1О, можно подробнее развить мысль? Мне глобальные переменные как раз таик неприятны из-за возможных конфликтов имён, тогда как локальные стили позволяют мне с большой долей уверенности подключать компоненты из разных источников, написанных разными людьми и не бояться что они переопределят стили друг друга
vintage
29.08.2016 21:49+3Это всеобщее заблуждение, что локальность как-то спасает от конфликтов. От конфликтов спасают пространства имён. Всё, что даёт локальность — возможность вместо длинного глобально уникального имени использовать короткое локальное.
justboris
30.08.2016 14:23Дали вам, например, задачу подвинуть кнопку на 5px влево в одном легаси-проекте.
А там css-модули и html выглядит так:
<div class="panel_3LqQH658"> <button class="button_2OhV6WSs"> </div>
И где в исходниках искать концы этой
button_2OhV6WSs
— непонятно.Yozi
30.08.2016 14:34Спасибо, теперь понятно ваша проблема. Если модули чисто от CSS, то действительно боль может выйти, согласен, но в случае того же React этот модуль должен был импортироваться там же, где и объявляется сам компонент, т.е. в общем то ищем где рендерится эта кнопка, а там уже и найдём концы.
import styles from './styles'; // <= Здесь концы ... render(){ return ( <div class={styles.panel}> <button class={styles.button}/> </div> ); }
justboris
30.08.2016 17:06Так в этом моя проблема и есть. Как я найду, какой компонент рендерит этот html, если исходного кода много и я в нем не ориентируюсь?
Обычно я всегда по css-классам и ищу, потому что они уникальные и в исходниках выглядят так же как и на странице.
alibertino
30.08.2016 17:09Это к вопросу именования React-компонентов и инструментов.
justboris
30.08.2016 17:19React-devtools показывает displayName компонента, оно может быть неуникальным.
К тому же, если нет проблем с именованием React-компонентов, то откуда они возникнут в названиях css-классов?
alibertino
30.08.2016 18:01К тому же, если нет проблем с именованием React-компонентов, то откуда они возникнут в названиях css-классов?
Вроде речь шла не о проблемах именования, а о конфликтах? Одно дело разбираться с одинаковыми displayName у реакта, которые ни на что по сути не влияют, другое дело искать пересекающиеся наложенные стили.
Yozi
30.08.2016 17:49Для этого source maps существуют, которые покажут где был создан
.myClass_test-2hscR
из:local(.myClass)
Если этого недостаточно, то можно так:
https://github.com/webpack/css-loader#local-scope
You can configure the generated ident with the localIdentName query parameter (default [hash:base64]). Example: css-loader?localIdentName=[path][name]---[local]---[hash:base64:5] for easier debugging.
Что означает буквально следующее: вы можете собрать отладочную версию хоть с вот такими классами
.app-components-test---myClass---2hscR
DexterHD
29.08.2016 20:19+1Видно же, что этот стек рассчитан на «Лендинги» и прочие TODO проекты.
Ибо для более менее серьезного проекта 12 месяцев — это 4-6 итераций разработки и пара другая релизов. И стек выбирают на 3-5 лет как минимум, а не на 12 месяцев. С другой стороны для мира JS планирование хотя бы на год это уже большое дело.Yozi
29.08.2016 21:04Не видно, ждём статью с единственно правильным стеком. Нельзя просто закритиковать что-то и аргументировать словами «это все знают».
DexterHD
29.08.2016 23:02+3Разве я что-то упоминал о «единственно правильном» стеке? Нет.
Я сказал о том, что оценка из расчета в 1 год слишком недальновидна для более менее среднего размера проекта.
Для «лендингов» и простеньких заказных сайтов со сроком разработки 2-4 месяца вполне себе нормально.
Для среднего размера интернет проекта со временем жизни 2-5 лет, оценка из расчета «выберем на год а там посмотрим» приведет к тому, что кому то придется заплатить большие деньги за переписвание всей системы с нуля раз в 12 месяцев.
А так свое судение о размере проектов я сделал исходя из статьи, а точнее преложения:
… на следующие 12 месяцев, с которым можно быстро стартовать новые проекты.
… быстро стартовать новые проекты — предполагается что в течении года их будет как минимум несколько — значит вряд ли они будут крупными.Yozi
30.08.2016 00:12этот стек
Окей, первоначально воспринял коммент как критику непосредственно перечисленных в нём проектов. Если же воспринимать с позиции "автор топика собирает этот стек для проектов на год (что всё равно не легко с учетом постоянных хайпов)", то да, полностью согласен
ncix
29.08.2016 21:59+319 инструментов чтобы создать лендинг? Девятнадцать, Карл! Нет с веб-разработкой что-то не так…
DenimTornado
30.08.2016 09:32+1Можно и в блокноте набросать, тут вопрос для чего. Если продавать будет большая красная кнопка по среди экрана, то больше ничего и не надо и работать будет на IE6. Так что в данном случае цель оправдывает средства.
ncix
30.08.2016 09:42+1Так вот и я о том же. У меня в проекте просто PHP5, MySQL, CSS, JS, кое-где jquery да куски древнего CI. И нет никаких проблем с разработкой — проект развивает один(!) человек. И все это прекрасно решает проблемы заказчика и приносит мне деньги.
Вопрос в том, какая экономическая мотивация у новых проектов для использования такого зоопарка инструментов? Или это просто фан и любопытство разработчиков?wispoz
30.08.2016 10:57+1Думаю все от проекта зависит, чем больше хочется свисто-перделок, тем ближе к вот таким наборам.
fijj
30.08.2016 11:38+2Это модно.
Andre_487
30.08.2016 12:19Скорее это идеология npm – если это есть в репозитории – не пиши заново. Все модули маленькие и выполняют единственную задачу. В какой-то мере опасно, но удобно и быстро.
В тёплые LAMP'овые времена в проектах не было такого количества мелких зависимостей – всё писалось самостоятельно.
MrCheater
29.08.2016 21:31+512. isomorphic-fetch для отправки HTTP-запросов (“AJAX”).
Имею неблагоприятный опыт работы с isomorphic-fetch и в целом с Fetch API.
Стандарт кривой и ничего толком не умеет, даже работать с query парамметрами [пруф. http://stackoverflow.com/questions/35038857/setting-query-string-using-es6-fetch-get-request/35039198#35039198 ]
А когда нужно писать изоморфный код, возникают еще и проблемы сheaders["Authorization"]
иbaseUrl
.
Рекомендую axios. Там всё очень круто и удобно
napa3um
29.08.2016 22:10Для работы с fetch API предполагается использование вспомогательных объектов URL, URLSearchParams и FormData для формирования адреса с query-параметрами и тела запроса.
https://developer.mozilla.org/ru/docs/Web/API/Fetch_API
https://developer.mozilla.org/ru/docs/Web/API/URL
https://developer.mozilla.org/ru/docs/Web/API/URLSearchParams
https://developer.mozilla.org/ru/docs/Web/API/FormData.
https://toster.ru/q/344956#answer_865910MrCheater
30.08.2016 00:29+1Да — я читал про это. И от этого чтива у меня слезы на глазах наворачиваются — каждое с голубиное яйцо…
Вместо того, чтобы сделать API, которое можно, не напрягаясь, использовать всегда и везде — сделали еще одно неудобное API, вокруг которого будут и дальше писать десятки и сотни разных оберток. И в каждом проекте будет своя — не такая как в других…
А ведь им ничего не мешало сделать по-нормальному
Miraage
29.08.2016 22:58+2Тоже долго не мог определиться с библиотекой для отправки http запросов — остановился на Axios.
Поверх него сделал обертку для группировки get/head/delete, put/post запросов — восхитительно вышло.
visortelle
29.08.2016 23:54Насколько я знаю, в axios нет нормального способа прервать запрос. В superagent можно сделать req.abort(). В fetch тоже можно. В axios — нет. Если не прав — поправьте.
heilage
30.08.2016 05:15+1В fetch — нельзя. https://github.com/whatwg/fetch/issues/27 Ибо cancelable promises еще не завезли. Возможно в каких-то имплементациях и можно, но это явно отсебятина, поскольку спек еще даже не драфт. Так что кому нужны отменяемые запросы — да, superagent почти единственный выбор, если не хочется возиться с низкоуровневым доступом.
Leopotam
29.08.2016 23:50+3Andre_487
30.08.2016 12:22А почему mobx?
Leopotam
30.08.2016 12:34Потому что банально быстрее на соизмеримом функционале (в redux-е может получить похожее быстродействие только путем тонкой ручной настройки), не иммутабельный стейт (меньше затраты по памяти на развесистых приложениях), меньше кода по обслуживанию (декораторы). Ну и вообще — почему redux? Исключительно из-за хайпа?
Strate
30.08.2016 21:21Соглашусь с вами по поводу mobx — из коробки отличная производительность, отсутствие необходимости постоянно нормализовать/денормализовать сторейдж объектов доменной модели, а также минимум бойлерплейта — отличный повод сменить redux.
Riim
30.08.2016 22:22Посмотрите на cellx, почти в 10 раз быстрее mobx-а, в остальном единственное значимое отличие — декораторы сделаны отдельным модулем. Коннектор к реакту здесь.
Strate
31.08.2016 11:19Ознакомился поверхностно, выглядит неплохо, особенно производительность. Попробуйте обновить mobx до 2.5 версии и провести тест ещё раз — авто обещал увеличение производительности в нём.
vintage
31.08.2016 12:00В реальных приложениях глубина зависимостей редко превышает 10. Максимум — 100, если использовать архитектуру в духе реакта, где родительский компонент зависит от дочернего. Так что эти бенчмарки — ни о чём. Помнится мы с автором обсуждали этот вопрос, и я даже вносил патч в jin-atom, чтобы не было проседания "производительности" на больших глубинах, но он продолжает с завидным упорством вводить всех в заблуждение.
Riim
31.08.2016 12:49Помнится мы с автором обсуждали этот вопрос,
обсуждали и я уменьшал число слоёв с увеличением числа ячеек в каждом, для библиотек не умирающих на этом тесте (все кроме Knockout, Kefir.js и Matreshka.js) соотношение результатов не менялось, просто усложнялся код бенчмарка, поэтому для простоты повторения оставил как есть. Цель теста как раз отсечь библиотеки имеющие эту ловушку производительности и спокойно сравнивать уже оставшиеся (другие ловушки либо не так критично убивают производительность, либо почти невозможны в реальных приложениях).
вносил патч в jin-atom
я тоже знаю как внести патч в cellx что бы он стал в 3 раза быстрее заодно просев в некоторых других тестах (выложен только один из примерно 10).
vintage
31.08.2016 14:31Покажите реальное приложение, где нужны хотя бы 1000 слоёв.
Мой патч не вносил никаких проседаний.
Riim
31.08.2016 17:28реальное приложение
я тоже люблю поговорить про реальные приложения, особенно когда это касается каких-то view-фреймворков, но что касается cellx-а — я особо не пытаюсь привязать его только к реалиям сегодняшнего фронтенда, забивая при этом на любые проблемы возникающие за пределами этих реалий, я пытаюсь создать некую идеальную реализацию с самым минимумом ограничений и способную хорошо работать в том числе в любых нестандартных ситуациях: нужно бешенное число слоёв — пожалуйста, какие-то изменения ячеек прямо внутри расчёта предыдущих изменений — сколько угодно (прошлый раз вы тоже говорили, что такого в реальных приложениях массово не случается, но в более ранних версиях Rionite, когда он ещё на morphdom работал, вся развёртка компонентов происходила как раз во время расчёта уже случившегося изменения, при этом происходило как массовое создание ячеек, так и их массовое изменение и всё это в идеале отрабатывало, как видите может и что-то нестандартное пригодиться), множественные изменения единичных ячеек — без проблем, всё красиво схлопнется в одно событие с единичным изменением в dom-дереве (кто-то говорил, что это плохо и хочется полного контроля над всем случившимся, какие проблемы, в evt.prev полная история всего что схлопнулось). И так далее.
Я заморачиваюсь над избавлением от RangeError в разных ситуациях, добиваюсь идеального увеличения времени расчёта при увеличении числа ячеек (в 5 раз увеличилось число ячеек, ровно в 5 раз, но не более, должно увеличится время расчёта), добиваюсь идеального высвобождения памяти после всего. Многое из этого вряд ли нужно сегодняшнему фронтенду, мне же просто нравится, спортивный интерес наверно.
И именно поэтому я не выкладываю остальные свои тесты, часть из них пытается выявить ещё какие-то ловушки производительности (порой их довольно сложно привязать к какому-то реальному кейсу), другая — ещё какие-то мои заморочки. Я выложил, наверное, наиболее близкий к сегодняшней фронтендерской реальности тест, ловушка, что в нём, реально может подпортить нервов, но даже этот тест всякие умники (да да, вы тот ещё умник, в самом хорошем смысле :) ) постоянно пытаются выставить как какой-то неправильный и ничего не показывающий. Тут я ещё могу как-то отбиваться, выложив остальные тесты я просто создам кучу хороших вариантов для выставления cellx-а не в лучшем виде, просто примеряя их к той самой реальности (от которой порой, в нестандартных ситуациях, всё же приходится отходить и в случае многих реализаций сразу нарываться на проблемы).
Мой патч не вносил никаких проседаний.
если хотите, пришлите мне ещё раз ссылку на пропатченную версию, я оформлю её результаты отдельной колонкой. Лучше конечно если этот патч будет в основной версии, как я сказал, с пол года назад я легко ускорял cellx в 2-2.5 раза (в 3 раза вырезая часть функционала), затачивая именно под этот тест, но так, конечно, не совсем честно.
vintage
31.08.2016 18:11Изменять свою зависимость при вычислении — плохо с архитектурной точки зрения. То, что это встречается — это бесспорно. Зачастую это — баг. Реже — костыль. Поэтому лучше такие штуки детектировать и кидать исключение.
RangeError — это о чём?
25000 слоёв — это какое-то мифическое суперсложное приложение будущего, а текущая аудитория пилит более приземлённые приложения, поэтому бенчмарки должны отражать скорость работы типичного приложения, а не абстрактные попугайчики, чтобы не вводить людей в заблуждение.
Касательно изменения атома, от которого зависит текущий вычисляемый — у меня в induce это как раз и учитывается. > Каждый раз выбирается наименее глубокий атом для расчёта. Если во время вычисления атома B, зависящего от A изменится A, то следующим будет вычислен снова B, а не какой-нибудь C. Собственно из-за неоптимальной реализации этой логики у меня и тормозило при глубоких цепочках.
Оптимизировал работу с глубокими цепочками: http://nin-jin.github.io/lib/props/props1.js
Теперь моя реализация с замыканиями по скорости примерно сравнима с твоей, но вот реализация с прототипами раза в 2 быстрее.
Ещё я поправил код теста с jin-atom чтобы использовались прототипы:
https://gist.github.com/anonymous/69a1a1531679e8f39aabНо это уже не имеет значения, свежие атомы имеют совсем другую логику, я о ней чуть позже напишу :-) Если вкратце, то инвалидируется дерево синхронно и полностью, а обновляется лишь по требованию.
Riim
31.08.2016 18:2425000 слоёв — это какое-то мифическое суперсложное приложение будущего
я ж говорю, я уменьшал число слоёв увеличивая число ячеек в каждом (как вы и предлагали), соотношение результатов не менялось (или менялось очень незаметно), попробуйте сами. То есть тест даже в текущем виде имеет очень даже реальный смысл применительно к самым реальным приложениям.
Оптимизировал работу с глубокими цепочками: http://nin-jin.github.io/lib/props/props1.js
ok, на днях добавлю)
vintage
31.08.2016 20:33Для атомов без патча результат точно должен был быть существенно меньше. Так как там на каждый шаг была пробежка от начала массива в 25000 элемента.
Riim
31.08.2016 21:24Да, результат заметно лучше и я вспомнил почему не добавил этот вариант — очень нестабильный результат, в новой вкладке ставлю 25к и запускаю несколько раз, результаты: 1644, 1258, 1685, 1258, 1383, 1333, 1891, 1368, 23092 !!!, 22571, 45864.
Создаю новую вкладку и по новой: 1299, 1211, 1289, 1288, 1300, 1498, 23249 !!!, 27635, 52475. Я просто не знал и сейчас не знаю, что мне с этим делать. То есть на 5-10 запуске резкое падение производительности (консоль пустая). Могу добавить средний результат до этого падения (1300 примерно), так норм будет?vintage
31.08.2016 21:29Очевидно всё дело в GC. С прототипами GC должен меньше напрягаться.
Riim
31.08.2016 22:02Добавил результаты.
raveclassic
01.09.2016 01:13+1Послушайте, вот вы тут спорите вдвоем, это все здорово, да, спортивный интерес. А, между тем, обычные разработчики, повязнувшие по уши в просадке производительности «канонической архитектуры redux», так и не могут понять, как им решить их наболевшие проблемы.
Вот, например, хайпа вокруг mobx больше, чем вокруг cellx. Но почему — совсем непонятно. Сухие цифры бенчмарков — это не совсем тот аргумент, который хотелось бы услышать, потому что, все же, это просто сухие цифры.
Было бы просто прекрасно, если бы все эти сухие сравнения были как-то сведены в красивую статью тут на хабре, что думаете?Riim
01.09.2016 11:58+1что думаете?
была отличная общая статья про атомы: Атом — минимальный кирпичик FRP приложения, повлиявшая в том числе и на cellx. Вряд ли я могу написать лучше, общих статей и без меня хватает, если же я уйду в более подробное описание оптимизаций, вряд ли кто-то кроме vintage это осилит. Вот статейка типа "Пилим тудулист на React+cellx" может вполне интересной получится.
Но почему — совсем непонятно
как раз всё очень понятно, mobx крутится на западе, где легко собрать большое сообщество заинтересованных пользователей, а не просто покидаться какахами в комментах. Мне с моим китайским английским там довольно неуютно. Всё что я могу — постить ссылочки на хабре, но тут проблема — менталитет наших разработчиков — средний наш разработчик с большим восторгом воспринимает практически всё приходящее с запада, но и с не меньшей настороженностью смотрит на то, что делает его сосед. Ведь сосед — это не Джон, а просто Вася)), а Вася по определению должен быть тёмным.
Riim
31.08.2016 12:38Примерно в три раза быстрее стал, на 1000 слоёв — 40-60, на 5000 так же — RangeError.
raveclassic
31.08.2016 00:48Если используете css-модули в библиотеке компонентов, есть смысл глянуть в сторону react-css-themr
PaulMaly
01.09.2016 18:45А если зачем вам на сервере Express, если рендером занимается React, да и роутингом связанная с ним библиотека?
DioNNiS
03.09.2016 05:026. UI-тестирование через Nightwatch.js + Browserstack.
Рекомендую обратить внимание на http://codecept.io/ — очень интересный проект.
PQR
12 месяцев — слишком далеко идущие планы!