Здравствуй, <%= habrauser %>!
Я очень люблю фреймворк Ruby On Rails, он правда очень и очень крут. Он позволяет в кратчайшие сроки реализовать твои замыслы. Раньше я много писал на нем, но сегодня я front-end разработчик. Когда я узнал о методологии БЭМ, я был в полном восторге, потому что так или иначе ты сам приходишь к чему-то подобному. Хорошо, когда дзен-процесс сокращается в разы. О том, что такое БЭМ можно прочитать тут и тут. Недавно прошедший BEMup окончательно расставил все на свои места. Мне были просто необходимы инструменты для работы с БЭМ в рамках проектов на Ruby on Rails. Конкретных решений не существовало, а bem-tools не подходит по вполне понятным причинам. Я решил написать bem-tools на Ruby.
Зачем?
Некогда многие высказывали мысль о том как использовать БЭМ в рельсах, но кроме того как правильно именовать классы в css, я ничего полезного не узнал. Тем более писать такие классы ручками совсем не хочется. Конкретных инструментов предложено не было. А БЭМ это не только css и яваскрипт. Мне хотелось иметь внутри рельс нечто подобное шаблонизатору BEMHTML. Чтобы его использовать можно было бы подключить в рельсы V8 и компилировать шаблоны. Но тогда от рельс мало чего остается и это далеко не Ruby way. Я привык писать шаблоны на HAML и использовать препроцессор SASS. Я очень не хотел, чтобы использование БЭМ в рельсах привносило бы серьезные трудности для понимания и заставляло разработчиков совершать непривычные для них действия. Кроме того в рельсах есть pipeline, который собирает и компилирует ассеты, значит пол работы уже сделано. После долгих размышлений сложились четкие требования к тому что необходимо иметь в виде инструментов:
- Одна директория с блоками для всех проектов на Ruby on Rails. В идеале — не только RoR.
- Рендеринг блоков и элементов во вьюхах.
- Удобное создание/удаление/просмотр блоков/элементов/модификаторов.
- Интеграция с pipeline.
- Максимальное сходство с bem-tools.
Как?
Создание/Удаление/Просмотр
Для того чтобы создавать/удалять/просматривать блоки я написал некоторое количество Thor задач. Еще мне показалось, что было бы полезно иметь возможность распределять блоки по группам. Не ручками, а из консоли, и рендерить потом блоки из нужной группы:
thor bem:create -b filter -G search
И теперь создавать блоки/элементы/модификаторы можно так, причем модификаторы могут быть как со значениями так и без:
thor bem:create -b test
thor bem:create -b test -e icon
thor bem:create -b test -m large
thor bem:create -b test -m color -v red
thor bem:create -b test -e icon -m file
thor bem:create -b test -e icon -m size -v small
thor bem:create -b test -e icon -m size -v small -T sass
Удаление происходит аналогично:
thor bem:remove -b test
...
Просмотр существующих блоков:
thor bem:list
thor bem:list -G search
thor bem:list -b test
...
Для себя я решил немного изменить файловую структуру блока. Я решил вынести элементы блока в директорию /elements, а модификаторы в /mods. Мне показалось это более удобным, чем держать все в одной директории. Вернуться назад можно в любой момент. Сейчас директория с блоками автоматически создается в корне rails приложения и выглядит примерно так:
- block_name
- elements
- __element_name
- __element_name.html.haml
- __element_name.css.sass
- __element_name.coffee
- __element_name.md
- __element_name
- mods
- _mod_name
- _mod_name.css.sass
- _mod_name.coffee
- _mod_name.md
- _mod_name
- block_name.html.haml
- block_name.css.sass
- block_name.coffee
- block_name.md
- elements
- group_name
- block_name
Так же совсем неплохо иметь описание к каждому блоку/элементу/модификатору, причем в привычном markdown. Независимо от технологий, которые использую лично я, вы можете использовать свои, те, к которым давно привыкли. Для этого я создал initializer, в котором определил все настройки BEM. Там вы можете все отредактировать для себя, в том числе префиксы для блоков/элементов/модификаторов.
Рендеринг
Благо в рельсах есть хелперы. Благодаря им и хэшам, рендерить блоки в HAML вьюхах можно так:
= b "test", mods: {color: "red"}, content: [{ elem: "icon", elemMods: {size: "small"} }]
= b "test", group: "name", mods: {color: "red"}, content: []
На мой взгляд смахивает на BEMHTML и это не может не радовать. Для технологий haml, sass, coffee, md я создал шаблоны. После создания блока, шаблон haml(например) станет реализацией блока на технологии haml. По образу и подобию можно создать шаблоны для всех интересующих вас технологий.
А ассеты?
С ассетами решается все крайне просто. Можно добавить любую директорию в скоуп, где будут искаться файлы стилей и скриптов. При создании блока/элемента/модификатора в файлы application.css.sass и application.js добавляются строки с определением, например:
//= require test/elements/__field/__field.coffee
Остальную работу делает Sprockets. Чтобы все работало хорошо, крайне рекомендуется не писать стилей и скриптов в файлах application.css.sass и application.js. Используйте их как конфиги, только для списка того, что ипользуется. Это удобно и без БЭМ. Такой подход позволяет забыть об объявлении используемых блоков/элементов/модификторов впринципе. Все происходит автоматически. Про deps.js можно забыть. Попробуйте!
Продакшн
Попробовать использовать данный набор инструментов можно уже сейчас. Я оформил их в виде гема, который вы можете установить себе в проект и использовать БЭМ уже сегодня. Ссылка на гитхаб: bem-on-rails.
Планы
- Рендеринг блоков в блоке. Пока только элементы и строки.
- Кастомные теги для блоков и элементов. Пока надо указывать в шаблоне блока/элемента.
- Добавление атрибутов в блоки и элементы при рендеринге.
- Добавление кастомных классов при рендеринге.
- Флаги bem и js.
- Подмешивание блоков и элементов.
- Модификаторы с изменением структуры блока. Пока только стиль и яваскрипт.
- Bem из командной строки. Запуск тасков через Thor имеет свои недостатки.
Профит
Имея директорию с блоками в качестве гит репозитория вы можете подключать свои блоки в любые проекты. Реализация блока/элемента/модификатора может быть как на привычных для рельс технологиях так и на привычных для PHP. Один и тот же репозиторий блоков вы можете использовать как во всех своих проектах на Ruby on Rails (чего бы мне очень хотелось), так и в любых других проектах предполагающих использование БЭМ. Данный набор инструментов призван расширить сферу влияния БЭМ на такой замечательный фреймворк как Ruby on Rails.
Буду рад любым замечаниям и любой помощи. Спасибо за внимание!
Stay BEMed!
Автор: verybigman