В преведущей теме Предложение выделить технологии в отдельные пакеты упомянул о блоке someBlock, расскажу немного подробнее, пока это только эксперимент, текущая реализация позволяет подключив к странице собранный банд, разместить блок используя такую конструкцию:
<div class='someBlock i-bem'
data-bem='{"someBlock":{"url":"data_url.json}}'>
load...
</div>
В результате полученные данные из data_url.json в нормализованном JSON будут преобразованны BEMTREE в BEMJON и применен BEMHTML.
Для того что бы собрать такой бандл потребовалось в сборку добавить технологию browser.js+bemhtml+bemtree и пробросить в глобальную переменню модуль vow добавив зависимость от модификатора vow_global, а также указать для технологии js зависимость от реализаций BEMTREE/BEMHTML для самого блока и блока i-bem, в результате получился вот такой someBlock.deps.js:
[
{
mustDeps: [
{ block : 'i-bem', elems : ['dom'] },
{ block : 'vow', mods: { global: true } }
],
shouldDeps: [
{ elems: [ 'title', 'answer' ] }
]
},
{
tech : 'js',
shouldDeps : [
{ tech : 'bemhtml', block : 'i-bem' },
{ tech : 'bemhtml', block : 'someBlock' },
{ tech : 'bemtree', block : 'i-bem' },
{ tech : 'bemtree', block : 'someBlock' }
]
}
]
Пример использования http://jsfiddle.net/ilyar/5dw8Q/
Вопросы и предложения приветствуются.
Не решенные вопросы от меня
Для того что бы не помещать vow в глобальную видимость, а задействовать модульную систему,
var environ = require('bem-environ');
exports.baseTechPath = environ.getLibPath('bem-core', '.bem/techs/bemhtml.js');
exports.techMixin = {
getCompiledResult : function(sources) {
sources = sources.join('\n');
var BEMHTML = require('bem-xjst/lib/bemhtml'),
exportName = this.getExportName(),
optimize = process.env[exportName + '_ENV'] !== 'development';
return BEMHTML.generate(sources, {
wrap : true,
exportName : exportName,
optimize : optimize,
cache : optimize && process.env[exportName + '_CACHE'] === 'on',
modulesDeps : this.getModulesDeps(exportName)
});
},
getModulesDeps : function(exportName) {
return exportName == "BEMTREE" ? { vow: 'Vow' } : ''; // FIXME get from deps.js
}
};
В результате в бандле BEMTREE будет таким:
(function(g) {
var __bem_xjst = (function(exports) {
//...files.bemtree
})({});
var defineAsGlobal = true;
if(typeof exports === "object") {
exports["BEMTREE"] = __bem_xjst;
defineAsGlobal = false;
}
if(typeof modules === "object") {
modules.define("BEMTREE", ["vow"],
function(provide, Vow) { provide(__bem_xjst) });
defineAsGlobal = false;
}
defineAsGlobal && (g["BEMTREE"] = __bem_xjst);
})(this);
При это получаемм сообщение об ощибке: Uncaught ReferenceError: Vow is not defined
Вопросы:
- Почему ошибка, если модуль vow вошел в сборку и в декларации BEMTREE у казан как зависимость?
- Каким образом надо описыть modulesDeps зависимость в deps.js?
- Понимать modulesDeps должен технология deps.js или разбираем ее на уровне BEMHTML?
UPD:
1. я сделал упячку, исправление: https://github.com/bem/bem-xjst/pull/16
2, 3. modulesDeps — это переменная исклчительно в контексте bem-xjst, к технологии deps.js отношения не имеет. твоя реализация в технологии BEMHTML вполне ок, разве что я бы в bemhtml в getModulesDeps оставил пустую функцию-stub, а в технологии bemtree, которая от нее наследуется, перекрыл этот метод и вернул бы там { vow: 'Vow' }.
На самом деле я вчера начал все это делать в bem-core (есть две ветки на тему), но осознал, что исправление в bem-xjst не работает. Как вольем фикс — доделаю.
Сделаю и browser.js+bemhtml+bemtree. Там, если отрефакторить browser.js+bemhtml, реализация будет чуть лаконичнее, чем в твоем варианте.
Теперь для блока достаточно указать зависимость { block : 'vow' }
Я точно не уверен, но похоже в vow нужно пропихнуть в виртуальную машину сервера, где исполняется bemtree. И тогда vow вообще не нужно будет указывать в зависимостях. У нас это сделатно так.
Или вот пример https://github.com/bem/ss
Спасибо за ответ. В описанной мной ситуации BEMTREE и BEMHTML работают исключительно в браузере, поэтому виртуальная машина сервера тут ни причем.
2, 3. modulesDeps — это переменная исклчительно в контексте bem-xjst, к технологии deps.js отношения не имеет. твоя реализация в технологии BEMHTML вполне ок, разве что я бы в bemhtml в getModulesDeps оставил пустую функцию-stub, а в технологии bemtree, которая от нее наследуется, перекрыл этот метод и вернул бы там { vow: 'Vow' }.
На самом деле я вчера начал все это делать в bem-core (есть две ветки на тему), но осознал, что исправление в bem-xjst не работает. Как вольем фикс — доделаю.
Сделаю и browser.js+bemhtml+bemtree. Там, если отрефакторить browser.js+bemhtml, реализация будет чуть лаконичнее, чем в твоем варианте.
Отлично, теперь все ок.
bem-examples#a81f71
Теперь для блока достаточно указать зависимость { block : 'vow' }