Открыл я amdy.su, присмотрелся — и действительно.
На первом DOM-узле 42 класса (да-да, modernizr же), на body — айдишник и еще 3 класса (конечно, это все WordPress). Cтраница делает 25 запросов за JS-файлами.
Бедные разработчики из больших бюрократизированных компаний, конечно, не могут себе позволить таких простых человеческих радостей ;)
1. Можно группировать блоки по смыслу. Например, мы используем группировку по платформам: common.blocks, desktop.blocks, touch.blocks и т.д.
2. Блоки могут иметь зависимости, только эти зависимости должны быть явные. Чтобы при необходимости повторно использовать блок, его перенос на другой проект автоматически доставлял все зависимости. См. пример.
зачем тянуть еще один формат модулей в OpenSource?
Во-первых, помимо возможности догружать модули в рантаме у ymodules есть еще возможность дожидаться готовности модуля уже после того, как его код загружен. Во-вторых, ymodules позволяет гибко доопределять модули, что необходимо для работы с доопределением библиотечных блоков на уровне проекта.
Ну и здесь примерно та же история, что и со сборщиками: первый релиз ymodules в open source состоялся в апреле 2013, а systemjs — в июле 2013.
Есть ли в этом смысл после github.com/facebook/react/issues/3228?
Ответ на этот вопрос как раз и должен появиться в результате экспериментов.
Правильно ли я понимаю, что на поддержку альтернативных сборщиков просто не было пожеланий, поэтому их поддержка не входит в приоритет команды?
Пожелания были и именно потому команда постепенно движется в эту сторону. Но в условиях ограниченных ресурсов нет возможности реализовывать все пожелания, приходится их ранжировать по степени необходимости для пользователей.
Т.е. commonjs модули это что-то плохое?
Нет, конечно. И они благополучно используются там, где их возможностей хватает. В частности все БЭМ-инструменты используют именно commonjs-модули.
сейчас технологии для сборки bundle, bemhtml, bemjson жестко связаны со сборщиком enb? и нет отдельной технологии, которую можно было бы адаптировать под любой сборщик?
Да, все так. Но как я и писал выше, мы думаем над тем, как позволить собирать эти технологии с помощью других сборщиков. Прототип доступен по ссылке в отчете с хакатона.
Проект де-факто мертвый. Это было экспериментом по пробе реакта и насколько я знаю он был сразу же заброшен и дальше не развивается.
В текущей реализации — да. Но эксперименты на этом не прекратились. Сейчас dfilatov, veged и Вова Варанкин думают над развитием этой идеи.
ты можешь использовать все возможности Javascript, а в BEMHTML не можешь.
Это не так, BEMHTML (и BH) — это все тот же старый добрый JavaScript.
Недавно sbmaxx запилил песочницу, где можно проверить, как это работает в браузере: rozhdestvenskiy.ru/dev/bemhtml/
Когда это движение дойдет до продакшна и до уровня официальных библиотек Лего
Пользователи официальных библиотек Лего должны быть в курсе, как донести свои пожелания. И не секрет, что приоритеты команды БЭМ формируются именно на основе фидбека ;)
Сейчас насколько я знаю большинство БЭМ-библиотек завязано на формат модулей ymodules, что делает их сразу же несовместимыми ни с commonjs, ни с amd из коробки
Да, из коробки модули несовместимы. Но странно использовать что-то, что по по определению не решает наши задачи, только потому, что кто-то успел привыкнуть к плохому )
Каждой задаче свой инструмент.
Разве не удобнее, когда для задачи сборки любой технологии компонента используется один инструмент по одним правилам?
когда БЭМ-стек будет изоморфным из коробки и уметь быстро рендерить на клиенте с использованием Virtual DOM без лишних прослоек
Это два разных вопроса. Ответ на первый — создавать изоморфные проекты на БЭМ из коробки можно было всегда. Использовать текущие шаблоны с Virtual DOM as is нельзя. Но эксперименты про это тоже делаются: github.com/dfilatov/bem-components-react
я вижу свой формат описания веб-страниц в виде BEMJSON, а не использование нативных конструкций языка
БЭМ создает дополнительный слой абстракции над конструкциями языка, позволяя описывать интерфейс в терминах компонентов (блоков). Но с точки зрения языка BEMJSON — это просто JS-объект. В чем тут принципиальное отличие от описания компонентов, скажем, в Реакте?
1. нужен сборщик для проекта — собирать картинки, css, browserify, вот вам enb, bem-tools вместо gulp, grunt.
Ирония в том, что первый коммит в bem-tools датируется январем 2010, а первый релиз случился в октябре 2010, тогда как первый коммит в grunt — в сентябре 2011, gulp — июль 2013.
2. нужна модульная система — конечно, вот вам ymodules вместо commonjs, es6 модулей и systemjs.
О том, почему нас не устроила ни одна из существующих модульных систем, здесь писал dfilatov: habrahabr.ru/post/213627/
Если вы знаете open source аналоги «богаче по фичам», поделитесь, пожалуйста.
Важно понимать, что если по каким-то причинам ymodules не подходит, БЭМ-инструменты вполне могут собрать проект с любой другой модульной системой. И наоборот — если по каким-то причинам не подходят инструменты, можно использовать ymodules без всякой связи с БЭМ вообще. На самом деле это справедливо практически для каждого составляющего стека.
3. нужен шаблонизатор — bh, bemtree, тысячи их в разных вариациях.
Или любой другой на ваш выбор, благо в том числе на Хабре хватает статей от ребят не из Яндекса, которые использовали реализацию яндексовых инструментов вместе с собственными шаблонами на PHP и про прочие вариации на тему. В идеале, конечно, чтобы шаблонизатор был декларативный. Это позволяет применять те же подходы, которые отлично работают в CSS и для шаблонов. В том же Яндексе изначально БЭМ-шаблоны были на XSLT, TT2 и наверняка найдется еще какое-то количество менее распространенных вариантов, которые при этом вполне позволяют разрабатывать проекты на БЭМ.
До сих пор сборка БЭМ проекта основывается не на модульной системе, а на конвенциях, как располагать блоки, элементы и модификаторы на файловой системе с _ и __. Это жутко неудобно.
Тут на вкус и цвет, конечно. Но нельзя упускать важный момент — сборка по файловой системе позволяет полностью консистентно собирать любые технологии: от CSS до тестов и документации. Выразить эти же задачи в терминах модульной системы плюс-минус невозможно. По крайней мере готовых реализаций я не встречал.
Стек на данном этапе больше нацелен на рендеринг на сервере и добавление динамики ручками через клиентский js
Это ошибочное утверждение. Стек состоит из инструментов (они позволяет собрать любой проект), JS-фреймворка и JS-шаблонизаторов, которые работают на клиенте абсолютно с тем же результатом, что и на сервере.
Когда ты разворачиваешь свой первый БЭМ-проект у тебя в папке генерируется куча кода от шаблонизаторов, куча разных конфигов и ты просто не знаешь куда смотреть, что править, чтобы простой hello world завести, когда технология уже сгенерировала за тебя кучу кода.
control-group отвечает только за визуальное объединение других контролов (например, убирает скругление углов у двух стоящих рядом кнопок или у инпута и кнопки).
Поэтому реализация того, как именно меняется внешний вид конкретного блока с конкретной темой логично хранить внутри реализации его темы, а микс с control-group выступает удобным консистентным API для этой задачи.
Вот так декларируется кнопка: {
block : 'button',
text : 'Тема не указана'
}
А вот так радиогруппа на основе кнопок: {
block : 'radio-group',
mods : { type : 'button' },
name : 'Small',
options : [
{ val : 1, text : 'first' },
{ val : 2, text : 'second' }
]
}
Шаблоны на radio-group написаны таким образом, чтобы каждый элемент options превратился в полноценную кнопку, смиксованную с элементом radio-group.
Поэтому никакого копипаста нет, зато API каждого блока отвечает именно тем задачам, которые перед ним стоят.
описанная ситуация — фича :)
и, как мне кажется, достаточно логичная. результат будет получаться ожидаемым, если класть сущности на файловую систему консистентно на всех уровнях: либо везде разделяем, либо везде в один файл.
в процессе сборки происходит достаточно простая штука.
есть 2 сущности, задекларированные в БЭМ-дереве: блок и модификатор.
{
block: 'block',
mods: { mod: true }
}
на файловой системе на одном из уровней сущности описаны в отдельных файлах, на другом — в одном:
common/
block/
block.css
_mod/
block_mod.css
desktop/
block/
block.css
сборщик на основе дерева строит граф зависимостей, представляющий из себя массив. зависимости попадают туда строго в том порядке, в котором они встречаются в БЭМ-дереве:
далее при сборке конкретной технологии (в нашем примере — CSS), сборщик обходит все задекларированные уровни и пушит в массив пути к каждому найденному файлу.
соответственно, для первого элемента массива найдутся ['common/block/block.css', 'desktop/block/block.css'], затем перейдет к модификатору и допушит туда 'common/block/block_mod.css'.
затем для технологии CSS этот массив просто мапится в импорты.
На первом DOM-узле 42 класса (да-да, modernizr же), на body — айдишник и еще 3 класса (конечно, это все WordPress). Cтраница делает 25 запросов за JS-файлами.
Бедные разработчики из больших бюрократизированных компаний, конечно, не могут себе позволить таких простых человеческих радостей ;)
Но вот БЭМ вполне себе используют ребята-фрилансеры. Ну или вот немного результатов из англоязычного мира.
2. Блоки могут иметь зависимости, только эти зависимости должны быть явные. Чтобы при необходимости повторно использовать блок, его перенос на другой проект автоматически доставлял все зависимости. См. пример.
Во-первых, помимо возможности догружать модули в рантаме у ymodules есть еще возможность дожидаться готовности модуля уже после того, как его код загружен. Во-вторых, ymodules позволяет гибко доопределять модули, что необходимо для работы с доопределением библиотечных блоков на уровне проекта.
Ну и здесь примерно та же история, что и со сборщиками: первый релиз ymodules в open source состоялся в апреле 2013, а systemjs — в июле 2013.
Ответ на этот вопрос как раз и должен появиться в результате экспериментов.
Пожелания были и именно потому команда постепенно движется в эту сторону. Но в условиях ограниченных ресурсов нет возможности реализовывать все пожелания, приходится их ранжировать по степени необходимости для пользователей.
Нет, конечно. И они благополучно используются там, где их возможностей хватает. В частности все БЭМ-инструменты используют именно commonjs-модули.
Да, все так. Но как я и писал выше, мы думаем над тем, как позволить собирать эти технологии с помощью других сборщиков. Прототип доступен по ссылке в отчете с хакатона.
В текущей реализации — да. Но эксперименты на этом не прекратились. Сейчас dfilatov, veged и Вова Варанкин думают над развитием этой идеи.
Это не так, BEMHTML (и BH) — это все тот же старый добрый JavaScript.
Недавно sbmaxx запилил песочницу, где можно проверить, как это работает в браузере: rozhdestvenskiy.ru/dev/bemhtml/
Пользователи официальных библиотек Лего должны быть в курсе, как донести свои пожелания. И не секрет, что приоритеты команды БЭМ формируются именно на основе фидбека ;)
Да, из коробки модули несовместимы. Но странно использовать что-то, что по по определению не решает наши задачи, только потому, что кто-то успел привыкнуть к плохому )
Разве не удобнее, когда для задачи сборки любой технологии компонента используется один инструмент по одним правилам?
Это два разных вопроса. Ответ на первый — создавать изоморфные проекты на БЭМ из коробки можно было всегда. Использовать текущие шаблоны с Virtual DOM as is нельзя. Но эксперименты про это тоже делаются: github.com/dfilatov/bem-components-react
БЭМ создает дополнительный слой абстракции над конструкциями языка, позволяя описывать интерфейс в терминах компонентов (блоков). Но с точки зрения языка BEMJSON — это просто JS-объект. В чем тут принципиальное отличие от описания компонентов, скажем, в Реакте?
Ирония в том, что первый коммит в bem-tools датируется январем 2010, а первый релиз случился в октябре 2010, тогда как первый коммит в grunt — в сентябре 2011, gulp — июль 2013.
Однако есть движение в сторону поддержки популярных сборщиков. См., например, ru.bem.info/blog/first-bem-build/
О том, почему нас не устроила ни одна из существующих модульных систем, здесь писал dfilatov: habrahabr.ru/post/213627/
Если вы знаете open source аналоги «богаче по фичам», поделитесь, пожалуйста.
Важно понимать, что если по каким-то причинам ymodules не подходит, БЭМ-инструменты вполне могут собрать проект с любой другой модульной системой. И наоборот — если по каким-то причинам не подходят инструменты, можно использовать ymodules без всякой связи с БЭМ вообще. На самом деле это справедливо практически для каждого составляющего стека.
Или любой другой на ваш выбор, благо в том числе на Хабре хватает статей от ребят не из Яндекса, которые использовали реализацию яндексовых инструментов вместе с собственными шаблонами на PHP и про прочие вариации на тему. В идеале, конечно, чтобы шаблонизатор был декларативный. Это позволяет применять те же подходы, которые отлично работают в CSS и для шаблонов. В том же Яндексе изначально БЭМ-шаблоны были на XSLT, TT2 и наверняка найдется еще какое-то количество менее распространенных вариантов, которые при этом вполне позволяют разрабатывать проекты на БЭМ.
Тут на вкус и цвет, конечно. Но нельзя упускать важный момент — сборка по файловой системе позволяет полностью консистентно собирать любые технологии: от CSS до тестов и документации. Выразить эти же задачи в терминах модульной системы плюс-минус невозможно. По крайней мере готовых реализаций я не встречал.
Это ошибочное утверждение. Стек состоит из инструментов (они позволяет собрать любой проект), JS-фреймворка и JS-шаблонизаторов, которые работают на клиенте абсолютно с тем же результатом, что и на сервере.
Вот это действительно так. Но все планомерно становится лучше: github.com/bem/project-stub/pull/96 ;)
А вот, например, в руководстве для разработчиков Web Fundamentals в разделе про производительность уже непосредственно коллеги из Гугла сами рекомендуют методологию: developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations#use-block-element-modifier
Поэтому реализация того, как именно меняется внешний вид конкретного блока с конкретной темой логично хранить внутри реализации его темы, а микс с control-group выступает удобным консистентным API для этой задачи.
{ block : 'button', text : 'Тема не указана' }
А вот так радиогруппа на основе кнопок:
{ block : 'radio-group', mods : { type : 'button' }, name : 'Small', options : [ { val : 1, text : 'first' }, { val : 2, text : 'second' } ] }
Шаблоны на radio-group написаны таким образом, чтобы каждый элемент options превратился в полноценную кнопку, смиксованную с элементом radio-group.
Поэтому никакого копипаста нет, зато API каждого блока отвечает именно тем задачам, которые перед ним стоят.
и, как мне кажется, достаточно логичная. результат будет получаться ожидаемым, если класть сущности на файловую систему консистентно на всех уровнях: либо везде разделяем, либо везде в один файл.
в процессе сборки происходит достаточно простая штука.
есть 2 сущности, задекларированные в БЭМ-дереве: блок и модификатор.
на файловой системе на одном из уровней сущности описаны в отдельных файлах, на другом — в одном:
common/ block/ block.css _mod/ block_mod.css desktop/ block/ block.css
сборщик на основе дерева строит граф зависимостей, представляющий из себя массив. зависимости попадают туда строго в том порядке, в котором они встречаются в БЭМ-дереве:
далее при сборке конкретной технологии (в нашем примере — CSS), сборщик обходит все задекларированные уровни и пушит в массив пути к каждому найденному файлу.
соответственно, для первого элемента массива найдутся
['common/block/block.css', 'desktop/block/block.css']
, затем перейдет к модификатору и допушит туда'common/block/block_mod.css'
.затем для технологии CSS этот массив просто мапится в импорты.