Closed vitkarpov closed 8 years ago
Это про чистый HTML. Я скорее про:
<Popup js={{ "foo": this.ctx.foo }}>
<MyBlock title="Hello, world!" />
</Popup>
require('html2bemjson').convert(`
<Popup js={{ "foo": this.ctx.foo }}>
<MyBlock title="Hello, world!" />
</Popup>
`);
/*
{ tag: 'popup',
attrs: { js: '{{', '"foo":': '', 'this.ctx.foo': '', '}}': '' },
content: { tag: 'myblock', attrs: { title: 'Hello, world!' } } }
*/
Насколько я понимаю, нужно лишь добавить поддержу {{}}
в атрибутах?
Это да, но не только. В данном примере должен получиться:
({
block: 'popup',
js: { 'foo': ... },
content: {
block: 'my-block',
title: 'Hello, world!'
}
})
Т.е. идея в том, чтобы описывать именно БЭМ-дерево, а не HTML, более лаконично.
Под капотом, шаблонизатор все равно будет работать с bemjson, а человек — с jsx
Я почему про это подумал (не только я, идея очевидная). Кажется, что компонентный подход стал популярнее в последнее время, с распространением реакта, во многом благодаря тому, что дерево компонентов описывается, условно в привычном для многих XML (HTML), нет?
Если это правда кто-то будет использовать, то сделать можно, дело не хитрое. Но что-то есть у меня сомнения.
Если запилю, вы действительно будете использовать у себя на проектах?
Пока это просто вброс — интересно, что народ думает
Мне кажется, что для ребят, которые привыкли «верстать статичный HTML», а так же для тех, у кого «реакт головного мозга», такой интерфейс будет привычнее — соответственно, порог вхождения уменьшится (просто мысли, не факт)
Мне кажется, что для ребят, которые привыкли «верстать статичный HTML», а так же для тех, у кого «реакт головного мозга», такой интерфейс будет привычнее
Да, но порог это врядли уменьшит, и, вероятно, будет больше путаницы.
Но минусов в том, чтобы уметь собирать из bundle.bem.xml
вместо bundle.bemjson.js
, я не вижу ;-).
Но минусов в том, чтобы уметь собирать из bundle.bem.xml вместо bundle.bemjson.js, я не вижу ;-).
Лишь бы толк был, а не «еще один стандарт», как в известном меме :)
@vitkarpov это невозможно. Можно только конвертировать bemjson в jsx. Обратно без дополнительных знаний не получится, потому что на одном уровне jsx находится несколько уровней bemjson. Например, не существует возможности отличить value в jsx от { block: 'b', value: value }
, { block: 'b', attrs: {value: value} }
, { block: 'b', mods: {value: value} }
, { block: 'b', mix: {block: 'b2', value: value} }
. Самое важное во всем этом, что правила конвертации для каждого блока уникальны.
Это касается безусловно плоской записи. Если есть желание писать примерно так:
<BEM block='b1' mods={{ mod1: 'val1' }} attrs={{ value: 'val' }} mix={{}}>content</BEM>
То сделать действительно легко, как и сказал @tadatuta, но кажется в этом нет смысла. Ибо в реальном коде это превратится в:
<BEM
block='b1'
mods={{ mod1: 'val1' }}
attrs={{ value: 'val' }}
mix={{}}>
content
</BEM>
@awinogradov это да — придется вводить дополнительные соглашения, например, введя пространство имен для зарезервированных атрибутов:
<Popup bemMix="..." bemMods="..." bemJs="...">
ну или запретить использовать эти атрибуты в качестве кастомных, для АПИ своего компонента :)
Я уверен, что найдутся и другие неоднозначные моменты.
@vitkarpov я могу рассказать как мы решаем это в Лего)
«это» — что именно? :) Упрощаете синтаксис bemjson?
Реализуем интерфейс на jsx в React для бэм-компонентов.
Это история про jsx-адаптер?
Я не знаю что это такое) Но история есть и длинная)
Ну, я имею ввиду, что можно писать jsx, вместо bemjson, который, под капотом, bemhtml умеет понимать в рантайме?
Если это другая история — конечно, интересно послушать :) Если это укладывается в рамки форума, конечно.
можно писать jsx, вместо bemjson, который, под капотом, bemhtml умеет понимать в рантайме?
Именно так ;)
Если это другая история...
Почему другая если проблема одна?)
Не, задача та же, я про то, что эту историю я знаю. Нормальный ход! Согласен с тем, что компилировать, возможно, смысла и нет, если можно научить шаблонизатор понимать другой формат описания входных данных.
А есть в этом реальная польза, в смысле, все радостно начинают писать xml вместо bemjson?
Нет, но мы решили инкапсулировать весь многогранный мир БЭМ за простым API в jsx для React-пользователей. Условно мы живем в чужом стеке по его правилам, что дает понимание как работать с компонентами разработчикам, которые уже знакомы с React. Кроме того такая инкапсуляция позволяет защитить разработчика от разного рода фривольностей. При таком подходе он может модифицировать компонент только так как это позволяет пропсы. Влезть внутрь и поменять bemjson он не может.
в jsx для React-пользователей
Ммм, кажется, я не совсем понимаю — надо уточнить. А если нет Реакта?
Условно, я фрилансер, и хочу сверстать простой лендинг на БЭМ. Хочу побить всю страничку на компоненты, продумать их АПИ, далее описать страничку в xml (как в старые добрые времена), и получить HTML в браузер — не важно, статичную верстку один раз, или накладывать шаблоны на сервере в рантайме.
Мне не нужно, что бы jsx компилировался в React.createElement
и все такое.
Кроме того такая инкапсуляция позволяет защитить разработчика от разного рода фривольностей.
А всякие миксы и мода js
?
А всякие миксы и мода js?
Миксы деградировали до нативного className
. js
мода отвалилась, ибо нужна только для i-bem
.
Мне не нужно, что бы jsx компилировался в React.createElement и все такое.
Мы превращаем jsx
в bemjson. Так как bem-xjst
понимает именного его. Мы обрабатываем результат выполнения React.createElement
.
Мне не нужно, что бы jsx компилировался в React.createElement и все такое.
Это невозможно) Вернее как, если кастомно по-своему реализовать компиляцию, то можно и машку. По одной простой причине: jsx
нужен чтобы коротко описывать React.createElement
.
<div className='test'>text</div>
Компилируется в:
React.createElement('div', { className: 'test' }, 'text');
Мы превращаем jsx в bemjson. Так как bem-xjst понимает именного его. jsx нужен чтобы коротко описывать React.createElement
Что-то не совсем пойму, давай попробую сформулировать, а ты меня поправишь.
Есть такой bemjson:
({
block: 'popup',
content: [{
block: 'button',
text: 'Hello, world!'
}]
})
сейчас это дело принимает шаблонизатор и выдает html.
Хочется:
<Popup>
<Button text="Hello, world!" />
</Popup>
по-прежнему, это дело принимает шаблонизатор и выдает html.
Если jsx компилирует в React.createElement
, то и рендерить это дело должен реакт — при чем здесь bemhtml
?
Если jsx компилирует в React.createElement, то и рендерить это дело должен реакт — при чем здесь bemhtml
Т.е. задача не в том, чтобы по bemhtml-шаблонам получить jsx и скормить его реакту (это задача про «научить реакт понимать bemhtml»), а в том, чтобы позволить человеку писать jsx вместо bemjson.
Что я упускаю?
jsx нужен чтобы коротко описывать React.createElement
Наверное, лучше вообще абстрагироваться от jsx и говорить xml :)
({
block: 'popup',
theme: 'action',
mods: {'action': 'action'},
action: {text: 'install me now'},
content: {
block: 'button',
mix: {block: 'popup', elem: 'button', mods: {'action': 'yes'}},
attrs: {name: 'id-4'},
name: 'Hello, world!',
text: 'Hello, world!'
}
})
Наверное, лучше вообще абстрагироваться от jsx и говорить xml
Примерно лет 6 назад в Лего появился скрипт, превращающий XML в BEMJSON ;)
@tadatuta Вот. Практика показывает, что это плохой путь! Ну или не практика. И не показывает. И не такой уж плохой.
да всё просто по кругу идёт 🌀
@vitkarpov можешь мой bemjson
перевести в jsx
?
я не набрасываю если что
Примерно лет 6 назад в Лего появился скрипт, превращающий XML в BEMJSON ;)
@tadatuta а почему это произошло? Насколько я понял, потому что умирал xslt и все переписывалось на JavaScript, а какой родной формат представления данных в JavaScript — json. Т.е. сам по себе xml не плох, а именно в сочетании с xslt-шаблонами, верно?
@Yeti-or ты к тому, что в значениях многих атрибутов json и не очень ясно как это вытянуть в плоский список атрибутов?
@vitkarpov нууу, не знаю... сам по себе XML, конечно, неплох, но возможность в BEMJSON сделать [].map()
и прочие JS-штуки — это приятно :)
сделать [].map() и прочие JS-штуки
Ну, с jsx это как раз можно сделать:
{this.ctx.users.map(user => {
return <User name={user.name} />;
})}
лучшее из обоих миров :)
Спасибо всем за обратную связь, в целом, я понял что и как 👍
Коллеги!
Для описания БЭМ-дерева мы используем bemjson (или bemtree, который позволяет создавать полный bemjson страницы по частям, что по сути — то же самое, верно?) Однако, по своей природе json — довольно многословный формат представления данных, а html (jsx) более лаконичный.
Есть какие-то трансляторы jsx -> bemjson? Наверняка, кто-то думал в эту сторону, имеет ли это практичный смысл?