bemhint-estree
v0.2.0
Published
acorn-based plugins for bemhint
Downloads
3
Readme
bemhint-estree
Плагины к bemhint для парсинга js и поиска недостающих депсов.
Что внутри
plugins/browser
— плагин для технологииjs
.plugins/templates
— плагин для технологийbh.js
иbemhtml.js
.
Как работает
Оба плагина используют хелпер, который умеет парсить js-файлы, и искать в AST объектные литералы, которые
похожи на BEMJSON (есть поля block
, elem
, mods
, elemMods
). Плагины, затем, проверяют наличие зависимостей от
найденных БЭМ-сущностей в deps.js
.
Когда мы пишем BEMJSON в шаблонах, мы, обычно, хотим передать его в applyCtx
или вернуть из дефолтной моды,
то есть хотим вместо текущего BEMJSON обработать какой-то другой. Чтобы для нового BEMJSON отработали шаблоны и на
клиент попали стили и javascript, нужно чтобы все БЭМ-сущности были указаны в shouldDeps или в mustDeps.
У блока могут быть опциональные зависимости, которые нужно подключать только если API блока используется определённым образом.
Например, если у блока button2
используется поле icon
, нужно дополнительно прописать зависимость от блока icon
.
Чтобы уменьшить вероятность ложных срабатываний в таких случаях, плагин игнорирует код находящийся внутри
условных конструкций (if
, ? :
, &&
, ||
).
// a.bemhtml.js
block('a').def()(function() {
return {
block: 'b',
mix: [{block: 'mixed', mods: {name: 'val'}, js: true}],
content: [
{elem: 'e'},
this.ctx.d && {elem: 'd'}
]
}
});
// a.deps.js
({
mustDeps: [
// Такая зависимость должна быть у всех блоков с bemhtml (до bem-xjst 4.0), плагин это не проверяет
{block: 'i-bem', elem: 'html'},
// Элемент d опциональный, находится за логическим оператором, плагином игнорируется
{block: 'b', elems: ['e']},
{block: 'mixed', mods: {name: 'val'}}
]
});
Когда BEMJSON встречается внутри клиентского js, это значит, обычно, что мы собираемся передать его шаблонизатору.
В этом случае справедливо всё что написано в предыдущем абзаце: нужно указать shouldDeps/mustDeps от всех сущностей из
BEMJSON, кроме опциональных. Кроме того, в клиентский js должны попасть шаблоны этих сущностей.
Для этого должны быть правильно прописаны depsByTech
: в зависимости по технологиям js
→bemhtml
нужно прописать все
блоки, кроме тех, которые переданы в поле mix
(они не участвуют в шаблонизации). Для защиты от ложных срабатываний,
кроме конструкций ветвления, плагин игнорирет findBlock*()
методы, BEM.create()
, BEM.HTML.decl()
,
BEM.HTML.build()
, первый аргумент BEM.DOM.decl()
.
// a.js
BEM.dom.decl({block: 'a'}, {
method: function() {
var c = this.findBlockInside({block: 'c'});
BEM.DOM.update(this.elem('e'), BEMHTML.apply({
block: 'b',
mix: {block: 'a', elem: 'e'},
content: [
{elem: 'e1'},
_buildOther(),
this.params.d ? {block: 'd'} : ''
]
}))
},
_buildOther: function() {
return [
{elem: 'e2'},
{block: 'f'}
],
}
});
// a.deps.js
([{
mustDeps: [
// Зависимость должна быть у всех блоков использующих BEM.DOM
{block: 'i-bem', elem: 'dom'}
],
shouldDeps: [
// Элемент используется внутри поля mix, depsByTech для него не нужны
{elem: 'e'},
// Плагин игнорирует не предупреждает про e2, т.к. не умеет прокидывать контекст блока в другой литерал
{block: 'b', elems: ['e1', 'e2']},
{block: 'f'}
// Блок d опциональный, находится за условным оператором, плагином игнорируется
]
}, {
// Для сущностей участвующих в шаблонизации прописываем depsByTech
tech: 'js',
shouldDeps: [
{tech: 'bemhtml', block: 'b', elems: ['e1', 'e2']},
{tech: 'bemhtml', block: 'f'}
]
}]);