Пример Добавление БЭМ-сущностей для задач вёрстки из руководства по BEMHTML выдает ошибку:
Error: Only literal or function is allowed in template's body
at Compiler.assert (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/node_modules/xjst/lib/xjst/compiler/base.js:180:9)
at Compiler.transformTemplates (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/node_modules/xjst/lib/xjst/compiler/base.js:648:8)
at Array.map (native)
at Compiler.translate (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/node_modules/xjst/lib/xjst/compiler/base.js:201:41)
at Object.translate (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/node_modules/xjst/lib/xjst/api.js:16:40)
at Compiler.translate (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/lib/bemhtml/compiler.js:121:35)
at Compiler.generate (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/lib/bemhtml/compiler.js:707:14)
at Object.generate (/vagrant/project-stub/node_modules/enb-bemxjst/node_modules/bem-xjst/lib/bemhtml/api.js:16:40)
at require.declare.process (/vagrant/project-stub/node_modules/enb-bemxjst/techs/bem-xjst.js:7:28)
at /vagrant/project-stub/node_modules/enb-bemxjst/node_modules/sibling/lib/runner.js:22:48
Гугление подсказало обернуть матчинг флага в анонимную функцию:
block('box').match(function() { return !this.ctx._processed; })
Не помогло.
Обернул вызов applyCtx:
block('box').match(function() { return !this.ctx._processed; }).content()(function() {
applyCtx({'ctx._processed':true}, {
elem: 'left-top',
content: {
elem: 'right-top',
content: {
elem: 'right-bottom',
content: {
elem: 'left-bottom',
content: applyNext()
}
}
}
});
})
Ошибка пропала, но html сгенерировался криво:
<div class="box">
<div class="box">text</div>
<div class="box__left-top">
<div class="box__right-top">
<div class="box__right-bottom">
<div class="box__left-bottom"></div>
</div>
</div>
</div>
</div>
Подскажите, как правильно делать такую банальную вещь?
applyCtxне нужно , обычно эта конструкция нужна когда тебе нужно сам блок обернуть во что, в неких враппер например или в другой блок и вызватьapplyCtxпо модеdef()Например:
Получим html:
В твоей задаче достаточно будет написать return куска bemjson, который будет контентом блока
box:@tavriaforever от applyCtx я, в первую очередь, ожидал, что стили вложенных блоков подключатся автоматически.
Если переписывать контент куском bemjson, приходится создавать файл box.deps.js:
Не хотелось бы писать зависимости для каждого враппера.
Нет смысла такие стили раскидывать по папкам. Пишите их в рамках стилей 'box'
Согласен с @Guria Но на будущее - твою запись депсов можно сократить до
@Guria @sipayRT а если примиксован другой блок со своими технологиями к одному из вложенных элементов?
@raulleo зависимости нужно писать в любом случае — доставать зависимости из bemhtml программы это не тривиальная задача, т.к. может быть написано
var res = {}; if(...) res.elem = myVar;и т.п. (см. также https://github.com/bem/bem-forum-content-ru/issues/298#issuecomment-83813859)@veged А давайте писать зависимости как в Ангуляре? Ну, всмысле не прямо так, а по такой же идее. Вначале css-файла делать
@importнужных. В начале js-файлов уже всё написано, там же модульная система. И для bemhtml что-нибудь подобное ввести. Потом сборщик всё это считывает и собирает так же как сейчас.@varya таким образом, кажется, можно выразить только mustDeps из текущего формата описания зависимостей. Как быть с depsByTech и shouldDeps?
@varya кстати,
@importв css файле и блок в зависимостях - это разные вещи.@importвставляет столько раз, сколько его напишешь, а блок в сборку попадет только один раз.mustDeps и shouldDeps различать тем, в начале файла написана зависимость или в конце. Ну для depsByTech так и быть можно как сейчас сделать. Главное что если в файле писать для простых случаев, то похоже на другие системы и сразу ниже порог вхождения.
@varya Я, кстати, слышал про технологию для enb, которая зависимости собирает по тому, что в js-файлах указано, но сейчас ее найти не могу.
@apsavin https://github.com/enb-make/enb-modules/blob/master/techs/deps-with-modules.js
@varya @apsavin Идея крутая, но это будет каша...
@importв css-файлах это и есть чесныйdepsByTech, но только дляcssтехнологии.Это значит, что для построения CSS-файлов не обязательны DEPS-файлы, и может быть достаточно только кода. Чтобы построить шаблоны и прочее, по-прежнему смотрим в DEPS-файлы и не смотрим в CSS.
Но и совсем без обычных DEPS-ов не обойтись.
Пример:
Допустим, что нам нужна кнопка. в BEMJSON-файле она будет записана так:
Из BEMJSON получаем декларацию:
Исходный код шаблонов:
button.bemhtmlДля шаблонов пишем зависимости:
button.deps.jsДополняем декларацию зависимостями:
Исходные файлы CSS-файлы:
button.cssbutton__text.cssПо дополненной декларации, строим CSS-файл:
Если бы мы для шаблонов написали зависимости вида
depsByTechТо в результирующий CSS-файл, не попал бы код элемента
button__text, и это было бы ошибкой. При этомbutton.cssникак не зависит отbutton__textи использовать@importтут было бы не уместно.@importбольше подойдёт для случая с модификатором, например:button_size_m.cssТ.е. я бы рассматривал
@importкак что-то дополняющее DEPS-файлы, но не заменяющее их.@zxqfox почему будет каша?
@varya вариант с
@importв конце файла, кажется, не очень очивидным. Тем более, это не чесный аналогshouldDeps: код из@importбудет всегда снизу.@apsavin это же не мешает настроить сборщик таким образом, чтобы код вставлялся только один раз.
@apsavin Если рассматривать
@importкак нечто дополняющее, то можно всегда считать, что этоmustDepsа для остальных случаев есть DEPS-файлы.@blond
Собственно, я вот к этому и писал: