Пример Добавление БЭМ-сущностей для задач вёрстки из руководства по 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.css
button__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
Собственно, я вот к этому и писал: