Pull to refresh

БЭМ on Rails

JavaScript *Ruby on Rails *HTML *


Здравствуй, <%= habrauser %>!

Я очень люблю фреймворк Ruby On Rails, он правда очень и очень крут. Он позволяет в кратчайшие сроки реализовать твои замыслы. Раньше я много писал на нем, но сегодня я front-end разработчик. Когда я узнал о методологии БЭМ, я был в полном восторге, потому что так или иначе ты сам приходишь к чему-то подобному. Хорошо, когда дзен-процесс сокращается в разы. О том, что такое БЭМ можно прочитать тут и тут. Недавно прошедший BEMup окончательно расставил все на свои места. Мне были просто необходимы инструменты для работы с БЭМ в рамках проектов на Ruby on Rails. Конкретных решений не существовало, а bem-tools не подходит по вполне понятным причинам, описанным ниже. Я решил написать bem-tools на Ruby.

Зачем?


Некогда многие высказывали мысль о том как использовать БЭМ в рельсах, но кроме того как правильно именовать классы в css, я ничего полезного не узнал. Тем более писать такие классы ручками совсем не хочется. Конкретных инструментов предложено не было. А БЭМ это не только css и яваскрипт. Мне хотелось иметь внутри рельс нечто подобное шаблонизатору BEMHTML. Чтобы его использовать можно было бы подключить в рельсы V8 и компилировать шаблоны. Но тогда от рельс мало чего остается и это далеко не Ruby way. Я привык писать шаблоны на HAML и использовать препроцессор SASS. Я очень не хотел, чтобы использование БЭМ в рельсах привносило бы серьезные трудности для понимания и заставляло разработчиков совершать непривычные для них действия. Кроме того в рельсах есть pipeline, который собирает и компилирует ассеты, значит пол работы уже сделано. После долгих размышлений сложились четкие требования к тому что необходимо иметь в виде инструментов:

  1. Одна директория с блоками для всех проектов на Ruby on Rails. В идеале — не только RoR.
  2. Рендеринг блоков и элементов во вьюхах.
  3. Удобное создание/удаление/просмотр блоков/элементов/модификаторов.
  4. Интеграция с pipeline.
  5. Максимальное сходство с bem-tools.


Почему не bem-tools

Во-первых, используя в rails приложении bem-tools вы получаете некую штуку сбоку, которая никак вам не подчиняется, вы же не яваскрипт разработчик? Во-вторых, bem-tools тянет за собой еще добрую кучку инструментов через npm, что вам не подвластно. А у рельсового разработчика есть bundler и Gemfile. Зачем мне нужны еще пакетные менеджеры? Используя bundler я всегда могу создавать гемсеты для разных проектов привычным для себя способом. Все зависимости идут вместе с проектом в привычном виде. Ничего дополнительно не нужно. Я устанавливаю гем и у меня все работатет. Никаких дополнительных директорий в корне проекта, кроме самой библиотеки блоков. В-третьих, процесс сборки в рельсах несколько иной, он уже реализован и менять его не хотелось бы. Можно было бы использовать bem-tools только для работы с файловой системой, но это не отменило бы написания самостоятельного кода для рендеринга. Кроме того не получилось бы использовать для паршелов шаблоны. Об описанных инструментах вполне можно думать как о способе организации паршелов в rails приложении.

Как?


Создание/Удаление/Просмотр

Для того чтобы создавать/удалять/просматривать блоки я написал некоторое количество 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 приложения и выглядит примерно так:
Файловая структура
blocks
  • block_name
    • elements
      • __element_name
        • __element_name.html.haml
        • __element_name.css.sass
        • __element_name.coffee
        • __element_name.md


    • mods
      • _mod_name
        • _mod_name.css.sass
        • _mod_name.coffee
        • _mod_name.md



    • block_name.html.haml
    • block_name.css.sass
    • block_name.coffee
    • block_name.md

  • group_name
    • block_name



Так же совсем неплохо иметь описание к каждому блоку/элементу/модификатору, причем в привычном markdown. Независимо от технологий, которые использую лично я, вы можете использовать свои, те, к которым давно привыкли. Для этого я создал initializer, в котором определил все настройки BEM. Там вы можете все отредактировать для себя, в том числе префиксы для блоков/элементов/модификаторов.

Рендеринг

Благо в рельсах есть хелперы. Благодаря им и хэшам, рендерить блоки в HAML вьюхах можно так:
= b "test", mods: [{color: "red"}], content: [{ elem: "icon", elemMods: [{size: "small"}] }]

= b "test", mods: [{color: "red"}], content: [{ block: "yeah", content: ["Hello, BEM!"] }]

= b "test", group: "name", mods: [:large, {color: "red"}], content: [] 

= b "test", cls: "custom", attrs: {"data-toggle": "modal"}, content: [] 

= b "test", tag: "article", content: [] 

На мой взгляд смахивает на BEMHTML и это не может не радовать. Для технологий slim, 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.
Планы

  1. Флаги bem и js.
  2. Подмешивание блоков и элементов.
  3. Модификаторы с изменением структуры блока. Пока только стиль и яваскрипт.
  4. Bem из командной строки. Запуск тасков через Thor имеет свои недостатки.


Профит

Имея директорию с блоками в качестве гит репозитория вы можете подключать свои блоки в любые проекты. Реализация блока/элемента/модификатора может быть как на привычных для рельс технологиях так и на привычных для PHP. Один и тот же репозиторий блоков вы можете использовать как во всех своих проектах на Ruby on Rails (чего бы мне очень хотелось), так и в любых других проектах предполагающих использование БЭМ. Данный набор инструментов призван расширить сферу влияния БЭМ на такой замечательный фреймворк как Ruby on Rails.

Буду рад любым замечаниям и любой помощи. Спасибо за внимание!

Stay BEMed!
Tags:
Hubs:
Total votes 55: ↑45 and ↓10 +35
Views 14K
Comments 27
Comments Comments 27

Posts