Однако не всё так просто. В конце концов, мы не только пишем код, но и решаем однотипные проблемы:
- Как сделать наше приложение быстрым?
- Как писать понятнее и проще?
- Как писать быстрее?
Кто-то может сказать: «Эту тему уже миллион раз обсасывали, зачем опять?». Но, все же, если вы запускаете новый проект или решили переписать старый, перед вами всё равно встанет проблема выбора. И даже если вы считаете, что всё очевидно — это далеко не так.
Вот уже год как Wrike использует Angular 2 в бою. И вроде всё хорошо, но иногда закрадываются сомнения: “А вдруг мы свернули не туда?”
В этом докладе мы постараемся быть «ближе к земле». Никакой зауми, слов «ну, в теории...». Возьмём реальный пример, за который вам заплатят денег, и будем смотреть на него с разных сторон, пытаясь выжать весь сок из двух конкурентов.
Мистер Красный (Евгений Гусев) и мистер Синий (Илья Таратухин) спорят, доказывают, демонстрируют примеры, пытаясь понять, что же лучше.
Будет боль, будет спор, будет вывод (видеозапись доклада с фестиваля РИТ++, Москва 5.06.2017).
Комментарии (40)
Alexeyco
27.06.2017 13:48Как писать понятнее и проще?
Лучше быть богатым, но здоровым, чем бедным, но больным (с)
Как писать быстрее?
vintage
27.06.2017 14:36-1Для сравнения, полный код приложения с прогнозом погоды на $mol:
/my/weather/weather.view.tree
$my_weather $mol_page title \Weatcher app api_base \http://weather.example.org/ body / <= City $mol_string hint \City name value?val <=> city?val <= Forecast $mol_view sub / \Forecast: <= forecast \
/my/weather/weather.view.ts
namespace $.$mol { export $my_weather extends $.$my_weather { forecast() { const uri = new URL( this.api_base() ) uri.searchParams.set( 'city' , this.city() ) return $mol_http.resource( uri.toString() ).json().forecast } } }
Kikun
27.06.2017 18:26+3/my/weather/weather.view.tree
Если смотреть это с точки зрения читаемости, то выглядит оно не оченьvintage
27.06.2017 19:21-3Какие мы нежные :-) А конкретней, что не так?
raveclassic
27.06.2017 23:43Боги, да все не так. Вам уже пол года, если не больше, об этом говорят.
vintage
28.06.2017 08:47Кроме аргумента "я не хочу ничего изучать, я хочу бац-бац и в продакшен, а после меня хоть потоп" я ничего за пол года так и не услышал. Может я что-то пропустил?
raveclassic
28.06.2017 10:58Ну просто мы неправильные пчелы.
А если серьезно, изучать что-то должно нравиться, либо под дулом заказчика. Так как $mol не про второе, то остается только первое, но ваши шаблоны не вызывают чувства эйфории. Вы их разработали, вам с ними хорошо и просто, а мне (как и остальным) — нет. Попробуйте поменять синтаксис на что-нибудь более… спокойное, возможно как плагин к парсеру.
raveclassic
28.06.2017 11:03Кроме того, крайне большим шагом к адаптации станет плагинчик-хайлайтер к тому же vscode/atom, чтобы не нужно было ломать глаза среди забора торчащих в разные стороны слэшей и стрелок.
vintage
28.06.2017 11:51Для Атома есть. Правда ставить его сейчас приходится через клонирование репозитория :-(
Ещё есть плагин для WebStorm, но в репозитории он для старой версии Tree. К сожалению JetBrains что-то сломали и новые билды плагина не хотят работать.
vintage
28.06.2017 11:46ваши шаблоны
Какие ещё шаблоны? У нас нет никаких шаблонов. Всё, что у нас есть — это компоненты и описание их коммуникаций.
Попробуйте поменять синтаксис на что-нибудь более… спокойное
"Спокойное" — это как? Вот тут я пробовал описывать одно и то же в форматах Tree, XML, JSON. Какой вариант вам больше по душе?
raveclassic
28.06.2017 12:57Какие ещё шаблоны? У нас нет никаких шаблонов. Всё, что у нас есть — это компоненты и описание их коммуникаций.
Называйте, как хотите. Представление у вас живет отдельно от логики.
Вот тут я пробовал описывать одно и то же в форматах Tree, XML, JSON.
Ну так а почему вы об этом не говорите никогда? Вот слушал я вас на РИТ++ — ни слова, даже вопрос вам задали, а где разметка то?
Явно меньше углов для перехода у html-подобного варианта. Именно поэтому JSX такой популярный, в отличие от формата, используемого в elm/purescript (обычные функции).
vintage
28.06.2017 14:00Называйте, как хотите. Представление у вас живет отдельно от логики.
Структура живёт отдельно от логики, а вместе со стилями они образуют представление.
Ну так а почему вы об этом не говорите никогда? Вот слушал я вас на РИТ++ — ни слова, даже вопрос вам задали, а где разметка то?
Так доклад про реактивное программирование, а не про разметку был :-)
Явно меньше углов для перехода у html-подобного варианта. Именно поэтому JSX такой популярный, в отличие от формата, используемого в elm/purescript (обычные функции).
Только вот во view.html ещё сложнее разобраться, чем во view.tree, так как используемые идиомы очень криво ложатся на html. Можно отказаться от идиом, но тогда получится ещё один клон Ангуляра — зачем оно надо?
raveclassic
28.06.2017 14:43Так доклад про реактивное программирование, а не про разметку был :-)
Неправда, доклад был про $mol, хоть и назывался по-другому :)
Только вот во view.html ещё сложнее разобраться
Ну не знаю, мне все стало кристально ясно. Но писать везде bind тоже не очень. Но я уверен, что все-равно можно накрутить html-подобный DSL с удобным неявным связыванием.
vintage
28.06.2017 15:21Неправда, доклад был про $mol, хоть и назывался по-другому :)
Примеры были на $mol_mem, а доклад был про ОРП и бонусы, которые он даёт. Половину этих бонусов вы можете получить с MobX, например.
Ну не знаю, мне все стало кристально ясно. Но писать везде bind тоже не очень. Но я уверен, что все-равно можно накрутить html-подобный DSL с удобным неявным связыванием.
Не знаю, что там вам стало "кристально ясно", но суть bind вы так и не поняли :-) Суть его в том, что у каждого элемента (как и у любого другого свойства компонента) должно быть уникальное имя, по которому к нему можно обратиться. И имя это может быть задано только программистом вручную.
raveclassic
28.06.2017 15:29Примеры были на $mol_mem, а доклад был про ОРП и бонусы, которые он даёт. Половину этих бонусов вы можете получить с MobX, например.
Может, тогда не стоило приводить примеры на $mol? Потому что проблема не в "ОРП", а в нем.
Суть его в том, что у каждого элемента (как и у любого другого свойства компонента) должно быть уникальное имя, по которому к нему можно обратиться. И имя это может быть задано только программистом вручную.
Ну значит у вас кривые примеры. Если это не bind в привычном понимании (связывания значения элемента представления со значением поля модели), но поправьте доки. Понять, что это такое из примера в виде .tree вообще невозможно. С доками кстати тоже большая беда, да, много всего, но что с этим делать — не понятно ну вот совсем.
vintage
28.06.2017 15:40Может, тогда не стоило приводить примеры на $mol? Потому что проблема не в "ОРП", а в нем.
Какая проблема?
Ну значит у вас кривые примеры. Если это не bind в привычном понимании (связывания значения элемента представления со значением поля модели), но поправьте доки.
Да нет, это bind. Просто значением является вложенный компонент. Это очень мощная идиома, позволяющая динамически отрендерить что угодно во что угодно. Без плясок с бубном как в Ангуляре и не ломая переиспользование узлов, как в Реакте.
raveclassic
28.06.2017 16:03Какая проблема?
Жуткий синтаксис и отсутствие хорошей документации с хорошими примерами.
Да нет, это bind. Просто значением является вложенный компонент. Это очень мощная идиома, позволяющая динамически отрендерить что угодно во что угодно. Без плясок с бубном как в Ангуляре и не ломая переиспользование узлов, как в Реакте.
Мне кажется, что стоит написать статейку разжевывающую именно этот момент. Потому что в Реакте я делаю
const Wrapper = ({Child}) => ( <div> Hi, <Child/> </div> );
и прекрасно себя чувствую...
Wriketeam
28.06.2017 16:10Коллеги, ветка как-то переросла в оффтоп-обсуждение темы, мало связанной с постом. Может, это достойно отдельной публикации?
vintage
28.06.2017 16:19Жуткий синтаксис и отсутствие хорошей документации с хорошими примерами.
В моём докладе не было ничего про "жуткий синтаксис".
Потому что в Реакте я делаю и прекрасно себя чувствую...
А стилизуете/локализуете вы это дело как?
raveclassic
28.06.2017 16:32l10n/i18n через react-intl
Стилизация/темизация через те же HOC/HOF и react-css-themr
Ладно, тут Wrike уже жалуется на оффтоп
vintage
28.06.2017 17:20О том и речь, что такой простой код у вас только в комментариях на Хабре, а в реальном проекте он неизбежно обрастает костылями:
import React, { Component } from 'react'; import { themr } from 'react-css-themr'; import { FormattedMessage } from 'react-intl' import { SuccessIcon } from 'icons'; import successTheme from './SuccessButton.css'; @themr('MySuccessButton', successTheme) class Button extends Component { render() { const { theme, icon, title } = this.props; return ( <button className={theme.button} > { icon || <SuccessIcon /> } <span className={theme.text} >{ title || <FormattedMessage id='SuccessButton.title' /> }</span> </button> ) } } export default Button;
.button { padding: .5rem; } .text { margin-left: .5rem; }
На "жутком синтаксисе" всё куда проще:
$my_button_success $mol_button sub / <= Icon $mol_icon_success <= Text $mol_view sub / <= title @ \Success
[my_button_success] { padding: .5rem; } [my_button_success_text] { margin-left: .5rem; }
raveclassic
28.06.2017 18:09Где костыли-то? То, что вы называете "костылями", на деле является инкапсуляцией стилей и управлением зависимостями через css-модули, чего, судя по всему, ваш $mol лишен.
В любом случае, вы теряете нить обсуждения, так как мой изначальный посыл был про документацию вашего $mol и кривейший синтаксис. А "костыли в реакте" мне как-то по сотому разу обсуждать не охота.
bano-notit
28.06.2017 00:43Синтаксис вообще незнакомый. Если у ng всё же ближе к html, у JSX тоже как-то входит стандартный код для шаблонизаторов, то тут вообще новое. Нету ассоциаций с привычными вещами. Тут нужно с нуля по факту учить синтаксис. Я именно из-за привычности в своё время выбрал Pug (ранее haml) вместо Slime.
eXtReeM
28.06.2017 04:02Вроде как PUG ранее был Jade
bano-notit
28.06.2017 18:43Да, совершенно забываю… Сейчас то он называется pug, но я и им уже не пользуюсь...
vintage
28.06.2017 08:42pug очень похож на html?
RubaXa
28.06.2017 09:57+3Он похож на не совсем стандартный CSS, но похож, а tree просто изобилует разными спец символами и нет ничего похожего на теги, css-классы или атрибуты.
Поэтому без глубокого погружения невозможно оценить на сколько лучше стало или как хоть это сопоставить с кодом на другом FW.
Напишите же в конце концов статью, где будет описан процесс создания простой «Кнопки» с нуля, без использования уже готовых
$mol_*
-компонентов.
Главное, в этом примере должно быть не просто «вот так делается кнопка», а «раньше вы писали вот такой HTML», а «теперь вам достаточно всего вот такой записи».
Затем показать, как добавить такой кнопки
title/disabled
, кастомные атрибуты, запихать внутрь текст + иконку и сделать возможность, чтобы при передачеhref
свойства, кнопка использовала тегa
, вместоbutton
.
Финальный шаг, как интегрировать эту кнопку в уже готовое приложение не на
$mol
.
P.S. В конце можете написать, что ничего этого делать не надо, 99% компонентов уже имеют стандартную реализацию, например вот Кнопка.
raveclassic
28.06.2017 11:00Вот именно, я, честно говоря, так до сих пор и не понял, как вообще на нем верстать обычную верстку.
bano-notit
28.06.2017 00:43+2А вы всё со своим $mol всё бегаете… Заканчивайте уже, только вы его рекламируете, а не он себя.
hlebbobulka
27.06.2017 18:58-1Заметил, что участники подобных дискуссий с завидной регулярностью забывают рассмотреть возможность быстрого порта логики на мобильные устройства. И вот тут (да не заминусют меня ангулярщики) Ionic проигрывает по скорости и удобству(субъективно), тогда как React Native заметно шустрее. А для пишущих, что Vue.js — вообще сказка, соглашусь, но только в том случае, если вы бэкендщик и вам нужно быстро накидать приличный фронт особо не влезая в js (gitLab — отличный пример использования Vue.js на фронте).
Neyury
Кажется на все эти 3 вопроса отвечает vue.js, хотя по поводу быстродействия можно долго спорить.
igontarev
я за vue.js, но однозначно он не отвечает на эти три вопроса, главное проблема его в том, что любой компонент знает о store, и ты можешь в компоненте кнопки написать this.$store.dispatch('addComment'), и как тогда переиспользовать компоненты, в ng есть DI, в реакте есть redux connect, которые выносят логику из компонента
jMas
Я думаю эта проблема может решаться обращениям к стору только из high order компонентов, причем здесь вроде бы все ок со стором — ведь его можно подменять на любой другой. redux-овый connect ведь тоже пробрасывает dispatch. Мне импонирует больше redux, так как он эксплуатирует функциональный стиль.