Pull to refresh

Comments 9

Уже многие в БЭМ сообществе отходят от написания отдельного файла под модификатор и пишут модификатор прямо в файле с блоком,

некоторые принципы диктуются особенностями ихнего (BEM) инструментария. тут основной прикол в тамошнем сборщике, который работает не с BEM-сущностями как таковыми, а с файлами. именно раскидывание кода по файлам дает возможность тулзам собирать результат в правильном порядке (с учетом уровней переопределения, порядка применения модификаторов, явных зависимостей и прочей хиромантии). поэтому файлы и четкое следование правилам их именования вообще-то являются очень важной частью разработки. когда вы складываете все в один файл, результат сборки становится значительно менее предсказуемым.
Ну да, в бемтулсах это всё имеет значение. Тем не менее, команда bem create создаёт структуру файлов, полностью идентичную той, что создают бемтулсы. Так что, если не хотите использовать эти амперсанды, можно делать всё по правилам БЭМа.

Насчёт переопределения и порядка — для этого я как раз добавил возможность вставки css ассетса прямо в манифест через опцию -i, чтобы верстальщик смог контролировать переопределение и порядок таким образом.
И ещё — конечно можно использовать разные манифесты и не складывать все стили в один файл. Например, для разных лэйаутов можно использовать разные манифесты. А если вы хотите использовать свой манифест для каждого контроллера(что правда убивает преимущества turbolinks), то нужно будет прописать пару строк и не забыдь добавить в прекомпиляцию соответствующие манифесты. В последней версии рельс это добавляется в файле config/initializers/assets.rb.
а можно какой-нибудь пример, который бы проиллюстрировал ситуацию, когда результат сборки «все в одном файле» окажется непредсказуемым?
например, когда у нас есть библиотека (common), мы пытаемся переопределять что-то на своем уровне (desktop):

common/
  block/
   block.css
   block_mod.css

desktop/
  block/
    block.css


предположим, что я положил все свои переопределения в один desktop/block/block.css:

.block {}
.block_mod {}


в сборке у меня часто получалась вот такая прелесть:

@import url(common/block/block.css);
@import url(desktop/block/block.css);
@import url(common/block/block_mod.css);


т.е. common/block/block_mod.css перекрывает все старания desktop/block/block.css. если же модификаторы класть в отдельный файл, тогда эффект в сборке получается правильным:

@import url(common/block/block.css);
@import url(desktop/block/block.css);
@import url(common/block/block_mod.css);
@import url(desktop/block/block_mod.css);


в прочем, не до конца уверен, фича это сборщика, или какая-то локальная проблема в проектных конфигах. но есть ощущение, что все же фича. :)
описанная ситуация — фича :)
и, как мне кажется, достаточно логичная. результат будет получаться ожидаемым, если класть сущности на файловую систему консистентно на всех уровнях: либо везде разделяем, либо везде в один файл.

в процессе сборки происходит достаточно простая штука.

есть 2 сущности, задекларированные в БЭМ-дереве: блок и модификатор.
{
    block: 'block',
    mods: { mod: true }
}


на файловой системе на одном из уровней сущности описаны в отдельных файлах, на другом — в одном:
common/ block/ block.css _mod/ block_mod.css desktop/ block/ block.css

сборщик на основе дерева строит граф зависимостей, представляющий из себя массив. зависимости попадают туда строго в том порядке, в котором они встречаются в БЭМ-дереве:
exports.deps = [
    {
        "block": "block"
    },
    {
        "block": "block",
        "mod": "mod"
    }
];


далее при сборке конкретной технологии (в нашем примере — CSS), сборщик обходит все задекларированные уровни и пушит в массив пути к каждому найденному файлу.
соответственно, для первого элемента массива найдутся ['common/block/block.css', 'desktop/block/block.css'], затем перейдет к модификатору и допушит туда 'common/block/block_mod.css'.

затем для технологии CSS этот массив просто мапится в импорты.
и, как мне кажется, достаточно логичная. результат будет получаться ожидаемым, если класть сущности на файловую систему консистентно на всех уровнях: либо везде разделяем, либо везде в один файл.

такое возможно, лишь когда весь код находится под контролем одной команды (крайность какая-то?). в общем же случае, надежнее придерживаться общих соглашений.
А ещё там есть отличная фича, которая как раз подходит для БЭМ — это использование амперсанда.


В LESS также:

.nav {
  background: white;
  &__link {
    font-size: 1.2em;
    &_active {
      color: blue;
    }
  }
}


Превратится в

.nav {
  background: white;
}
.nav__link {
  font-size: 1.2em;
}
.nav__link_active {
  color: blue;
}
Да, действительно, есть такое. Спасибо, добавил ссылку на документацию и ваш комментарий в статью.
Sign up to leave a comment.

Articles