Леша @zxqfox, а следом и Коля @gruzzilkin интересуются, как начать разрабатывать свою БЭМ-библиотеку.
Ответ на этот вопрос может быть разным в зависимости от того, что вы вкладываете в этот термин.
Я попробовал рассмотреть создание библиотеки от простого к сложному, постепенно добавляя фичи.
А именно:
- Самый простой вариант, когда библиотекой является просто папка с блоками
- Разделение библиотеки по уровням переопределения
- Вид библиотеки после добавления документации
- Пример файловой структуры с тестами и линтерами
- Оформление своей библиотеки
А в конце поделился рецептом, как быстро получить себе всю инфраструктуру, которую мы используем для bem-библиотек. TL;DR
Любая папка с блоками — библиотека
В самом простом случае любая папка, в которой лежат файлы с реализацией блоков, может служить библиотекой.
Например, вот так может выглядеть полезная библиотека с блоком clearfix
:
my-library/
clearfix/
clearfix.css
Конечно, просто копировать ее из проекта в проект не очень удобно. Поэтому стоит воспользоваться любимой системой контроля версий и опубликовать библиотеку, скажем, на github.
На проекты ее удобно будет доставлять через bower
.
Получим:
my-library/
.git/
bower.json
clearfix/
clearfix.css
Теперь представим, что у нас в библиотеке появился блок ua
, который будет помогать с feature detection.
Хозяйке на заметку: не стоит бояться класть в библиотеку блоки, которые не будут востребованы во всех ваших проектах, ведь сборщик соберет только нужные вам блоки в каждом конкретном проекте.
Нужный блок можно реализовать несколькими способами.
Самый простой — поступить по аналогии с clearfix
и положить реализацию в соответствующую папку:
my-library/
.git/
bower.json
clearfix/
clearfix.css
ua/
ua.js
Однако, очевидно, что для разных платформ будут нужны разные данные. Например, на мобильном устройстве нас интересует ориентация устройства, для десктопа это знание не нужно. Тогда как часть информации о user agent будет нужна на всех платформах.
Как можно избежать дублирования кода и при этом не тянуть лишний код туда, где он заведомо не нужен?
Разделение блоков по уровням переопределения
Можно воспользоваться концепцией уровней переопределения. Это может выглядеть так: один блок представляем «слоями», а каждый новый слой до- переопределяет либо какую-то часть визуальных свойств, либо доопределяет поведение блока.
В результате структура библиотеки может выглядеть так:
my-library/
.git/
bower.json
common.blocks/
clearfix/
clearfix.css
ua/
ua.js
desktop.blocks/
ua/
ua.js
touch.blocks/
ua/
ua.js
Мы видим, что блок ua
оказался разделен на общую между всеми платформами часть (она попала в common.blocks
) и специфику, необходимую в конкретном окружении.
Как это работает?
Сборщик знает, какие уровни переопределения и в каком порядке мы хотим собирать для нашего проекта. Поэтому код из последующих «слоев» сможет перекрыть предыдущий.
Нагляднее всего это можно продемонстрировать на примере с CSS:
/* my-library/common.blocks/b1 */
.b1 {
width: 150px;
height: 50px;
}
/* my-library/desktop.blocks/b1 */
.b1 {
font-size: 24px;
height: 80px;
}
Здесь некий блок b1
представлен на двух уровнях: common.blocks
и desktop.blocks
. При этом на общем уровне ему задаются высота и ширина, на уровне desktop.blocks
добавляется знание про размер шрифта, а высота переопределяется новым значением.
Если писать код определенным образом, то аналогичного эффекта можно достичь и для остальных технологий, в т.ч. JavaScript и шаблонов. Например, мы используем i-bem.js и BEMHTML(https://ru.bem.info/technology/bemhtml/), чтобы упростить себе эту задачу.
Документируем блоки библиотеки
Когда в библиотеке окажется много блоков, потребуется какое-то описание для всей библиотеки в целом. А если блоки в ней будут достаточно сложными, то хорошо бы иметь описание каждого блока отдельно. Кроме того, нужно где-то фиксировать информацию об изменениях в каждой версии библиотек.
Получим что-то вроде:
my-library/
.git/
bower.json
common.blocks/
clearfix/
clearfix.css
clearfix.md
ua/
ua.js
ua.md
desktop.blocks/
ua/
ua.js
ua.md
touch.blocks/
ua/
ua.js
ua.md
README.md
CHANGELOG.md
Тестируем и следим за кодстайлом
Если работу над библиотекой ведут сразу несколько разработчиков, то нужно следить за кодстайлом, для блоков писать тесты, которые бы запускались на прекоммит-хук и в CI:
my-library/
.csscomb.json
.git/
.githooks/
pre-commit
.jscsrc
.jshint-groups.js
.travis.yml
bower.json
common.blocks/
clearfix/
clearfix.css
clearfix.md
ua/
ua.js
ua.md
ua.spec.js
desktop.blocks/
ua/
ua.js
ua.md
ua.spec.js
package.json # здесь задекларируем модули для сборки и тестирования
touch.blocks/
ua/
ua.js
ua.md
ua.spec.js
README.md
CHANGELOG.md
Как мы оформляем bem-библиотеки
В какой-то момент для наглядного примера работы каждого блока во всей его вариативности может потребоваться демо-страница.
Я не случайно оставил за скобками всю историю про сборку таких примеров, тестов и документации по всем уровням переопределения.
Также не стоит ограничиваться unit-тестами для JavaScript, проверки требуют и шаблоны, и верстка. А для всех видов тестов в свою очередь потребуется анализ покрытия (coverage).
Для решения всех этих задач в БЭМ-платформе существуют готовые инструменты. Их достаточно много, и каждый требует какого-то времени, чтобы с ним разобраться.
Поэтому самый простой способ быстро начать разрабатывать библиотеку, а не заниматься налаживанием необходимой инфраструктуры вокруг — взять готовое.
TL;DR
Я бы предложил поступить примерно так:
git clone https://github.com/bem/bem-components.git my-library
cd $_
rm -rf *.blocks/* design
Теперь можно пользоваться ;)
Конечно, это не самый элегантный способ, но зато быстро и работает.
Мы думаем над тем, как облегчить получение готовой инфраструктуры для своей библиотеки. Решение видится в пакете-обертке над всем необходимым с удобным и лаконичным API.
Рассказывать о ней планируем в нашем блоге. Stay BEMed!
Крутяк! ;-) Надо поскорее сделать элегантный способ, а то только начал и уже устал велисопеды писать и обновления синхронизировать.
Ведь есть же уже
magic-platform
, почти есть пачка конфигов для кодстайла, еще нужны какие-то оберточки для всяких gemini, чтобы работало. Собрать же только осталось, не?Cборщик сайтов с документацией https://github.com/bem/bem-site-engine не упомянут по каким то особым причинам?
Вы не думали что пора начать такие гайды писать на английском, раз BEM интернациональный?
И куда писать, если не работает кнопка "Репорт багов"?
@operatino https://github.com/bem/bem-forum/issues/
Спасибо за напоминание про доки.
@operatino Кнопка работает, тебя видимо ввело в заблуждение, что ничего явно не произошло по клику на кнопке. Сейчас, если ты внимательно посмотришь, по клику на репорт багов, мы просто фильтруем посты с такой меткой, с тем смыслом, что ты увидешь подобный баг и просто отпишешься в комментариях. Но я согласен, что этот вариант оказался не лучшим и мы скоро будем сразу открывать форму, чтоб добавить сообщение о баге, что должно стать достаточно явным.
@zxqfox, у @andrewblond есть мысли, как распилить текущий конфиг сборки на декларативную часть, описывающую библиотеку и императивный конфиг, который будет отвечать на вопрос, как такую библиотеку собрать. должно стать гораздо лаконичнее и понятнее. но хочется учесть все многообразие вариантов использования. поэтому требуется время.
@operatino на самом деле там достаточно много инструментария не упомянуто явно, о чем я и говорю в посте. иначе пост стал бы раз в 20 длиннее. но конкретно
bem-site-engine
не упомянут еще и потому, что это внешняя по отношению к библиотекам сущность: в конфигеbem-site-engine
описываются все нужные библиотеки, а на выходе получается общий сайт типа https://ru.bem.info/libs/, при этом библиотеки ничего не знают о том, что их документация, примеры блоков и JSDOC собираются на каком-то сайте.@operatino по поводу переводов ты, конечно, прав. мы очень стараемся переводить как можно больше. но пока, к сожелению, не все успеваем (
@tadatuta Про переводы всегда будут тыкать пальцем, но лучше писать на том языке, на котором более удобно, а переводить в рабочем порядке или силами общества. Тут хочется сказать, что было бы удобно знать, что именно не переведено, чтобы не распылятся на все и иметь какие-то приоритеты по переводам, может быть голосовалками, или еще как-то.
А про модульную сборку — я думал, что понимаю что происходит, но после общения пару недель назад я опять потерялся, мб потому что праздники. В общем, целостной картины происходящего по сборке я уже не вижу и это удручает, хочется понимать, куда можно приложить руку и подтолкнуть этот процесс. Проблема, впрочем, тебе известная, и я знаю (хотя, скорее верю), что ты её держишь под контролем ;-)
upd: Добавлю, что текущие инструменты очень сложно интегрировать в нашу инфраструктуру и поэтому модульная сборка очень актуальная для наших текущих нужд. Т.е. мы готовы вложится в это, знать бы куда.
@zxqfox согласен, особенно про сборку. Прочитал отчет Хакатон по БЭМ: проект «Сборка», без лопаты понять что именно заставляет говорить: "Каждый из них не был идеальным и не подходил для использования в реальных проектах.". Стоит отметить результат https://github.com/belyanskii/gulp-bem-stub радует и хочется понять дальнейший план, что бы копать в нужную сторону и сообща.
@innabelaya Инна, вот Леша просит приоритезированный список непереведенного. Давай придумаем, как его держать снаружи? Можно, например, завести issue со списком в https://github.com/bem/bem-method/ или еще как-нибудь.
@zxqfox @ilyar, в комментарии призывается @andrewblond (впрочем, вы и без меня знаете кого пинать по этому поводу ;))
@zxqfox, я наоборот считаю, что надо сразу все писать на английском. Технические тексты писать легко, а постоянно переврдить это как замкнутый круг. К тому же, если сначала все на русском появляется, интернациональное сообщество не может полноценно включиться, ибо есть явный барьер.
@tadatuta, просто направить
bem-site-engine
на папку с блоками нельзя?@operatino
bem-site-engine
решает задачу построения общего сайта библиотек, где отражены все версии каждой библиотеки. Просто папка с блоками — это частный случай. При этом важно понимать, что каждая библиотека может быть реализована ОЧЕНЬ по-разному (разная структура папок, разные технологии реализации блоков, разные форматы JSDOC, ожидать разные версии разных сборщиков). Поэтому знание про свою сборку инкапсулирует каждая версия каждой конкретной библиотеки (в процессе разработки тебе нужно мочь поднять dev-сервер и собирать примеры, документацию и тесты в рамках разрабатываемой версии), далее вступает bem-data-source, который на вход получает адрес библиотеки на gh и, при необходимости, какие-то дополнительные подсказки, как ее собирать и отдает единый формат, с которым умеет работатьbem-site-engine
. При этом есть возможность поднять эту инфраструктуру в CI, чтобы создание PR или установка тега автоматически вызывало сборку и добавление соответствующей версии на сайте библиотек. Из важных фич, которые приходится учитывать в процессе, например, рерайт ссылок: все ссылки при разработке остаются относительными и правильно работают локально на файловой системе или на гитхабе.bem-site-engine
знает, какие именно версии каких именно библиотек с какими именно уровнями переопределения были собраны и переписывает доступные на сайте ссылки с учетом роутинга сайта, а все, что на сайт не попало, продолжает уводить на соответствующие источники. Ну и еще целая куча подобных нюансов.@andrewblond Андрей, возможно сделать обзор состояния модульной сборки? Предлагаю создать тему, где обозначить планируемые пакеты их предполагаемую функциональность, как то отобразить идеальную картину будущего и текущие проблемы.
@tadatuta Владимир, расскажи про bem-mv.
@operatino Если у сообщества есть желание — оно и без наших текстов включится. Причинно следственная связь обратная. Из желания следуют и тексты, и переводы. Наоборот не бывает. А если писать исключительно на английском — подавляющее большинство не осилят писать крупные тексты. В итоге будет дефицит в информации. Имхо, лучше много на русском и мало на английском, чем мало на обоих.
@ilyar
bem-mv
— это прототип прототипа. Опубликованный код будет полностью выкинут в пользу реализации нескольких инструментов на основе COA:Прототипы всего, кроме bem create, у меня уже есть, но все еще не в том состоянии, чтобы публиковать на github.
@zxqfox Я понимаю твою позицию. Но по моему, следуя такой стратегии вы сильно ограничены русскоязычной аудиторией, и выйти на инт рынок, где всем все на блюдечке подают так не получиться.
К тому же, вы не только себя ограничиваете, но и мотивируете ру сообщество дальше не учить английский язык, и оставаться закрытым в себе.
Я бы согласился, если бы мы на фламанском общались и статьи писали. :-)