Комментарии 296
Это как Java — огромный рынок, на котором всё хорошо, но ничего нового нет. Как с этой проблемой справиться — не знаю.
Вот эту мысль было бы неплохо развить в статье. С моей личной позиции «огромный рынок, на котором всё хорошо, но ничего нового нет» — это вообще не проблема, а наоборот. И я очень рад, что сейчас во фронт-энде все гораздо более стабильно, чем 2-3 года назад, когда, если утром не прочитал новости, то к обеду ты уже не разбираешься в трендах.
Если серьёзнее — не могу говорить за Андрея/интервьюеров, но мне кажется, что это во многом вопрос личных предпочтений: для одних людей Java ощущается «застойным болотом без прогресса», а для других «отличной надёжной рабочей лошадкой», и никто из них не более прав. Ну, Андрей из числа первых.
Но мы ещё на самой HolyJS в трансляции расспрашиваем спикеров — возможно, тогда там эту тему разовьём, спасибо за комментарий.
С точки зрения мозгов того, кто этот фундамент пересобирает — возможно. А с точки зрения того, кто строит дом?
www.indeed.com/q-Cobol-Programmer-jobs.html
* отличной надёжной рабочей лошадкой
Ну или «лабиринтом с граблями, по которому, после некоторой практики, можно прекрасно научиться ходить и даже бегать»
Вот людей на такое количество кода относительно немного, да. Ну так это же и есть воплощение стабильности: код десятилетиями работает и приносит человечеству пользу, когда его даже не трогают.
Вообще приведённые цифры впечатляют: какой-то там банк исспользует 112,500 программ(!!!!!) на Коболе. Это как вообще?
Хорошее представление о «рынке языка» даёт рынок труда. А там пусто. Это и есть реальное место Кобола, а подсчёты строчек оставим изнасилованым журналистам.
Другой вопрос, что они таки страдают, и большенство новых проэктов уже несколько лет как, заводят именно для перехода с кобола (и вообще мейнфрейм релейтед) на что угодно.
И совсем другой вопрос — банки большие, бюджеты жирные, так что процесс будет итти еще дооолго, и коболисты будут нужны как некроманты ;)
Наверное с точки зрения JS разработчика весь остальной мир стагнирует.
Как можно завтракая не создать новый framework, потом начав работу и заварив чашку кофе не сделать +1 framework, потом пообедать и сделать +2 framework и т.д.,
очевидно что весь остальной мир падает в пучину стагнации и упадка.
Основной минус — если бизнес задачи не блещут разнообразием даже на активно развивающемся проекте(ах), то получишь профессиональный застой, вырваться из которого можно только (?) изобретением велосипедов или переходом на другие позиции и роли (необязательно формальным).
это вообще не проблема, а наоборот
Да, это не обязательно плохо. В мире Java нормально можно работать и быть счастливым. Тут вопрос о препочтениях и желаниях.
Единственная объективная пробелма — отсутствие социальных лифтов.
Он просто ещё молодой
В мире фронтенда очень много хайпа без реальных улучшений, бесконечно много альтернатив всяких фреймворков, бандлеров и либ. И это, конечно, утомляет. Ну и качество проектов не соответствует количеству звезд на столько, что диву даешься.
Но в то же время периодически происходят более фундаментальные изменения. Переход от колбэков к промисам и асинхронным методам. Появление TypeScript и тп.
Да в Java ней нет назойливого хайпа, но в ней нет и действительно полезных новшеств. Может быть и не должно быть, т.к. нельзя запихнуть все в один язык с обратной совместимостью. Проблема Java в том что она со своей критической массой доминирует, а ее стабильность стагнирует умы многих разработчиков (до сих пор не понимают асинхронности, не знают ФП и не стремятся и тд.).
Развитию JS сильно способствует мода переделывать фронтенд каждые год-два, в Java такое реже. Но новые проекты уже делают и функциональные и асинхронные (если это нужно) и довольно давно.
Проблема Java
до сих пор не понимают асинхронности
Эм, пардон, как вас тут понимать? По вашему в Java нет асинхронного кода? Или он под строгим табу?
Это же «полноценный ЯП» — тут потоки ввели еще в 90-х
Это же «полноценный ЯП» — тут потоки ввели еще в 90-х
Ну вот сами же и привели пример: речь об асинхронном коде, а вы про потоки.
Начало адекватного асинхронного кода — CompletableFuture, который появился лишь в 8 (2014). А одного наличия не достаточно.
Я не понимаю вашей цитаты. Я могу с таким же успехом надергать отдельные слова из любого поста и составить из них какую-нибудь ерунду.
Под капотом в CompletableFuture нет ничего из ряда вон выходящего — просто к моменту выхода 8 было достаточно высокое давление от простых разработчиков (мода, то есть), плюс убрали часть ритуалов при кормлении Future callback'ами, что и послужило отправной точкой добавления именно в стандартную библиотеку.
В общем, это будто вы сказали, что под Java реактивное программирование появилось только в 2018 с выходом Java 9 и тамошнего
java.util.concurrent.Flow
, при живом-то RxJava.Только когда есть общепринятые абстракции можно говорить о чем-то. Без них вы запаритись интегрировать асинхронный код из разных библиотек (в одной будет свой Future, в другой event loop и тд).
В общем, это будто вы сказали, что
?
Вот это я никогда и не понимал. Большие серьезные мужики в 2019 году в 20ый пишут статьи про var/let/const… и ведь даже не вспоминают про выведение типов, статический анализ, JIT и другие прелести.
Ну и все такие:– Еее, спасибо за статью, как же я раньше жил.
Всегда в выборе между бэком и фронтом был аргумент в пользу первого по причине нового вида смузи каждый день, которое нужно учить.
И не вижу логики в том, что при стабильном рынке вдруг все инновации и новые фреймворки заканчиваются.
по факту под этой верхушкой айсберга есть сотни людей, которые сделали проекты не хуже, но никому не известны.
Призываю vintage излить горечь души своей…
Я обычно всякие интервью сразу скипаю, так как там в основном вода и нудятина. Но спасибо, что обратили моё внимание. Тут вырезать диалоги и получилась бы неплохая статья, поднимающая важную тему.
Мне особо нечего добавить. По теме скажу лишь, что приложения в MAM инфраструктуре, на которой основан $mol, получаются весьма компактными, если не тянуть что попало из npm. А тянуть оттуда не очень удобно. Отчасти это сделано намеренно, чтобы не подключали всё подряд. Но в основном, конечно, чтобы решить проблемы с копипастой импортов/экспортов, тришейкингом наимпортированного (чтобы не плодить ещё больше импортов/экспортов/реэкспортов, ага) мусора, и как следствие, проблем с долгой сборкой.
Для сравнения:
Главная страница Реакта, где функциональности с гулькин нос — 500kb сжатых скриптов.
Галерея с демонстрациями большинства $mol компонент и их онлайн редактором — 100kb сжатых скриптов.
А, ну и если Андрей научит приходить в компании за деньгами, было бы круто. А то я когда рассказываю про свой проект очередному представителю какой-нибудь компании, то в глазах собеседника вижу лишь усталый взгляд и единственный тезис — а мы уже героически запилили свои (и в каждой компании точно такие же, но свои) компоненты на Реакте с Редуксом, нас всё устраивает. А на письма или в публичных обсуждениях так вообще никто не отвечает.
Кстати, не хочешь попиарить $mol на западе или хотя бы дать обратную связь? А то я не умею в эти ваши Твиттеры.
$my_heroes $mol_view
sub /
<= Title $mol_view
sub /
<= title \
<= Title_sub $mol_view
sub /
<= title_sub @ \My Heroes
<= Rows $mol_list
rows <= rows /
Сходу не могут понять ни люди, ни анализаторы кода для js (фичи ide rip, литеры rip).
Повсюду какие-то слеши в разные стороны, спецсимволы, чтобы указывать на типы.
$my_heroes $mol_view
sub /
<= Title $mol_view
Стрелочка влево означает получение значения свойства, а после неё идёт собственно объявление этого свойства указанием его имени и значения через пробел.
Это получить свойство Title из $mol_view или объявление его на $mol_heros или что вообще?
UPD: Даже посмотрев во что это компилится, ощущения что это хороший дизайн не стало.
Сходу не могут понять ни люди
Если новую концепцию можно понять сходу, то не такая уж она и новая. И если бы вместо этого птичьего синтаксиса можно было воспользоваться каким-либо иным, более привычным, уж поверьте, я бы не стал подвергать людей лишней когнитивной нагрузке. Вот, сравните сами, как та же концепция выглядит на более привычных html и json: https://github.com/eigenmethod/mol/wiki/View-formats
фичи ide rip
Эти фичи IDE делают под конкретный синтаксис конкретных фреймворков. Вот, ждём, когда же в ТС позволят наконец создавать типы из плагинов и обрабатывать не только файлы с расширением ts
и tsx
, тогда можно будет встроиться в его language server. Но сейчас нужно очень большое медиа-влияние, чтобы побудить их не хардкодить один единственный jsx.
линтеры rip
Тут очень строгий синтаксис, ему не нужны линтеры. А проверкой типов занимается тайпскрипт.
Повсюду какие-то слеши в разные стороны, спецсимволы, чтобы указывать на типы.
А в Ангуляре скобочки квадратные, круглые, фигурные, палочки вертикальные и странный язык программирования в некоторых аттрибутах. А во Вью волшебные аттрибуты и какие-то слоты. А в Реакте то кавычки, то фигурные скобочки, то теги внутри аттрибутов. Любой синтаксис не понятен, пока не ознакомишься с документацией.
Это получить свойство Title из $mol_view или объявление его на $mol_heros или что вообще?
Это объявить свойство Title в $mol_heroes и тут же получить его значение. Следующие два кода полностью эквивалентны:
sub /
<= Title $mol_view
Title $mol_view
sub /
<= Title
Даже посмотрев во что это компилится, ощущения что это хороший дизайн не стало.
А что такое хороший дизайн в вашем представлении?
Попробую ответить на все сразу.
Вступление
Я говорил о том, почему $mol, на мой взгляд, в текущей своей форме распространенным стать не может, т.к. у него очень низкая доступность. А не про то, где его расположить на глобальной шкале фреймворков и DSL.
Сначала отвечу фидбеком, потом попробую написать полезные вещи про конкретные аспекты view tree.
Примеры ниже будут от моего лица, но, кажется, они справедливы для большинства frontend разработчиков.
Если новую концепцию можно понять сходу, то не такая уж она и новая.
Да. Только новизна сама по себе — не то чтобы положительное свойство (с прикладной точки зрения), это конечно очень весело, но едва продуктивно.
ему не нужны линтеры
Ок, но форматтеры все еще нужны т.к. договариваться в пулл реквестах и постоянно думать про то, как оформлен код, неудобно. Тут все еще можно написать с маленькой буквы то, что принято писать с большой и поставить 2 пробела, где принято 1.
Любой синтаксис не понятен, пока не ознакомишься с документацией.
Тут есть 2 нюанса.
- "ментальное расстояние" между 2 языками(синтаксисами), мне как-то не понадобилось читать доки, когда я первый раз увидел, скажем, jsx. Потому что он выглядит как html, где можно написать
{
и писать js до следующей}
. Потому что писать js html я уже умею, а фигурные скобочки для переключения синтаксиса — конвенция в куче шаблонизаторов, языков, да и в самом jsRight? ${true ? 'yes' : 'no'}
.
Аналогичная вещи произошла с elm, если показать случайному фронту https://ellie-app.com/37gVmD7Tm9Ma1, он даже не зная elm по цвету слов и буквам в них опишет, что там происходит. Т.е. если птичий синтаксис оперирует такими же понятиями (функции, аргументы, массивы, объекты, поля, переменные) и одинаково обозначает структуры данных, его сильно легче воспринять, чем принципиально альтернативный подход. (понял большую сразу верно для кучи всего, elm, sass, toml, kotlin, C#, go, vue, т.д). Для $mol и view.tree верно скорее понял примерно ничего, почитал и стало ненамного лучше. - Нагрузка на память. Это главная беда решений, которые начинаются с прочтения документации. Человек не сразу запоминает связь символов и семантики, значит если код не подсказывает свой смысл сам, придется регулярно проверять, что он делает. Это долго и удручающе, никто не хочет этим заниматься. В этом главная проблема операторов, которыми пестрит view tree. Они не намекают на то, в чем их смысл. Слова это делают. Операторы которые человек уже знает. Например:
[]
для массивов и{}
для объектов это делают,/
и*
— нет, более того, у многих они зарезервированы под деление и умножение (или wildcard), и приклеивать им дополнительные смыслы энергозатратно. Причем в этом же проекте их надо будет мыслить по-старом, ведь не все можно на view tree написать. Не просто так люди со скрипом пишут (если вообще справляются) regex из головы.
А что такое хороший дизайн в вашем представлении?
В данном случае говорим про дизайн языков, я бы выделил 6 критериев (которые все в сущности ведут к одному: инструментом просто решать задачи сразу)
- Простота восприятия (выразительность) — описание решения задачи на данном языке максимально понятно (не важно насколько оно короткое)
- Первичная доступность — количество усилий, которые целевой пользователь языка должен приложить, чтобы начать использовать его для своих задач
- Запоминаемость — простота восприятия и создание кода на языке без использования дополнительных источников (т.к. это быстрее, приятнее и позволяет не терять контекст задачи которую пользователь пытается решить с помощью языка)
- Безусловность (ортогональность) — насколько сущности в языке (такие как, например, значение, выражение, указатель, тип, функция и т.д.) взаимозаменяемы.
- Покрытие области — могу ли я комфортно и эффективно решить все свои задачи используя только этот язык? Нет. Какую их часть я могу так решить?
- Инструментарий совместной работы — Насколько легко использовать чужой код? Насколько легко параллельно делать несколько задач? Несколькими людьми? Есть ли инструменты, упрощающие чтение? (подсветка синтаксиса, go to definition и ему подобные, автоформаттинг (чтобы повысить привычность чужого кода, если язык позволяет разные формы записи).
Менее личное и (возможно) более полезное
Не факт что я скажу тут что-то новое, но сейчас создается впечатление, что эти пункты игнорируются.
- На ваш язык мигрируют js разработчики. Они привыкли, что
\n
что-то значит, отступы — нет. Они привыкли что структуры данных открываются и закрываются. Они привыкли к модели родитель\ребенок, а неsub
и т.д. - Операторы не намекают на свой смысл, значит, язык, в котором их много, требует больше ментального ресурса, для восприятия. (чем словесный)
- Разрыв компонентов — шаблон не зависит от логики, структура от стилей и т.д. звучит очень красиво, но это ложь. Условия показа, интерпретация действий пользователя, повторения — инъекция логики в шаблон. Ну а будь в вебе все настолько волшебно, что структура независима от стилей div (структурное ничто) был бы не нужен, а он, наверное самый популярный тег сегодня. React + css-in-js \ Vue SFC не просто так набрали популярность. (хотя я так и не понял,
$mol
советует компонентный подход или что) - Подход "все говно, $mol \ view tree — пушка" вызывает защитную реакцию и желание искать изъяны, а не понимать чем хорошо данное предложение.
- Отсутствие туториалов мешает пониманию. Большинству при первом знакомстве интересно "берем A B C и получаем вот такую пушку", очень желательно редактируемо и прямо в браузере. (есть примеры, но их надо смотреть отдельно, и они без вставок о философии, сущностях и целях инструмента)
$mol
хвалится стандартной библиотекой компонентов, при этом нет не 1 примера вида: берем$mol_button
и добавляем ей:active
\ убираемborder-radius
с выделенных дат в календаре и т.д. Т.к. дизайн библиотеки компонентов$mol
не в том, состоянии, чтобы брать ее дизайн как есть, а как его поправить или переопределить — непонятно. Ну а большим компаниям чужой стиль тем более не нужен, так что для них$mol
— в лучшем случае "низкоурованеый фреймворк".
Итого
Скорее всего в $mol
есть куча хороших идей и решений, но за ними надо непонятно где и куда копать, а его подача мотивации не прибавляет.
Спасибо за развёрнутый ответ.
новизна сама по себе — не то чтобы положительное свойство
Новизна — необходимое, но не достаточное условие прогресса. Нет новизны — нет и прогресса. Есть прогресс — есть и новизна. И если хочется прогресса, нужно быть готовым к новизне. Изучение ещё одного фреймворка как 2 капли воды похожего на те, что уже знаешь, — ничего полезного не даст. Да и смысла разрабатывать такой фреймворк — нет.
форматтеры все еще нужны
Тоже нет, там очень строгий синтаксис, не допускающий различий в форматировании. Кроме некоторых нюансов, которые крайне сложно формализовать типа "в каких случаях выделять подкомпонент".
Тут все еще можно написать с маленькой буквы то, что принято писать с большой и
Я пока не вижу как это формализовать и не уверен стоит ли. Но если будет понимание как и зачем, то будет изменён компилятор, а не добавлен какой-то линтер сбоку.
поставить 2 пробела, где принято 1.
Нигде нельзя 2 пробела. Когда-то был баг, допускавший это, но он давно поправлен.
мне как-то не понадобилось читать доки, когда я первый раз увидел, скажем, jsx
А через сколько вы научились пользоваться им правильно? указывать ключи в циклах, кешировать хендлеры вне функции рендеринга, предоставлять пропсы для настройки отображения и тому подобные неочевидные вещи. view.tree
просто не позволяет выстрелить себе в ногу, при этом давая куда большую гибкость.
если показать случайному фронту https://ellie-app.com/37gVmD7Tm9Ma1, он даже не зная elm по цвету слов и буквам в них опишет, что там происходит.
Тут тоже не сложно догадаться что происходит.
если код не подсказывает свой смысл сам
Так view.tree как раз и подсказывает значения символов. Собственно, символы выбирались не наобум, а так, чтобы задействовать уже существующий ассоциации.
<=
— движение данных в одну сторону
<=>
— двустороннее движение данных
\
— экранирование
/
— разделитель директории и вложенных файлов
!
— обязательный аргумент
?
— опциональный аргумент
^
— значение свыше (супер класса)
@
— нестандартное начертание буквы (иные языки)
*
— наименее очевидная ассоциация, да, пересечение множества линий (соответствие ключей и значений), впрочем, это весьма редкоиспольземый символ во view.tree
Условия показа, интерпретация действий пользователя, повторения — инъекция логики в шаблон.
Ничего такого во view.tree нет.
Отсутствие туториалов мешает пониманию.
https://github.com/eigenmethod/mol#tutorials
нет не 1 примера вида: берем $mol_button и добавляем ей :active \ убираем border-radius с выделенных дат в календаре и т.д.
Да полно примеров. Например, тот же ToDoMVC: https://mol.js.org/app/todomvc/
Обычные CSS переопределения, никакого рокетсаенса.
Туториал про таблички начинается с бага (надо снять фокус с a1 чтобы значения появилось, потом начинает норм работать)
Контрибьторы идут до хоть чего-то про инструмент, сайт — галерея компонентов без слова про фреймворк (для сравнения react начинается с описания и потом сразу примеры основных концептов и interop с внешними либами)
И в этом туториале почти сразу `<= Head -` без объяснения что за волшебный минус.
Поиграться с кодом на промежуточных стадиях нельзя. Т.е. та же проблема: доступность страдает.
> click?event <=> decrement?event null
Ну вот как-то нет
Почему я вдруг в 2 стороны связался с кликом? Я их только потреблять вроде хочу. Но как я понял тут 2 стороны это что-то вроде «я компоненту listener, а он мне в него ивенты.»
Только поигравшись в компайлере можно понять, что? влияет на event, а не на click, кстати почему так?
Что null тут делает вообще, в другом месте это вроде стандартное значение?
> а так, чтобы задействовать уже существующий ассоциации
Так определенно стало понятнее, но `=>` все еще сложно понять.
`@` тоже едва очевидный, но можно понять после объяснения
И все же, почему не парные скобки, а / * для массивов и объектов?
> интерпретация действий пользователя
Речь про ивент листенеры, они есть, да и вообще в view.tree стандартные значения пишутся (судя по `value 0`)
> повторения — инъекция логики в шаблон
Речь про map и вроде вот оно, но я не уверен.
Body $mol_grid
col_ids <= col_ids /
row_ids <= row_ids /
head_cells <= head_cells /
cells!row <= cells!row /
UPD: А, `/` это пустой массив как стандартное значение.
Туториал про таблички начинается с бага (надо снять фокус с a1 чтобы значения появилось, потом начинает норм работать)
Можете подробнее описать баг и свою систему?
Почему я вдруг в 2 стороны связался с кликом? Я их только потреблять вроде хочу.
Потому, что это обычные свойства, как любые другие. И мы говорим, чтобы подкомпонент пушил ивенты не в своё свойство click, а в наше decrement.
Только поигравшись в компайлере можно понять, что? влияет на event, а не на click, кстати почему так?
Мы обсуждали вариант с click(event?)
, но тогда для консистентности пришлось бы все свойства писать со скобочками и тогда view.tree
рисковал начать соперничать с лиспом по числу скобочек на единицу кода. В итоге сошлись на том, что излишнее подражание яваскрипту даст слишком много визуального шума и не совсем корректные ассоциации и ожидания.
Что null тут делает вообще, в другом месте это вроде стандартное значение?
Да, значение по умолчанию для свойства.
=>
все еще сложно понять.
Согласен, и была мысль как это переделать, однако, это довольно редкая конструкция. Так что было решено пока не рыпаться.
И все же, почему не парные скобки, а / * для массивов и объектов?
Чтобы не усложнять разбор синтаксиса.
Речь про ивент листенеры, они есть, да и вообще в view.tree стандартные значения пишутся (судя по value 0
)
view.tree
про композицию и расширяемость. Вся логика описывается на удобном для описания логики языке — тайпскрипте. Статические значения логикой не являются.
Тут тоже не сложно догадаться что происходит.
На самом деле сложно. Сложнее чем в примере про elm. Говорю как человек, который знаком с JS, HTML, JSX, PHP, Scala, Java, Objective-C и не знаком с view tree и elm.
Тонко, тонко)
Продолжайте, потомки мои. Всегда ваш доктор Фрейд.
Есть Дэн Абрамов на Западе, есть я в России
Ситник известен тем что додумал идею одного разраба и оформил это на хайпе препроцессоров в постпроцессор PostCSS, заявляя значильную производительность при всем том же самом.
Справедливо это или нет, но так сложились звезды, он об этом и говорит. PostCSS используют в яндексе, автор bootstrap заявил что 5-ая версия будет на PostCSS. Этого вполне достаточно, чтобы самоназваться представителем фронта от России.
Например, я хочу, прости господи, типы в JavaScript добавить, понятно, что это уже перебор.Почему перебор? Мысль здравая, а то все какие-то постцээсэс и автопрефиксеры. Но просто так добавить типы в JS не получится. Там нужно постоянно что-то подпиливать как c TypeScript происходит. Поэтому если и сделают стандарт ES2025+ с типами, то он очень быстро устареет.
Если вы полагаетесь на типизацию, и думаете, что если скомпилировалось, значит нет багов, то на самом деле багов будет больше.Ну так, мне кажется, только самый начинающий джун будет думать при первом компилировании. Очень скоро даже он поймёт, что так не работает.
Особенно, если заменить типизацией реально работающие практики.Хорошие практики стоит дополнять друг другом.
Типизация будет хорошо работать на длинной дистанции, хотя и на короткой даст свой эффект.
Конечно на JS будет лаконичнее — но у вас также будет весьма условный контроль над тем, какие именно значения допустимы для 2, 3 и 4.
Про GO не могу сказать, но вот в Android подобное решается с помощью чего-то вроде вот такой обёртки для выхлопа достаточно простого парсера:
JSONObject
При этом все типы кодируются сразу, видны в коде, и вызывают ошибку если попытаться получить вложенный объект, но по адресу атрибута на самом деле, например, число. Это не лучший вариант подобной библиотеки, разумеется, но вполне рабочий, и снаружи своих типов касты не навязывает.
6 лет уже фронтенд стагнирует. Стагнирует-стагнирует, да невыстагнирует никак.
Ну это субъективно как-то.
По мне так все зависит от целей.
JavaScript сейчас даёт выбор.
А сейчас даже Parcel люди не знают (или боятся), хотя он исправляет то, за что все критикую Вебпак (отвратительный DX с кучей конфигов). То же самое с Vue — все критикую Реакт что там ничего не понятно и сторонние библиотеки (типа роутера) плохие, но продолжают боятся Vue (так как он не мейнстрим).
Правом выбора реально пользуются единицы.
Не знаю с чего вы решили про Parcel и Vue. Выглядит как сверхобобщение. Хороший архитектор не станет брать React из-за того что сейчас так можно. Он будет стараться выбирать решение под нужды проекта. То же самое и с webpack.
Я когда-то костьми лег против React в одном проекте. И был прав. Сейчас у них все хорошо. И они с Vue.
Хороший архитектор не станет брать React из-за того что сейчас так можно.
Ага. Я согласен. И таких примеров единицы.
Блин, я там хотел сказать "модно".
Хороший архитектор поглядит на то, на чем сейчас лабают в компании, и какого народа больше на рынке.
И в процессе миграции, неизбежно надо было править поток ошибок и косяков. Так вот, я в полной мере оценил, что такое «медленная сборка бандла».
Итогом стало погружение в изучение вопроса и уменьшение времени с ~12-15сек. до ~300-500мс. С прогретым кэшем, но все же.
Попутно и размер бандла уменьшился в пару раз.
Теперь весь js web-application умещается в < 500кб. Я рад :)
Ничего сложнее ajax и «ручной перерисовки UI» не было.
На jQ конечно плагины полноценные были написаны, и в целом код более-менее приведен в опрятный вид.
Теперь нормальная реактивность, websockets (центральный узел на Java), вся отрисовка на клиенте (раньше были банальные шаблоны на Smarty (PHP)).
Понятно, то есть внедрение сборки сократило размер бандла, даже не смотря на то, что на клиенте стало больше логики?
Спасибо за интересный пример!
— jQ-world, размер был N
— Webpack, babel, Vue, etc., размер 2N-3N
— Изучение мануалов и тонкая настройка, размер N
Т.е. с одной стороны выигрыш по размеру был лишь по сравнению с «не оптимизированной версией».
С другой стороны — приложение получило максимально современный код и архитектуру. Плюс сильно расширенный функционал.
И время сборки максимально-близкое по комфорту к «Ctrl+S -> Ctrl+F5».
Если выкинуть весь доп.функционал, то размер будет да, меньше изначального. Ибо были как и самописные jQ плагины (счет в пределах «до 10Кб»), так и сторонние, которые могли быть весьма и весьма тяжелыми.
Сейчас те же задачи решают аналоги, построенные на современном тех-стэке, местами они сильно-существенно меньше по объему.
А свои плагины заменены на Vue-модули (тоже самописные).
Но эти модули уже позволяют выкинуть десятки киллобайт кода, по «поддержанию/отображению данных».
UPD: Посмотрел анализ бандла — если исключить все библиотеки и оставить лишь «бизнес-код», то в режиме gzip имеем менее 30кб. Что весьма похоже на правду для web-dashboard для конфигурирования системы автотестирования, назначения расписания, управления балансировщиком нагрузки, выводом списка отчетов и просмотра каждого из них.
Сейчас навскидку только скажу про отсутствие автоимпортрв во вью файлах
Приколоченный гвоздями export default, который тоже некисло гадит при разработке
Наглухо отсутствующая типизации
Директивы через литералы
Пропаганда мутабельности
Это из того, что вспомнил
Когда я говорил про отличный DX, я имел в виду хорошую документацию (например, на русский она была переведена на год раньше Реакта), браузерный DevTools, готовые решения, а не «найди на npm и собери сам».
Тут скорее ваши предпочтения не совпадают с теми, что у разработчиков VueМне видится обратная ситуация
Документация не соотносится с тулингом от слова «совсем» и уж тем более, время ее перевода на русский (без английского в деве вообще тяжко, да)
Браузерный DevTools у Реакта — ничем не уступающий Вьюшному.
«найди на npm и собери сам» — скорее плюс, никто не прибивает разработчика гвоздями к той или иной библиотеке роутинга, или стейт менеджеру, как хочешь, так и варись
Не хочется собирать все по частям? Ставишь CRA, делаешь eject, бойлерплейт проект готов
Впрочем это уже тонкости, и к изначальному поинту не имеют никакого отношения
И получается, по сути, самодельный фреймворк на каждом проекте. Приходишь и вроде всё знакомо, но ни хрена не понятно.
Но тут вопрос в том, что больнее — юзать неудобный инструмент, или при смене части стека потратить пару дней на вливание в новую технологию
Дискриминации по стейт-менеджерам благо нет, да и парадигм всего 2 (в общем случае), если работал по обе стороны, хотя бы раз, без труда разберешься и в остальных (та же суть, другое апи)
Все таки свичнуть стейт менеджер — не менять фреймворк со всей экосистемой вместе)
И да, «свичнуть стейт менеджер» — это дело нифига не простое, но и не невозможное.
Вы так говорите, как будто это что-то плохое. :)
В итоге, пока найдешь, кто где что триггерит, пройдёшь все круги ада и собственно этих самых мутаций.
С мутированием переменных код получается императивным, а не декларативным
Так что, склонен думать, что да, плохое :D
которая вызывает первую.
В случае реактивного программирования у вас на этом шаге вылетит исключение.
Отсюда можем получить стейт-специфик баги и прочее)
ЗЫ: Кстати, а можно вопрос? Зачем вы в качестве контраргумента реактивному программированию приводите пример в духе «что-то внезапно дёргает что-то»? Реактивное программирование само по себе вам данные-то в хорошем порядке не выстроит, и граф преобразований от входов к презенташкам — тоже.
Я просто не понял, к чему был ваш аргумент. В ногу можно выстрелить? Да конечно можно. Везде можно. И с голой декларативщиной тоже можно.
Много проектов использует такой подход?
Даже в официальной доке про то, что это бест практис по использованию ни слова
Да и количество бойлерплейта которое придется писать переплюнет любой редакс, провоцируя в разы больше ошибок, чем использование либы в «голом» виде
¯\_(ツ)_/¯
Если без магии — это mov ax,bx. Если без бойлерплейта — это читаем доку, декларируем обсерваблы, экшены, вот это всё — и не жужжим.
что это бест практис по использованию ни слова
Потому что это не бест практис, кто вам такую глупость сказал? Вы спросили «как» — я вам ответил, как.
И как только дело доходит до интересных случаев (например, сложной оптимизации рендера), так вы со своим микроскопом приходится, говорите «нет» мутабельности и сливаете в несколько раз больше памяти, чем было б с мутабельностью. А потом это происходит 100 раз на страницу (потому что компоненты и тэ дэ), а потом все кругом такие «ой, чёт наш прекрасный интерфейс память жрёт как не в себя».
Все совпадения с реальными случаями, разумеется, вымышлены.
Это что-то из серии «если у меня уже есть микроскоп и он довольно тяжелый, то молоток мне уже не пригодится».Лучше плохой аналогии — только никакая аналогия)
В большинстве кейсов, затык в производительности, при замене императивного на декларативное — траблы с архитектурой.
В большинстве кейсов, затык в производительности
Ага. А в деле производительности интерфейсов рендер — самая тяжелая штука.
при замене императивного на декларативное — траблы с архитектурой
Однозначно. Но слив памяти в трубу, потому что теперь никто ничего не мутирует — сразу же за этим.
Приведите пример кода, который в декларативном виде отъедает много памяти, а в императивном — нет)
До этого, кейс слишком космический)
«Я тут сяду и буду голословно утверждать, а вы мне в опровержениях код пишите» работает если только на тех, кто в интернет только вчера зашел.
Чьи утверждения после этого более голословны нужно бы проверить)
Декларативность кода заключается не только в каррировании функций, да и даже в них нет никакой особой проблемы. Даже при вызове в 100 раз, хотя тут опять же проблема архитектурного масштаба, не случится ничего криминального. С большой долей уверенности, скажу — то что жрет память как не в себя в декларативном виде, отожрет ее с той же прожорливостью и в императивном, пусть даже и немного меньше. Кроме того, сильно зависит от того, как написать
Да, только поинт про утечку памяти, если писать код декларативно — не я привел)
Не утечку, а перерасход.
Я исхожу из неявной предпосылки, что код во всех случаях пишут не идиоты. И что память отжирается не потому, что кто-то что-то плохо написал, а просто потому, что ошметки и куски данных теперь хранятся в большем количестве мест, чем нужно. Часто это не имеет значения. Но в некоторых близких к предельным случаях запросто может стать заметным и существенным.
Если код пишут идиоты, то тут и в том и в другом случае много всего плохого может случиться.
Кроме того, сильно зависит от того, как написать
Вот именно. И возвращаясь к вашему аргументу выше по ветке — не «императивщине не место в интерфейсах», а «всё зависит от того, как написать».
Не утечку, а перерасход.Сути не меняет, тащемта, не я утверждал это
Тот мизер эдж-кейсов, где императивность могла бы быть оправдана подтверждает правило, что декларативность (ВНЕЗАПНО) декларативнее, нагляднее, читабельней. Это позволяет сконцентрироваться на том, что происходит, а не как происходит. Никто не мешает написать императивно любую из низкоуровневых функций, я не накладывал на это табу в своем сообщении)
Однако, опять же, на своей памяти в реальной жизни не встречал ни одного подобного кейса)
Код не приведу, но приведу теоретические выкладки касательно редактирования в богатом редакторе текста. Вот у нас есть некоторое дерево. Нам нужна поддержка истории. В функциональном стиле сделать новый снепшот так, чтобы он переиспользовал ветви предыдущего снепшота — быстро и экономно по памяти. Однако, нам нужно совместное редактирование и чтобы у каждого пользователя была своя история. Снепшоты становятся бесполезны, а надо запоминать сами изменения. Изменения должны применяться к любой версии дерева, а значит должны быть сериализуемыми, а значит указывать на узлы по идентификаторам. Но как быстро найти узел по идентификатору в денормализованном дереве? Нужен индекс. Но перестраивать индекс на каждый чих — дорого. А нормализованный граф — сам себе индекс. Нормализованый граф — это фактически словарь с десятками тысяч ключей. Пересоздавать его на каждое изменение крайне медленно. Получается нужна ручная реализация какого-нибудь иммутабельного дерева поиска с хитрыми алгоритмами обновления за log(n).
Либо просто берём обычную хеш-таблицу, помещаем в неё объекты с обсерваблами, провязываем перекрёстными ссылками и получаем все операции а константу.
Я не пропагандирую табу любой императивщины, ибо ИТ, в своем корне — чистый императив, но говорю, что подход mobx, Vuex,… — заранее настраивает разработчиков писать императивный код. Хорошие программисты вынесут в нижние слои абстракций и не будут знать проблем, но ведь суть технологии свести проблемы проектирования приложения, архитектуры, кода к минимуму, и желательно для любого уровня программиста)
И как изначально начался тред, императивно код писать лучше в нижних слоях приложения, либо выносить это в отдельные слои.
Почему вы думаете, что я не приемлю императивного кода ВЕЗДЕ я не знаю, я такого не говорил.
Понятиями «интерактивного кода» и «инвариантов», я не владею, сорри.
Под императивным я понимаю код формата
this.props.someStore.myCounter += 1
И этот метод описания прямо таки форсят, подавая как фичу технологии, используя такой стиль практически в каждой статье официальной доки.
Можно и с mobx писать декларативно, но тогда по сути, это ничем не будет отличаться от тех же редаксоподобных стейт-менеджеров, на самом низшем уровне получая функцию с сайд эффектом, либо интерцепторы, которые будут аналогами локальных редьюсеров.
Это у какой технологии такая суть? Как-по мне, суть MobX — снять с программиста заботу об отслеживании изменений в объектной модели единым и унифицированным для всего приложения способом. Он уже тот самый нижний уровень абстрации.
А сейчас даже Parcel люди не знают (или боятся), хотя он исправляет то, за что все критикую Вебпак (отвратительный DX с кучей конфигов).
Мой опыт с Parcel'ом: недавно исправлял issue в библиотеке от пользователя parcel'а с тем что он не умеет подставлять значения во время сборки (DefinePlugin
в вебпаке или rollup-plugin-replace
в роллапе), заменил на process.env.
которые parcel умеет. Дальше собираю демонстрационный проект с флажком для scope hoisting'а, прохожусь prettier'ом по собраному файлу чтоб посмотреть во что он там насобирал и с печалью вижу что у него проблемы с примитивным tree shaking'ом на уровне webpack'а и он не выкидывает кучу неиспользуемых функций.
У меня нет глубокого понимания на тему внутренностей бандлеров, возможно у Parcel'а правильная архитектура итд, но на данный момент меня совершенно не устраивает тот бандл, который он генерирует.
То же самое с Vue — все критикую Реакт что там ничего не понятно и сторонние библиотеки (типа роутера) плохие, но продолжают боятся Vue (так как он не мейнстрим).
Небольшая история о том как развивался Vue: когда-то давно(после выхода реакта) я и ещё один человек работали над библиотеками, реализующими vdom алгоритмы и очень сильно задротствовали на тему производительности, на тот момент мы не понимали очень много мелочей о том как правильно должен работать реконсайлер, где-то через пол года появился ещё один разработчик который написал свою ещё более примитивную библиотеку, которую он делал глядя в наши исходники и естественно понимал ещё меньше о том как правильно должен работать реконсайлер(худшая библиотека на тот момент в плане поведения), потом появился Vue2, который использовал исходники этой примитивной библиотеки с добавлением своих костылей :) В итоге vue вобрал в себя ужасные идеи, которые я использовал в своих старых поделках + примитивный дифф алгоритм с кучей заплаток для эдж кэйсов, о которых все кроме авторов Реакта даже не догадывались в 2016ом.
Виноваты авторы Реакта в том что у них есть большой багаж знаний и они понимают что невозможно сделать "one size fits all" решение и поэтому не пихают всё подряд в свою библиотеку? Может кому-то со стороны кажется что это всё недостатки реакта, но большинство критики реакта связано с отсутствием глубокого понимания предметной области.
Реакт есть за что критиковать и разработчики реакта часто умышленно умалчивают о различных недостатках своих решений, но приводить в пример Vue как решение проблем React'а — сомнительная затея.
На самом деле это очевидные мелочи, если не замарачиваться на тему производительности и в первую очередь думать о композиционных паттернах. Например, в моей старой библиотеке невозможно было менять рутовый элемент у компонент и это было ограничено на уровне API, а так как остальные библиотеки использовали те же самые алгоритмы, но при этом пытались делать API как у React'а, то естественно во всех библиотеках кроме реакта это не работало, и когда я рассказал другим об этой проблеме и сказал что нормальный фикс потребует изменить код в куче мест, большинство разработчиков пошли простым путём и начали использовать корявый фикс, который в случае таких кэйсов рекурсивно шёл по дереву вверх и патчил все несоответствия, в некоторых либах это даже приводило к тому что изменялся шэйп виртуальных нодов и повсюду срабатывали деоптимизации с мономорфных колсайтов на полиморфные, но так как в популярных бэнчмарках этот кэйс не проявляется, то никто не замарачивался :) В некоторых библиотеках этот кэйс до сих пор поломан.
Потом всплыла проблема с условным рендерингом, во всех вдом библиотеках кроме реакта, условный рендеринг в некоторых ситуациях приводил к тому что соседние элементы/компоненты теряли внутреннее состояние и чтоб нормально пофиксить эту проблему нужно либо полностью переписывать дифф алгоритм, либо сделать корявый фикс (как в реакте) и получить проседание в производительности на большинстве кэйсов со статическими листами, но так как почему-то разработчики популярных библиотек не в состоянии переписать алгоритмы, учитывая этот кэйс, то для того чтоб демонстрировать хорошую производительность на микробэнчмарках некоторые разработчики библиотек начали исползовать специальные флаги для "продвинутых" оптимизаций. Большая часть вдом библиотек до сих пор не учитывает этот кэйс.
Дальше там всякие проблемы из-за использования мутабельных нодов, проблемы с алгоритмами нормализации чилдрен листов, которые ограничивают возможности композиции.
Все эти проблемы я отношу к фундаментальным проблемам, но так как у реакта очень большая популярность, то им дополнительно приходится фиксить кучу проблем связаных с нормализацией поведения в различных браузерах. Например во vue долгое время закрывали issues'ы связаные с поведением innerHTML на svg элементах, и только когда накопилась критическая масса недовольных пользователей, то наконец-то это пофиксили. Недавно во vue начали появляться недовольные пользователи, у которых инпут поля работают неправильно в некоторых браузерах из-за порядка присваивания аттрибутов, но так как кол-во недовольных пользователей пока маленькое, то естественно там забивают на эту проблему, а в реакте из-за его популярности пришлось нормализовать поведение для всех этих мелких кэйсов и многих других, тк недовольных пользователей значительно больше.
где-то через пол года появился ещё один разработчик который написал свою ещё более примитивную библиотеку, которую он делал глядя в наши исходники
если не секрет, а что за библиотека, которую использовал vue ?
«The rendering layer has been rewritten using a light-weight Virtual DOM implementation forked from snabbdom»
- Разные версии библиотек — практически нет шансов поддерживать одну версию библиотеки на всех стримах разработки. Постоянные накладные расходы на поднятие версий и бесконечные рефакторинги. Отсюда невозможность делать нормальные шаренные компоненты. Если и получается сделать, то это жуткий урод с несколькими реализациями под разные версии библиотек (у нас в фирме есть ангуляры от 1 (который angularJS), до 7. Причём ни реакт, ни vue особо бы не решили этих проблем);
- Плохая уживчивость в одном UI нескольких инстансов фреймвёрка — различные методики встраивания одного приложения в другое, это адовая боль. Постоянные пересечения и ошибки при многослойном использовании. Простейшие кейсы выливаются в использование iFrame-ов и прочих костыляний;
- Ужасная кастомизируемость — практически невозможно сделать ничего рантайм-расширяемого. Как только клиент хочет расширения, вэлком в код и пересборки всего приложения под конкретный проект внедрения. Самое лучшее что придумали это в рантайме подгрузка компилятора на клиент и сборка ts/css на клиенте (AOT — основной костяк, JIT — подгружается он-деманд при встрече с динамическими компонентами);
И это самые безобидные проблемы «кровавого микросервисного интерпрайса» в мире фронтэнда.
Отсюда невозможность делать нормальные шаренные компоненты. Если и получается сделать, то это жуткий урод с несколькими реализациями под разные версии библиотек (у нас в фирме есть ангуляры от 1 (который angularJS), до 7. Причём ни реакт, ни vue особо бы не решили этих проблем);
При активной разработке фиксация версий — дурная практика, ибо приводит к протуханию зависимостей, поддержке множества версий, замедленной обратной связи и тп. Идеальный вариант — при каждом обновлении зависимости, все зависимые проекты пересобираются с прогоном тестов. Если какой-то сломался, то уже разбираемся нужен ли фикс в зависимости или в зависимом. Про кейс "некогда разбираться, надо зарелизить вот прям щас", я в курсе, но это уже прокол менеджмента, который должен предусматривать буфер для форс-мажоров. А сильно ломающее изменение общей зависимости не должно происходить прямо перед продуктовым релизом.
Фиксация нужна лишь для проектов, разработка которых замораживается и то, только лишь чтобы спустя годы, кто-то мог сдуть с него пыль и собрать. Если же планируется продолжение разработки, то первое, что нужно сделать — обновить всё до последней версии.
Плохая уживчивость в одном UI нескольких инстансов фреймвёрка — различные методики встраивания одного приложения в другое, это адовая боль.
Как я уже сказал спасает единая версия всего. Ну и не обобщайте, не все фреймворки одинаково бесполезны.
Ужасная кастомизируемость — практически невозможно сделать ничего рантайм-расширяемого.
Хотите фокус? Следите за руками:
- Возьмём простую демку с 3 связанными друг с другом полями с подсветкой синтаксиса. Вот весь её код.
- Грузим эту демку в рантайме, в рантайме же формируем интерфейс редактирования и можем менять эту демку как угодно. Пример, как это выглядит.
Собственно, я пилил всё это для "интерпрайза с человеческим лицом". Но современному интерпрайзу не нужно быстро, дёшево и качественно. Ибо он то и дело выбирает технологии, на которых делать медленно, сложно, поэтому нужна большая команда, поэтому всё это выходит дорого, поэтому нанимают кого попало по дешевле, которые не способны сделать качественно.
Бэкенд перешёл на систему либо стагнации, либо поддержки: в последние годы практически нет развития. И как следствие, у них другие приоритеты: когда у тебя нет новых фреймворков каждые полгода, это на тебя влияет. Они есть где-нибудь в Rust или Go, но Ruby — что там нового? Как следствие, люди сфокусированы на другом. Конечно, я очень упрощаю, и бэкенд бэкенду рознь.
Господин отравлен энтерпрайзом. Понятно что топовые разработчики за спасибо не работают — но описанная ситуация это как раз махровый энтерпрайз (2% сайтов аккумулирующих 98% денег).
Бэкенд не меняется, в лучшем случае, десятилетиями. Но не по причине консервативности или костенелости. Здесь работают деньги, тут нет места непроверенным технологиям и хайповым вещам, цена ошибки, как правило, довольно велика (здравствуйте перекрестные ревью и 100% покрытие тестами, которые все равно не исключают косяков, но хотя бы дают мнимую уверенность).
Но это не значит, что бэкенд врос на одном месте и не движется. Вспомните появление дотнета, меньше чем за 10 лет, он смог отгрызть у явы 30% рынка. Да, за ним стоял микрософт, но он стоял и за J# о котором сейчас помнят два с половиной олдфага. Так что если сегодня появится технология способная потеснить три столпа энтерпрайза (ява, шарп, кресты) — она найдет свой угол. Просто самим фактом.
Не то что React с vdom и компонентами, которые ещё в 2012 году уже были в Ractive. Или webpack, до которого конечно не было ни browserfly, ни других. Прорыв прямо.
Смысл, что нельзя использовать асинхронный код в плагине
Например, давно есть идея сделать babel-плагин, чтобы прогонять postcss-плагины через CSS-в-JS. Но это сделать сложно, так как в PostCSS много асинхронных плагинов (например, те, что конвертируют картинки в WebP) — в итоге приходится делать костыли.
Или, например, плагин может читать/писать на диск какой-то кеш.
- Например, внутри babel-плагина нельзя вызывать какую-то асинхронную функцию.
- А если вызывать
*Sync
версии функций, то это плохо влияет на производительность
Для клиента это может и проблема, но на бэкенде есть node-fibers.
Мой опыт говорит о ровно противоположном. Синхронные функции во всяком случае с SSD диском работают быстрее.
2. Ты неправильно тестируешь. Запусти много задач, которые будут читать диск или что-то ожидать от системы. Асинхронность позволит другому JS-коду выполняться, пока твоя функция ожидает данные от файловой системы или сети. Без асинхронности вся виртуальная машина будет заблокирована одним HTTP- или IO-запросом. Но на математике или на одной функции результата не будет — ты прав.
- Наоборот. Почему не завести нормальные сопрограммы в браузеры?)
- Я изначально сделал свой сборщик асинхронным, но работал он медленно. Потом перевёл его на синхронную модель и он стал летать. Всё дело в том, что ссд диски очень быстрые, а перед ними ещё и дисковый кэш операционной системы. А асинхронные функции — штуки не бесплатные и плохо оптимизируются. Ну вот, человек бенчмаркал и получил разницу в 3 раза: http://qaru.site/questions/2410357/moving-100000-files-in-nodejs-sync-async-performance-and-speed
Одно время только в веб было комфортно находиться: когда начал появляться ADSL, но люди ещё не включали 10 мб (или сколько его там) momentjs только для того чтобы один раз дату отформатировать. А из статьи я узнал что оказывается ещё и разработчики браузеров в этом замешаны.
Сейчас каналы позволяют хоть сотни мегабайт пропускать и всем стало по барабану на размер кода. Теперь «Hello World» весит один мегабайт и на несколько секунд укладывает процессор на лопатки при инициализации.
Эта проблема серьезная и почему-то лишь единицы обращают на неё внимание. Я рад что есть всё же люди, как Андрей, которые понимают это и занимаются этой проблемой. Глядишь так и победим.
Было бы интересно, если бы гугль додумается сайты маркировать индексом легковесности.
Сборщики и React задали тон
не думаю, что React тут как-то выделяется. Есть Gmail, написанный на технологиях на 7 лет старше реакта и тормозной ужасно.
NPM-среда, пакеты с зависимостями (сегодня только удалял «лёгкую» страничку на Ангуляре с 1200 папками и 70+ тыс файлами в node_modules)и, как следствие, ужасно раздутые бандлы
Вечное развитие всё равно невозможно. Всему есть предел.
Это как Java — огромный рынок, на котором всё хорошо, но ничего нового нет. Как с этой проблемой справиться — не знаю.
В чём, собственно, проблема-то? Если на рынке нет новинок — значит, имеющийся спрос удовлетворён. В данном конкретном случае (так как речь идёт о языке — инструменте для решения неких задач бизнеса), это значит, что это не платформа стагнирует — это принципиально новых проблем у бизнеса не появляется, а существующих инструментов с лихвой хватает на good-enough решение. Проблемы конкретно в Java сконцентрированы на самой передовой, где действительно есть запросы бизнеса, например, обработать запросов ещё на миллион (но лучше — десять) в секунду больше, чем сейчас. Вот на этой целине сейчас действительно бурления, от новых фреймворков до языков или кастомных сборок виртуальных машин. Даже хорошо забытые парадигмы программирования прикручивают.
Новинки ради новинок действительно просто из принципа не будут пользоваться широким спросом, ну просто из соображений абзацем выше. Меня вот, наоборот, настораживает такая бешеная гонка во фронте — если у бизнеса особо нет принципиально новых проблем на бекенде, то их, вероятно, примерно столько же и на фронтэнде. Но тогда получается, что всё это бурление происходит уже не по запросу бизнеса. А если принять во внимание, что с моей бекендовой колокольни видно, главным образом, прогресс инструментов сборки, то просто получается, что там одни программисты решают проблемы других программистов, параллельно создавая десятки слоёв протекающих абстракций, чем обеспечивают новый цикл решения уже новых проблем с протеканием, которые затыкаются ещё парой слоёв абстракций и goto 10
.
Проблема в том, что из-за моды все берут ожно и то же решение, даже для задач, где оно не подходит
Проблема в том, что из-за моды все берут ожно и то же решение, даже для задач, где оно не подходит
В Java берут? Не очень понимаю, как вы к такому выводу пришли. Не могли бы примеров привести, хотя бы парочку?
Я, конечно, могу сам накидать примеров из любой кодовой базы, где из-за моды все стали писать list.stream().forEach(...)
вместо любого другого варианта итерации, или бесконечные вопросы на StackOverflow, мол, "вот у меня работающий код, а как мне переписать всё на C++ Stream". Но тут масштаб не тот немного.
А вот по теме архитектурных решений проблема овер-инжиниринга в софте на Java, по моему впечатлению, не больше чем в софте на любых других платформах. Я наоборот много видел (и сам участвовал в) написанных велосипедов, потому что "ну не тащить же целую библиотеку из-за пары функций". И это при том, что я сам только в кровавом энтерпрайзе работал.
Андрей много интересных тем поднимает. Выскажусь только про стагнирует/не развивается. Это называется зрелость, после бурного развития от первых ajax-сайтов мы пришли к некоторму набору фреймворков, которые позволяют решать типичные задачи при разработке веб-приложения. И теперь пришла пора эти приложения, собственно, писать, с прицелом на больший жизненный цикл и более детальные потребности бизнеса.
Я, например, не собираюсь изучать Vue. Просто не понимаю, что он может мне дать чего нет сейчас в Angular. Аналогично с вебпаком, зачем мне тратить кучу времени на настройку Bazel, если веб-пак делает это уже все. У меня задача сделать приложение для пользователей, а не найти самый оптимальный сборщик. Я лучше сфокусириусь на своих текущих инструментах и бизнес-задачах.
В мире Java, на которые все ссылаются, не все тихо, Kotlin набирает обороты, как примерно TypeScript в мире фронтенда, а с ним и новые фреймворки. Я думаю так же будет и во фронте. После затишься появятся и новые фреймворки, и новые подходы. Все просто устали и хотят отдышаться.
TypeScript это надстройка над JavaScript, целиком наследует семантику и (если я правильно понимаю) не имеет собственной стандартной библиотеки.
Тогда как Kotlin — это самостоятельный язык, который, как и Java, компилируется в JVM-байткод… но может и не компилироваться, и ничего важного при этом, по сути, не потеряет.
ну JS сам по себе тоже стандартной библиотекой не блещет, поэтому обвинять в этом TypeScript как-то странно.
я не говорю, что TS это тоже самое что Kotlin. Просто тенденция очень схожа — базовый язык, в который уже компилируются либо разные диалекты, либо вообще новые языки как Elm, например
Про стандартную библиотеку я говорил не в обвинение (вообще странно обвинять транспилер в том, что он транспилер) — а потому, что TypeScript наследует библиотеку от JavaScript (с элементами, который тот в свою очередь наследовал от ECMAScript), в смысле что он экспортирует те же самые типы. Kotlin типов Java не экспортирует сам по себе, у него собственные.
Увы, мы очень далеки от зрелости. Стагнация проявляется в том, что инструменты выбирают по моде а не по тому, подходят ли они к задаче. Подходящие инструменты использовать боятся, так как не мейнстрим и не модно.
Я, например, не собираюсь изучать Vue. Просто не понимаю, что он может мне дать чего нет сейчас в Angular.
Мне показалось что ключевая мысль по поводу Vue была вот в чем:
… хотя у него решено всё, за что мы критикуем React.
Если для вас Angular итак идеален и Vue не решает никаких проблем Angular лучше, тогда действительно, зачем переходить? Не нужно.
ну есть мнение, что Vue взял лучшее от всех платформ. Мне просто лень. Возможно стоит посмотреть ради расширения кругозора. Но детально понять различие можно будет только на проекте, который я не вижу смысла начинать на Vue без внятных преимуществ
легко :)
Есть разные классы проблем:
- Невозможно сделать ${чтоТо}.
- Чтобы сделать ${чтоТо} нужно написать много кода.
- Чтобы сделать ${чтоТо} нужно решить головоломку.
- Легко сделать ${чтоТо}, но потом это ${чтоТо} приходится долго дебажить.
- Легко сделать ${чтоТо} медленным, но сложно потом оптимизировать.
- Легко сделать ${чтоТо} и не менее легко ${чтоТо} ненамеренно сломать.
- Легко сделать ${чтоТо}, но сложно его потом использовать.
- Легко сделать ${чтоТо} в одном проекте, но сложно воспользоваться им в нескольких.
Многие из них человек не осознаёт. А те, что осознаёт считает свойством платформы / предметной области / хорошей практики.
Чтобы сделать ${чтоТо} нужно решить головоломку.
Этот пункт прекрасно иллюстрирует ViewTree из $mol ;)
Ну и расскажите, что вам не удалось сделать в view.tree.
1) Подписывать фильтры на свойства, как вы хотите в вопросе — мне представляется каким-то совершенно убийственным решением: провернуть его, наверное, можно, но зачем? И как потом это всё отписывать? И, опять же, зачем конвертировать все свойства в обсерваблы, когда можно и не конвертировать?
2) Вам надо перефильтровать список в трех случаях: а) поменялись игрушки; б) поменялся фильтр; в) поменялось где-то что-то в зависимых свойствах. Вы в вашем коде сделали а и б — остаётся в (который в итоге скорее всего будет а+в одновременно). Очевидно, что вам нужен поток (коли речь про rxjs таки), который будет пушить новый массив игрушек, который вы дальше отфильтруете, в ответ на изменение одного из свойств, заданных где-то в виде массива строк. Т.е. ежели у вас фильтр по count, то помимо функции фильтра вам придётся указать, что у вас зависимость от count. Как с применением RxJS мониторить изменения свойств объектов — это лучше загуглить, изящного изкоробочного решения в самом RxJS нет (и вообще люди пишут, что Proxy тут будут удобнее).
Ваше описание напоминает мне инструкцию как нарисовать сову.
Вот, смотрите, код в орп парадигме, который перевычисляется только когда меняются те свойства, от которых результат реально зависит, при этом один раз, сколько бы источников данных ни изменилось за раз и сколько бы подписчиков ни было:
class $my_toys {
@mem
filter( next = toy => toy.count() > 0 ) { return next }
@mem
toys( next = [] ){ return next }
@mem
toys_filtered() {
if( !this.filter() ) return this.toys()
return this.toys().filter( this.filter() )
}
}
Сможете переписать его на RxJS сохранив те же качества?
И вот только после всех этих вопросов уже можно сравнивать легкость, красоту, и читабельность.
Если вы забыли, я напомню вам тему обсуждения:
Чтобы сделать ${чтоТо} нужно решить головоломку.
И всё же очень жду от вас хоть какой-нибудь код, пусть даже не красивый и на коленке, но выполняющий поставленную задачу, а не разглагольствования о качестве поддержки от больших корпораций.
А по вашему мешать в кучу декларативку с императивкой, как в реакте, в результате чего теряются все преимущества декларативки, и даже часть преимуществ императивки — это хорошо? Обратите внимание, вы не назвали ни одной объективной причины, чем же view.tree плох. Одна предвзятая вкусовщина.
Это всё необъективно — но и код у нас пишут необъективные унылые meat bags, которым вечно чё-то не нравится. Как только код будут писать нейросетки — так всё будет нормально, у них субъективного неприятия не будет.
А по вашему мешать в кучу декларативку с императивкой, как в реакте
Можно не мешать. Взять стейт менеджер и растащить в разные стороны, всё равно родное управление стейтом в реакте масштабируется только с болью и миллионом оберток. Конечно какой-то совсем смешной минимум императивного кода в компонентах всё равно останется, ну да и пусть.
А я и не претендовал на объективность.
А я вот претендую, чего и вам советую. Это полезно как для карьеры, так и вообще по жизни. А нравится/ненравится — оставьте хипстерам и овуляшкам.
Взять стейт менеджер и растащить в разные стороны
Оно-то тут при чём? Речь шла об этом непотребстве:
function List( files ) {
return (
<div>{ files.map( file =>
file.type === 'dir'
? <Dir name={ file.name } icon={ CustomFolderIcon } />
? <File name={ file.name } />
) }</div>
)
}
Первый же вопрос: зачем здесь два разных компонента, если даже в массиве files
директория — это всего лишь тип файла? В остальных случаях это легко рефакторится, например, в функции. Тернарник никуда не денется, но станет читабельнее.
Довольно слабая позиция докапываться до примера. В реальном коде на реакте всё куда хуже. Но если на то пошло, то директория и файл отображаются и ведут себя совсем по разному.
Да как ни переставляйте, суть одна:
- Код не декларативен, так как вы не можете ничего о нём сказать программно, пока не выполните.
- Если вы вынесете вложенные компоненты в функции, то потеряете наглядность иерархии.
- Вы не можете поменять параметры вложенного компонента не перерендерив внешний, и параметры внешнего, пока не перерендерите параметры ещё более внешнего. И так далее, пока не дойдёте до того места, где параметры берутся не из пропсов.
- Вы не контролируете как будет проинициализирована ваша же иконка.
А как, кстати, у $mol дела обстоят с подсветкой синтаксиса? React, Vue, Angular поддерживаются IDE (по крайней мере продуктами от JetBrains) и некоторыми текстовыми редакторами вроде Visual Studio Code.
что такое DХ?
Вообще wasm развивается и в перспективе серьезно встряхнет фронтенд.
Это в любом случае будет лучше в будущем, не в плане обьема, а в плане того, что этот wasm код можно быстро откомпилировать в нативный и сайты смогут работать быстро. В конце концов разбирать байткод намного быстрее, чем высокоуровневый js
wasm это универсальный механизм во первых а во вторых части рантаймов можно держать прямо в браузере. Или сделать общий репозиторий wasm модулей и не качать одно и тоже по 10 раз.
Просто так и так вэб уже простым не станет опять, надо с этим смириться
Проблема в том, что реальная скорость загрузки сайта зависит уже от других параметров… Это время очень большое, до 500 мс. Во-первых, из-за ограничения скорости светаВот и приплыли. Современным сайтам уже скорость света кажется недостаточной.
нет, не занимаетесь, не создавайте новые опенсорс-проекты...Я пришел к выводу, что опенсорс проекты нужно делать «just for fun», а ответственность за проекты должна уже обговариваться.
Про деньги, иногда возникает мысль что «художник должен быть голодным», пример команда Angular — осваивает деньги и должна выдавать какой-то результат, в итоге разработчики, которые не «едят» свой продукт, генерят кучу кода, тем самым создавая неповоротливого монстра, или Meteorjs — нанимали «джунов» для «освоения» раундов, подобно выглядит и Vue где первая версия была простая, но после потока денег появилась ответсвенность «в развитие», и он тоже начал обрастать, медленно превращаясь в монстра (хотя это только взгляд со стороны, на vue уже давно не смотрел), с другой стороны, без денег проект может просто умереть.
Ещё есть грустные примеры с MongoDB и Amazon, или то что PHP вытянул MySQL, в результате автор mysql разбогател, а автор PHP не особо, или то что Марк Цукерберг разбогател воспользовавшись этим самым PHP, а получил ли что-то автор?
Вообщем OpenSource это не про деньги, и в этом плане что то тут «сломано», т.к. как раз благадоря open source появились гуглы, фейсбуки и подобные…
Сравнивать PHP с MySQL и Facebook как минимум странно.
Сравнивать PHP с MySQL и Facebook как минимум странно.MySQL стал популярен потому что PHP добавил его поддержку, впоследствии автор MySQL разбогател, фейсбук использовал (беспатный) PHP и заработал кучу денег, т.е. многие компании зарабтаывают кучу денег используя твой продукт, а ты с этого ничего не имеешь, у вас нет ощущения что автора PHP «обделили» деньгами?
автора PHP
Это точно был один человек, а не отдел сотрудников ФБ, которые его патчили?
PHP — это язык программирования, низкоуровневый инструмент для разработки веб-сервисов вроде FB. Это не конечный продукт даже не смотря на стандартную библиотеку внутри. Установив его и настроив, тебе еще нужно написать сам продукт. Если бы создатель PHP написал на его основе самую популярную в мире CMS, например, тогда он бы тоже заработал кучу денег. А у него была такая возможность, потому что в какой-то момент он наверное лучше всех знал и понимал PHP. PHP стал самым распространенным тулом в вебе, стоит на всех хостингах (и кстати не потом что автор PHP приложил к этому маркетинговую руку). Автор PHP просто не посуйтился, а скорее всего не захотел это никак манетизировать.
MySQL — это тоже software продуктЭто смотря как посчитать, а mongodb продукт? а linux/docker...? это все инструменты не для «конечного пользователя», и тут оно очень размыто.
Автору MySQL повезло, что его купили, но этого могло и не произойти.
PHP — это… низкоуровневый инструментЛюбой инструмент который вам помогает что-то сделать может что-то стоить. Если бы не PHP то фейсбука могло бы и не быть.
Разница в том, что в одних сферах за продукты платят, а в других — нет. Возможно это просто закон спроса — предложений, а может просто что-то «сломано».
Вот Docker — хороший «продукт», но если команда «закроется» (от того что нет прибыли), то будет обидно.
Ещё есть грустные примеры с MongoDB и Amazon
А что с ними было?
Да, — Java давно уже "окоболилась". — Я помню как она взлетела в 1995 году!
Да, — — остальные забились в ниши.
Да, так бывает, — к примеру на сервере окончательно победил Node.js (для JS) — (лет 5 назад там было несколько его конкурентов).
Да, рано или поздно революции заканчиваются.
Да, большинству народу всё равно — так как все эти «окоболившиеся» технологии приносят бабло.
Да, скучно.
Iskin
Мы в школе привыкли, что язык — это правила, особенно с токсичной русской культурой, где мы постоянно критикуем разных людей.А вот это новая мысль для меня! — Эта ваша мысль о "токсичной русской культуре". Я думаю в этом случае виноват… Белинский.
В школе мы учили логику на уроках геометрии. — «В жизни логики нет» (С)
Зубрили химию, физику, биологию, анатомию. (Ну, типа вот дано так и… всё!)
И постоянно критиковали на уроках литературы, используя паттерны статей Белинского.
Но если «Пора валить из фронтенда» то куда?
В нашей компании мы замечаем, что фронтенд, как достаточно молодое направление разработки, нуждается в людях с классическим академичиским образованием, в тех, кто изучал Java, C#, в тех, кто мыслит типами. К сожалению сейчас засилье Javascript разработчиков, которые знают только и учили только Javascript. Большинство из них даже не будет знать о существовании bigint в вашем PostgreSQL.
Вот только люди с академическим образованием предпочитают держаться в стороне от фротенда, и я их в этом прекрасно понимаю.
Мало платят? Не дают принимать архитектурные решения?
На деле же от того, что некоторые игнорируют границы применимости инструмента (а именно об этом вы говорите), сам инструмент плохим не становится.
Система рендеринга оперирует «примитивами рендеринга». Есть код, который переводит «модель интерфейса» в «модель примитивов рендеринга» — это один слой абстракции. Система построения пользовательского интерфейса оперирует «визуальными компонентами». И есть код, который переводил «прикладную модель» в «модель интерфейса» — это другой слой абстракции. И так далее. Всё приложение — это набор слоёв абстракций, дополняемых как сверху (ближе к пользователю), так и снизу (ближе к серверу), и даже сбоку (ближе к железу). И одна и та же сущность для одного слоя является «моделью», а для другого — «отображением модели с предыдущего слоя».
Заметьте — если у вас C спрятан где-то глубоко в недрах, откуда наружу торчит только
{myImportantProperty}
— это вовсе не значит, что C у вас нет — просто он достаточно абстрактный чтобы понимать декларативные биндинги.Ну, M и V нужны всегда, к примеру.
M в простых приложениях типа "загрузил и показал" часто вообще не выделяют. Прямо в V делают запрос к серверу и тут же показывают результат.
Даже если вы C напрямую не пишете.
Это и значит, что C в вашем приложении нет. MVC — это не метафизические сущности, а конкретные слои, на которые вы разбиваете код вашего приложения.
Ну раз уж пошла такая пьянка, вот чуть вольное переложение из той самой википедии:
Модель — предоставляет данные и методы работы с ними (запросы к серверу, проверка на корректность). Не "знает" как данные визуализировать и не имеет точек взаимодействия с пользователем.
Представление — отвечает за получение данных из модели и доставку данных пользователю.
Контроллер — обеспечивает прохождение данных от пользователя к системе и обратно. Использует модель или представление в зависимости от требуемого действия.
Вернитесь к моему первому комментарию в ветке, там, по-моему, практически то же самое и написано, с поправкой на постулат о возможной замене Controller'а Presenter'ом — и это, согласно цитате, как раз то, в чём я здесь не прав.
Зато загрузка данных с сервера, даже в простых приложениях — ответственность именно модели, и выходит, что без неё на самом-то деле никуда — разве что у вас там запрос синхронный (звоночек, кстати), и всё нафигачено прямо в одной и той же функции — и загрузка, и обновление DOM. А вот если функций несколько — высока вероятность, что одна будет носить функции модели, а вторая — функции представления. Ну а раз как-то модель с представлением связывается…
Странно что еще не появились аппаратные ускорители этого
Очень высокомерный пост. Читать было крайне неприятно.
«Пора валить из фронтенда»: Андрей Ситник о стагнации сообщества, опенсорсе и не только