Комментарии 105
Вот есть хороший, от создателя Redux: create-react-app
create-react-app это для совсем новичков, он урезан по самые яйца
В этом то и есть самое главное достоинство create-react-app, что урезан. Дает необходимый минимальный базис и далее есть возможность надстроить теми инструментами, которые нужны и вживить почти в любой проект.
Ну и кстати, там в документации по create-react-app есть список альтернативных бойлерплейтов на любой вкус, и урезанных и нет.
Я до сих пор в шоке от того, какой сложный этот вебпак. Для своих проектов начал юзать System.js + jspm, вполне доволен. Конфигурировать раз в десять наверное проще, чем вебпак,. Единственное нарекание в сторону system.js builder'а бандлов — то что он не оптимизирует автоматически бандлы, как это делает вебпак, за этим приходится немного следить вручную. Но всё равно он как-то проще вебпака будет, профиты по сути те же самые, плюс нативная поддержка ES6+ синтаксиса из коробки без каких-либо настроек.
Webpack 2 умеет ES6 imports из коробки.
Да я знаю что он много чего там умеет. Только конфиги его меня немного в жар бросают :) С System.js+JSPM получаешь всё то же самое, только как-то более просто и очевидно.
У JSPM есть свои недостатки: мутные проблемы за корпоративной проксей, два пакетных менеджера в проекте, изоморфные либы надо ставить два раза, тянет кучу своего барахла. Как лоадер SystemJS очень клевый, гибкий и мощный, но JSPM вызывает смешанные чувства.
Я попробовал и для себя выбрал либо browserify, либо rollup. Webpack это ад какой-то, зачем я должен из JS импортировать картинки, да еще с конфигом, который Хищники для Чужих писали.
Какие-то натянутые за уши «проблемы». Не знаю насчет проблем с прокси: он там как-то по другому запросы делает чтоли при скачивании пакетов?) Другой протокол какой-то использует вместо http чтоли?
Какие два пакетных менеджера? Npm и jspm? Так, npm особо и не нужен, можно всё держать в jspm. Зачем ставить два раза изоморфные либы? Jspm позволяет без проблем запускать весь ваш js стек как на сервере, так и в браузере, никаких проблем.
Тянет кучу своего барахла. Ну это вообще что за претензия?) А что сегодня не тянет за собой ничего?
Кажется, вы просто мало его изучали, просто не поняли какие-то моменты. Меня jspm очень радует, у нас в текущем проекте один и тот же код спокойно работает и на сервере, и в браузере, и всё это в том числе благодаря jspm.
Другой протокол какой-то использует вместо http чтоли?
Представьте себе, таки да. Желаю вам никогда не понять, о чем я говорю.
Так, npm особо и не нужен, можно всё держать в jspm.
Сам jspm тоже держать в jspm?:)
А что сегодня не тянет за собой ничего?
jspm тянет это в билд, вот в чем проблема. Почему-то когда я использую, например, browserify, у меня не загружаются полифиллы на половину стандартной библиотеки nodejs.
Jspm позволяет без проблем запускать весь ваш js стек как на сервере, так и в браузере
Насколько я помню, с этим были какие-то проблемы. Возможно, их уже решили, конечно. Например, в версии 0.17… которая в бете уже год:)
Меня jspm очень радует, у нас в текущем проекте один и тот же код спокойно работает и на сервере, и в браузере, и всё это в том числе благодаря jspm.
Меня npm очень радует, у меня в куче текущих проектов один и тот же код спокойно работает и там и там, и все это благодаря npm:)
Честно сказать, вы правы, jspm я знаю плоховато. Но первое впечатление было такое негативное, что изучать глубже не захотелось. Да и в чем профит? Tree-shaking там из rollup, который доступен отдельно. Загрузка и транспиляция на лету? так это медленно, каждый раз все с нуля компилять, а в browserify инкрементальные билды есть.
Сам jspm тоже держать в jspm?
Давайте всё-таки поговорим о реальных проблемах.
Почему-то когда я использую, например, browserify, у меня не загружаются полифиллы на половину стандартной библиотеки nodejs.
System.js весь же построен на теме динамичной подгрузки любого контента из любого доступного источника, соответственно и всякие полифилы в себе он тоже держит. Я не вижу особой проблемы в этом, но при желании вы можете попробовать упаковать всё свое приложение в sfx-бандл, который будет содержать только самый минимальный набор необходимого кода в 1.4 кб. Ну, я в свою очередь в данный момент ограничиваюсь обычными бандлами, вроде всё нормально.
Насколько я помню, с этим были какие-то проблемы. Возможно, их уже решили, конечно. Например, в версии 0.17… которая в бете уже год:)
Изначально мы в своём проекте использовали ветку 0.16. Ну, не знаю, я конечно поковырялся пару дней, но в итоге вроде как завёл всё это дело. Потом перешли на ветку 0.17, с ней тоже пока всё хорошо, хоть оно и в бете, но никаких проблем пока не возникало.
Меня npm очень радует, у меня в куче текущих проектов один и тот же код спокойно работает
Ну, это понятно, что код работает. Кто-ж с этим спорит, что он как-то там "работает" :) Но вот когда возникает необходимость наличия динамической подгрузки всего и отовсюду, тут я лично в других библиотеках вижу всякие разные странные и сложные решения, когда System.js весь построен вокруг этого, что меня и прельстило.
Давайте всё-таки поговорим о реальных проблемах.
Давайте. Я пока не услышал, какие реальные задачи jspm решает.
соответственно и всякие полифилы в себе он тоже держит
Угу, ставим (к примеру) angular, jspm качает npm:crypto.js (к сожалению, код сейчас не доступен, но зависимости примерно такие по нелепости). Как это связано с динамической подгрузкой из любого источника?
Окей, может, как-то и связано. Но, например, requirejs, светлая ему память, точно так же мог все динамически подгружать из любого источника, но обходился при этом без стандартной библиотеки nodejs. Значит, все-таки что-то не так в консерватории.
Ну, это понятно, что код работает. Кто-ж с этим спорит, что он как-то там "работает" :)
Вот насчет jspm у меня такие ощущения. Как-то оно там, из глины и палок, работает.
Потом, не путайте, пожалуйста, systemjs и jspm. За «динамическую подгрузку из любого источника» отвечает все-таки первое. Второе обещает только frictionless browser package management, но в моем опыте это было ни разу ни frictionless.
Давайте, в общем, сойдемся, что вас jspm устраивает, а меня нет. Я вполне могу с этим жить:) Ну а если судьба столкнет работать над одним проектом, уж договоримся как-нибудь:)
Давно используем JSPM в своем проекте и тоже весьма довольны. К сожалению, правда, что JSPM не без своих недостатков. В частности, к организации конфигов и путей в бете 0.17 много вопросов...
Какие вопросы по теме конфигов? На мой взгляд, в ветке 0.17 наоборот всё хорошо сделали в этом плане. По крайней мере, теперь наша личная конфигурация не смешана с конфигурацией и зависимостями других библиотек, которые мы просто подтягиваем из остального мира. Плюс, для браузера отдельный файл — тоже хорошо, там весь этот сгенерированный кеш зависимостей лежит, считай тоже не мешается в основном конфиге. Напишите какие у вас вопросы, возможно смогу что-то объяснить из своей практики.
Единственное что я не использовал в jspm 0.17 — это package configuration. Как-то не вижу смысла использовать его, когда наш код проекта не будет делиться на несколько пакетов.
47. Write some code :(
Какая разница, каков состав boilerplate, если его все равно необходимо осваивать? Оптимальный boilerplate для старта новых проектов — всегда и исключительно — _знакомый_ конкретному разработчику или команде boilerplate. Иначе старт может, мягко говоря, затянуться.
Но перебарщивать с количеством незнакомых инструментов действительно не стоит.
В остальном статья бессмысленная. На год вперед что-то планировать в мире JS? Да тут через месяц может все резко поменяться.
Единственное, что в первом не нравится: большой проект долго собирается в продакшн.
А вот 10 секунд и 100 секунд — уже большая разница.
В моем случае как раз второй вариант происходит на больших проектах.
CommonChunksPlugin не подходит, так как отрабатывает на каждой сборке
Optimizing Webpack build times and improving caching with DLL bundles
На год что-то планировать
А лучше совсем не планировать? Комменты к этой статье отлично зайдут как ответ на вопрос «как начинать здесь и сейчас?»
«На год что-то планировать в мире JS» — вот полная фраза.
Реакту всего года 3 с копейками. Половине инструментов перечисленных в статье и того меньше. Ну не получится тут выбрать состав на12 месяцев. Он все равно через месяц сменится, если конечно захочется поддерживать актуальное состояние.
Именно это я и имел ввиду.
Почему не Koa? Точнее даже так: Koa
3. jss, и вообще локальные стили — хорошо
13. Webpack2 имеет приятные фичи, типа оптимизаций размера, из коробки
19. Чем точка с запятой не угодили? Жду развёрнутого увлекательного ответа для дискуссии
В issues material-ui люди бесятся от того как инлайновые стили тормозят рендеринг страницы
19. Лишний символ, без которого всё и так будет работать, зачем он?
let doThis = ({some}) => console.log(some)
let doThat = ({some}) => console.log(some);
В корне меняет дело
В корне может и не меняет, но на больших объемах обеспечивает стабильное жжение в области поясницы у людей, которые пришли из менее свободных языков. А таких немало.
Плюс если вы работаете не один и принципиально не ставите точек с запятой, то ваши коллеги с большой долей вероятности будут их ставить, что приведет к неконсистентности кода в целом.
Конечно можно решить вопрос lint'ом, но в этом случае некомфортно (в моей личной статистике) будет все-таки большинству.
standard с командой --fix
Вам в помощь
const myFn = function () {
alert("Surprise!");
} // <-- No semicolon!
(function () {
//...
})();
;(function () {
//...
})()
привычка писать IIFE таким образом уберегает от подобных проблем
const myFn = function () {
alert("Surprise!");
} // <-- No semicolon!
void function () {
//...
}()
void хорош, но довод был в целом не про то, что мы можем как то писать или не писать, а про то как писать так, чтобы не рисковать неоднозначной трактовкой кода.
Боюсь только тема слишком холиварная, а рассуждений обеих сторон вполне хватит на stackoverflow в тематических вопросах.
Вот в джаваскрипте точку с запятой действительно не стоит пропускать. Потому, что иногда её пропуск может привести к неожиданным результатам. Но вообще в стабильном языке отсутствие точки с запятой — добро.
19. Не фанат штучек в стиле «смотри как могу!» и «и так работает»
Локальные стили — хорошо, пока пишешь один модуль. Когда исследуешь чужой легаси код и работаешь с кучей модулей одновременно, лучше иметь глобально уникальные имена.
О, можно подробнее развить мысль? Мне глобальные переменные как раз таик неприятны из-за возможных конфликтов имён, тогда как локальные стили позволяют мне с большой долей уверенности подключать компоненты из разных источников, написанных разными людьми и не бояться что они переопределят стили друг друга
Это всеобщее заблуждение, что локальность как-то спасает от конфликтов. От конфликтов спасают пространства имён. Всё, что даёт локальность — возможность вместо длинного глобально уникального имени использовать короткое локальное.
Дали вам, например, задачу подвинуть кнопку на 5px влево в одном легаси-проекте.
А там css-модули и html выглядит так:
<div class="panel_3LqQH658">
<button class="button_2OhV6WSs">
</div>
И где в исходниках искать концы этой button_2OhV6WSs
— непонятно.
Спасибо, теперь понятно ваша проблема. Если модули чисто от CSS, то действительно боль может выйти, согласен, но в случае того же React этот модуль должен был импортироваться там же, где и объявляется сам компонент, т.е. в общем то ищем где рендерится эта кнопка, а там уже и найдём концы.
import styles from './styles'; // <= Здесь концы
...
render(){
return (
<div class={styles.panel}>
<button class={styles.button}/>
</div>
);
}
Так в этом моя проблема и есть. Как я найду, какой компонент рендерит этот html, если исходного кода много и я в нем не ориентируюсь?
Обычно я всегда по css-классам и ищу, потому что они уникальные и в исходниках выглядят так же как и на странице.
React-devtools показывает displayName компонента, оно может быть неуникальным.
К тому же, если нет проблем с именованием React-компонентов, то откуда они возникнут в названиях css-классов?
К тому же, если нет проблем с именованием React-компонентов, то откуда они возникнут в названиях css-классов?
Вроде речь шла не о проблемах именования, а о конфликтах? Одно дело разбираться с одинаковыми displayName у реакта, которые ни на что по сути не влияют, другое дело искать пересекающиеся наложенные стили.
Для этого 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
Ибо для более менее серьезного проекта 12 месяцев — это 4-6 итераций разработки и пара другая релизов. И стек выбирают на 3-5 лет как минимум, а не на 12 месяцев. С другой стороны для мира JS планирование хотя бы на год это уже большое дело.
Я сказал о том, что оценка из расчета в 1 год слишком недальновидна для более менее среднего размера проекта.
Для «лендингов» и простеньких заказных сайтов со сроком разработки 2-4 месяца вполне себе нормально.
Для среднего размера интернет проекта со временем жизни 2-5 лет, оценка из расчета «выберем на год а там посмотрим» приведет к тому, что кому то придется заплатить большие деньги за переписвание всей системы с нуля раз в 12 месяцев.
А так свое судение о размере проектов я сделал исходя из статьи, а точнее преложения:
… на следующие 12 месяцев, с которым можно быстро стартовать новые проекты.
… быстро стартовать новые проекты — предполагается что в течении года их будет как минимум несколько — значит вряд ли они будут крупными.
Вопрос в том, какая экономическая мотивация у новых проектов для использования такого зоопарка инструментов? Или это просто фан и любопытство разработчиков?
12. 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. Там всё очень круто и удобно
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_865910
Да — я читал про это. И от этого чтива у меня слезы на глазах наворачиваются — каждое с голубиное яйцо…
Вместо того, чтобы сделать API, которое можно, не напрягаясь, использовать всегда и везде — сделали еще одно неудобное API, вокруг которого будут и дальше писать десятки и сотни разных оберток. И в каждом проекте будет своя — не такая как в других…
А ведь им ничего не мешало сделать по-нормальному
Поверх него сделал обертку для группировки get/head/delete, put/post запросов — восхитительно вышло.
0.15.0 (Oct 10, 2016)
Adding cancellation support (https://github.com/mzabriskie/axios/pull/452)
Соглашусь с вами по поводу mobx — из коробки отличная производительность, отсутствие необходимости постоянно нормализовать/денормализовать сторейдж объектов доменной модели, а также минимум бойлерплейта — отличный повод сменить redux.
Посмотрите на cellx, почти в 10 раз быстрее mobx-а, в остальном единственное значимое отличие — декораторы сделаны отдельным модулем. Коннектор к реакту здесь.
Ознакомился поверхностно, выглядит неплохо, особенно производительность. Попробуйте обновить mobx до 2.5 версии и провести тест ещё раз — авто обещал увеличение производительности в нём.
В реальных приложениях глубина зависимостей редко превышает 10. Максимум — 100, если использовать архитектуру в духе реакта, где родительский компонент зависит от дочернего. Так что эти бенчмарки — ни о чём. Помнится мы с автором обсуждали этот вопрос, и я даже вносил патч в jin-atom, чтобы не было проседания "производительности" на больших глубинах, но он продолжает с завидным упорством вводить всех в заблуждение.
Помнится мы с автором обсуждали этот вопрос,
обсуждали и я уменьшал число слоёв с увеличением числа ячеек в каждом, для библиотек не умирающих на этом тесте (все кроме Knockout, Kefir.js и Matreshka.js) соотношение результатов не менялось, просто усложнялся код бенчмарка, поэтому для простоты повторения оставил как есть. Цель теста как раз отсечь библиотеки имеющие эту ловушку производительности и спокойно сравнивать уже оставшиеся (другие ловушки либо не так критично убивают производительность, либо почти невозможны в реальных приложениях).
вносил патч в jin-atom
я тоже знаю как внести патч в cellx что бы он стал в 3 раза быстрее заодно просев в некоторых других тестах (выложен только один из примерно 10).
Покажите реальное приложение, где нужны хотя бы 1000 слоёв.
Мой патч не вносил никаких проседаний.
реальное приложение
я тоже люблю поговорить про реальные приложения, особенно когда это касается каких-то view-фреймворков, но что касается cellx-а — я особо не пытаюсь привязать его только к реалиям сегодняшнего фронтенда, забивая при этом на любые проблемы возникающие за пределами этих реалий, я пытаюсь создать некую идеальную реализацию с самым минимумом ограничений и способную хорошо работать в том числе в любых нестандартных ситуациях: нужно бешенное число слоёв — пожалуйста, какие-то изменения ячеек прямо внутри расчёта предыдущих изменений — сколько угодно (прошлый раз вы тоже говорили, что такого в реальных приложениях массово не случается, но в более ранних версиях Rionite, когда он ещё на morphdom работал, вся развёртка компонентов происходила как раз во время расчёта уже случившегося изменения, при этом происходило как массовое создание ячеек, так и их массовое изменение и всё это в идеале отрабатывало, как видите может и что-то нестандартное пригодиться), множественные изменения единичных ячеек — без проблем, всё красиво схлопнется в одно событие с единичным изменением в dom-дереве (кто-то говорил, что это плохо и хочется полного контроля над всем случившимся, какие проблемы, в evt.prev полная история всего что схлопнулось). И так далее.
Я заморачиваюсь над избавлением от RangeError в разных ситуациях, добиваюсь идеального увеличения времени расчёта при увеличении числа ячеек (в 5 раз увеличилось число ячеек, ровно в 5 раз, но не более, должно увеличится время расчёта), добиваюсь идеального высвобождения памяти после всего. Многое из этого вряд ли нужно сегодняшнему фронтенду, мне же просто нравится, спортивный интерес наверно.
И именно поэтому я не выкладываю остальные свои тесты, часть из них пытается выявить ещё какие-то ловушки производительности (порой их довольно сложно привязать к какому-то реальному кейсу), другая — ещё какие-то мои заморочки. Я выложил, наверное, наиболее близкий к сегодняшней фронтендерской реальности тест, ловушка, что в нём, реально может подпортить нервов, но даже этот тест всякие умники (да да, вы тот ещё умник, в самом хорошем смысле :) ) постоянно пытаются выставить как какой-то неправильный и ничего не показывающий. Тут я ещё могу как-то отбиваться, выложив остальные тесты я просто создам кучу хороших вариантов для выставления cellx-а не в лучшем виде, просто примеряя их к той самой реальности (от которой порой, в нестандартных ситуациях, всё же приходится отходить и в случае многих реализаций сразу нарываться на проблемы).
Мой патч не вносил никаких проседаний.
если хотите, пришлите мне ещё раз ссылку на пропатченную версию, я оформлю её результаты отдельной колонкой. Лучше конечно если этот патч будет в основной версии, как я сказал, с пол года назад я легко ускорял cellx в 2-2.5 раза (в 3 раза вырезая часть функционала), затачивая именно под этот тест, но так, конечно, не совсем честно.
Изменять свою зависимость при вычислении — плохо с архитектурной точки зрения. То, что это встречается — это бесспорно. Зачастую это — баг. Реже — костыль. Поэтому лучше такие штуки детектировать и кидать исключение.
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
Но это уже не имеет значения, свежие атомы имеют совсем другую логику, я о ней чуть позже напишу :-) Если вкратце, то инвалидируется дерево синхронно и полностью, а обновляется лишь по требованию.
25000 слоёв — это какое-то мифическое суперсложное приложение будущего
я ж говорю, я уменьшал число слоёв увеличивая число ячеек в каждом (как вы и предлагали), соотношение результатов не менялось (или менялось очень незаметно), попробуйте сами. То есть тест даже в текущем виде имеет очень даже реальный смысл применительно к самым реальным приложениям.
Оптимизировал работу с глубокими цепочками: http://nin-jin.github.io/lib/props/props1.js
ok, на днях добавлю)
Для атомов без патча результат точно должен был быть существенно меньше. Так как там на каждый шаг была пробежка от начала массива в 25000 элемента.
Да, результат заметно лучше и я вспомнил почему не добавил этот вариант — очень нестабильный результат, в новой вкладке ставлю 25к и запускаю несколько раз, результаты: 1644, 1258, 1685, 1258, 1383, 1333, 1891, 1368, 23092 !!!, 22571, 45864.
Создаю новую вкладку и по новой: 1299, 1211, 1289, 1288, 1300, 1498, 23249 !!!, 27635, 52475. Я просто не знал и сейчас не знаю, что мне с этим делать. То есть на 5-10 запуске резкое падение производительности (консоль пустая). Могу добавить средний результат до этого падения (1300 примерно), так норм будет?
Очевидно всё дело в GC. С прототипами GC должен меньше напрягаться.
Добавил результаты.
Вот, например, хайпа вокруг mobx больше, чем вокруг cellx. Но почему — совсем непонятно. Сухие цифры бенчмарков — это не совсем тот аргумент, который хотелось бы услышать, потому что, все же, это просто сухие цифры.
Было бы просто прекрасно, если бы все эти сухие сравнения были как-то сведены в красивую статью тут на хабре, что думаете?
что думаете?
была отличная общая статья про атомы: Атом — минимальный кирпичик FRP приложения, повлиявшая в том числе и на cellx. Вряд ли я могу написать лучше, общих статей и без меня хватает, если же я уйду в более подробное описание оптимизаций, вряд ли кто-то кроме vintage это осилит. Вот статейка типа "Пилим тудулист на React+cellx" может вполне интересной получится.
Но почему — совсем непонятно
как раз всё очень понятно, mobx крутится на западе, где легко собрать большое сообщество заинтересованных пользователей, а не просто покидаться какахами в комментах. Мне с моим китайским английским там довольно неуютно. Всё что я могу — постить ссылочки на хабре, но тут проблема — менталитет наших разработчиков — средний наш разработчик с большим восторгом воспринимает практически всё приходящее с запада, но и с не меньшей настороженностью смотрит на то, что делает его сосед. Ведь сосед — это не Джон, а просто Вася)), а Вася по определению должен быть тёмным.
Примерно в три раза быстрее стал, на 1000 слоёв — 40-60, на 5000 так же — RangeError.
6. UI-тестирование через Nightwatch.js + Browserstack.
Рекомендую обратить внимание на http://codecept.io/ — очень интересный проект.
Выбираем состав изоморфных React-приложений на следующие 12 месяцев