Closed Hurtsok closed 8 years ago
@blond
@Hurtsok, беглым взглядом кажется, что проблема в конфигурации нод.
Пакет enb-bem-examples
берёт BEMJSON-файлы из примеров, которые хранятся в блоках: block.examples/example-name.bemjson.js
и предоставляет их в сеты примеров: desktop.examples/button/example-name/example-name.bemjson.js
.
Тут следует обратить внимание, что маской к такой ноде будет *.examples/*/*
. Судя по логу ошибка возникает в том месте где BEMJSON пытается взяться по такой маске *.examples/*
(на один уровень выше).
Ошибка возникает на этапе сборки бандлов(common-desktop и common-mobile) . При сборке которых нет необходимости провайдить .bemjson.js.
Можешь подробнее расказать что это за примеры? Как они расположены на файловой системе изначально?
Что касается разного поведения на Windows и OS X/Linux, то скорее всего это какая-то ошибка в Windows.
@blond, у нас есть библиотека блоков, мы собираем не большую документацию по ним, чтобы всей команде было с ними проще работать.
Все примеры блоков, вместе с их описанием хранятся в .md
файле который лежит *.examples/*/*/?.md
. Насколько я понимаю файл парсится и ищутся вставки вида
```bemjson
{
block: 'b-test'
}
Сам enb-bem-examples
провайдит только .bemjson.js
, но нам необходимы еще css,js,bemhtml, html. Мы пробовали написать конфиг для ноды вида *.examples/*/*
, чтобы до собрать оставшиеся файлы, но такой вариант не подошел по 2 причинам:
1) Каждый раз при вызове enb make
у нас собирались и страницы, и примеры, что нам не нужно
2) Сборка всегда проходила с ошибкой, что мы не провайдим bemjson.js
. А если начинаем провайдит, то возникает конфиликт т.к его провайдит enb-bem-examples
каждый раз при запуске таска examples
Тот код, что я привел в посте решил все наши проблемы, но возникла проблема со сборкой на разных платформах...
Проблему эту можно решить, если создать файл .bemjson.js
в block.examples/*
, но насколько я понимаю, он не обязателен если мы собираем мердж бандл с помощью .deps.js
.
1) Каждый раз при вызове enb make у нас собирались и страницы, и примеры, что нам не нужно
Кажется, я понял в чём проблема.
Конфиг всё же надо написать для нод вида *.examples/*/*
.
А проблема вот в чём: сам ENB не умеет работать с magic пакетами. Точнее, с некоторыми работает, но по случайному совпадению. И с enb-bem-examples
когда-то давно мог, поэтому в документации осталось про запуск через enb make
.
Для таких пакетов нужно использовать пакет enb-magic-platform.
С точки зрения API он почти ничем не отличается:
$ magic --help
ENB magic platform
Usage:
magic COMMAND [OPTIONS] [ARGS]
magic [OPTIONS] [ARGS]
Commands:
make : build specified targets
run : run specified tasks
server : run development server
Options:
-h, --help : Help
-v, --version : version
Если нужно собрать что-то по пути — надо использовать make
команду:
Сет примеров:
$ magic make blocks.examples/
Примеры блока:
$ magic make blocks.examples/button
Конкретный пример блока:
$ magic make blocks.examples/button/OFa8iJsKWLBtnoxXtfgoLCc
Если нужно запустить таск:
$ magic run examples
Если нужно запустить сервер:
$ magic server
Magic server started at http://0.0.0.0:8080
@blond
Мы добились эффекта чтобы enb make
собирала только страницы, а команда enb make examples
собирала только примеры.
Если убрать сборку бандлов с примерами и собирать только таргеты примеров, то проблема уходит.
Конфиг для enb-bem-examples
есть, просто сейчас не могу его выложить, нет под рукой :) , чуть позже сюда скину.
Пример в ветке, это донастройка enb-make-examples
через фабрику, т.к примеры сами под капотом ее используют
@blond
И очень странно поведение с enb make
.
Если описать ноду в таком виде:
node.nodes('*.examples/*/*', function(){})
То эта команда будет собирать и примеры и страницы. Если написать так:
node.nodes(['block.examples/button/buttonHash', block.examples/popup/popupHash', ....], function(){})
Так будут собираться только страницы
Я заглянул под капот `enb-bem-examples
и декларация нод происходит в таком виде ['block.examples/button/buttonHash', block.examples/popup/popupHash', ....]
@blond
Вот более полный пример сборки примеров и их бандлов, с конфигом для enb-bem-examples
config.includeConfig('enb-bem-examples');
var examples = config.module('enb-bem-examples').createConfigurator('examples');
examples.configure({
destPath: appConfig.examplesDir,
levels: appConfig.examplesWatchedDirs,
inlineBemjson: true,
processInlineBemjson: function (bemjson, meta) {
var basename = path.basename(meta.filename, '.bemjson.js');
return {
block: 'page',
head: [
{
elem: 'js',
url: '/' + appConfig.examplesDir + '/' + naming.stringify(bemjson) + '/' + basename + '/' + basename + '.js'
},
{
elem: 'css',
url: '/' + appConfig.examplesDir + '/' + naming.stringify(bemjson) + '/' + basename + '/' + basename + '.css'
}
],
content: bemjson
}
}
});
var factory = config.module('enb-magic-factory'),
helper = factory.getHelper('examples');
helper.prebuild(function(magicConfig){
magicConfig.registerNode('blocks.examples/common-desktop');
magicConfig.registerNode('blocks.examples/common-mobile');
});
helper.configure(function(config, nodes, targets){
var nodes = nodes;
config.nodes(nodes, function(nodeConfig){
if(nodeConfig.getPath() === appConfig.examplesDir + '/common-desktop' || nodeConfig.getPath() === appConfig.examplesDir + '/common-mobile'){
console.log(nodeConfig.getTechs());
var depsDesktop = [],
depsMobile = [];
nodeConfig.addTechs([
[ require('enb-bem-techs/techs/levels'), {levels: getExamplesLevels(config)} ],
[ enbBemTechs.files ],
[ techs.js ]
]);
nodes.forEach(function (node) {
if (!/\/.*common.*/.test(node)) {
var pathNorm = path.normalize(node),
splitedPath = pathNorm.split(path.sep);
if(/m\-.\w*/.test(node)){
depsMobile.push(splitedPath[splitedPath.length - 1] + '.deps.js');
nodeConfig.addTechs([
//copy deps files to common-mobile dir
[ enbBemTechs.provideDeps, { node: pathNorm, target: splitedPath[splitedPath.length - 1] + '.deps.js' } ],
]);
}else{
depsDesktop.push(splitedPath[splitedPath.length - 1] + '.deps.js');
nodeConfig.addTechs([
//copy deps files to common-desktop dir
[ enbBemTechs.provideDeps, { node: pathNorm, target: splitedPath[splitedPath.length - 1] + '.deps.js' } ],
]);
}
}
});
//merge bundle
if(nodeConfig.getPath() === appConfig.examplesDir + '/common-mobile'){
nodeConfig.addTechs([
[ enbBemTechs.mergeDeps, { sources: depsMobile }]
])
}
if(nodeConfig.getPath() === appConfig.examplesDir + '/common-desktop'){
nodeConfig.addTechs([
[ enbBemTechs.mergeDeps, { sources: depsDesktop }]
])
}
nodeConfig.addTechs([
//bemhtml
[ techs.bemhtml, { sourceSuffixes: [ 'bemhtml', 'bemhtml.js' ] } ],
//css
[ techs.cssStylus, {target: '?.noprefix.css'}],
[ techs.cssAutoprefixer, {
sourceTarget: "?.noprefix.css",
destTarget: '?.css',
browserSupport: ["> 2%", "last 2 versions", "Firefox ESR", "Opera 12.1", "Android >= 4", "iOS >= 5"]
}]
]);
nodeConfig.addTargets(['?.js', '?.css', '?.bemhtml.js']);
}else {
console.log(nodeConfig.getTechs());
nodeConfig.addTechs([
[require('enb-bem-techs/techs/levels'), {levels: getExamplesLevels(config)}],
[enbBemTechs.bemjsonToBemdecl],
[enbBemTechs.depsOld],
[enbBemTechs.files],
//CSS
[techs.cssStylus, {target: '?.noprefix.css'}],
[techs.cssAutoprefixer, {
sourceTarget: "?.noprefix.css",
destTarget: '?.css',
browserSupport: ["> 2%", "last 2 versions", "Firefox ESR", "Opera 12.1", "Android >= 4", "iOS >= 5"]
}],
//BEMHTML
[techs.bemtree, {sourceSuffixes: ['bemhtml', 'bemhtml.js']}],
//BEMHTML
[techs.bemhtml, {sourceSuffixes: ['bemhtml', 'bemhtml.js']}],
//HTML
[techs.htmlBeautify],
[techs.htmlFromJSON],
//client JS
[techs.browserJs],
[techs.fileMerge, {target: '?.pre.js', sources: ['?.bemhtml.js', '?.browser.js']}],
[techs.prependYm, {source: '?.pre.js'}]
]);
nodeConfig.addTargets(['?.js', '?.css', '?.html', '?.browser.js', '?.beauty.html', '?.bemtree.js']);
}
});
});
@blond
Поставили enb-magic-platform
эффект тот же. Windows - ок, остальные fail.
Уже начали думать в пользу костылей, создавать на лету '.bemjson.js' для бандлов.
Мне кажется проблема кроется в enb-bem-examples
@Hurtsok Спасибо за подробности!
Я всё же, пока считаю, что проблема в конифге :)
Вот тут регистрируются ноды:
helper.prebuild(function(magicConfig){ magicConfig.registerNode('blocks.examples/common-desktop'); magicConfig.registerNode('blocks.examples/common-mobile'); });
Порядок исполнения будет такой:
prebuild
.prebuild
.configure
: https://github.com/enb-bem/enb-bem-examples/blob/master/lib/plugins/inline-bemjson.js#L111-L133.configure
.Из-за пункта (2) в родной configure
(3) придут эти ноды, и соответственно, там не будет симлинки. И этот код выполнится: https://github.com/enb-bem/enb-bem-examples/blob/master/lib/plugins/inline-bemjson.js#L130-L131.
Тут важно понимать, что prebuild
и configure
дополняют, а не переопределяют. Я бы предложил в текущем случае enb-bem-examples
использовать только для сборки инлайновых примеров, скажем в md-examples
таске. Плюс сделать мета-таск examples
, который будет просто вызывать сборку 2х бандлов + md-examples
.
Работа в Windows может отличаться из-за специфики симлинок. Я чесно говоря не знаю как симлинки работают в Windows.
@blond Спасибо за ответ! Очень помог :) Все же вы правы по поводу ошибки в конфиге.
Из-за пункта (2) в родной configure (3) придут эти ноды, и соответственно, там не будет симлинки. И этот код выполнится: https://github.com/enb-bem/enb-bem-examples/blob/master/lib/plugins/inline-bemjson.js#L130-L131.
Вот тут то и крылась проблема.
А по поводу
Тут важно понимать, что prebuild и configure дополняют, а не переопределяют.
Мы собственно и решили до определить изначально :)
Проблему решили, мы просто на этапе prebuild
создаем в директории с бандлом пустой bemjson, а когда завершается сборка c помощью EventEmitter
по событию build
прибираем за собой.
Всем привет!
Очень интересную ситуацию наблюдаю при сборке примеров для документации на разных платформах (Windows, Linux/OS X) с использованием пакетов
enb-bem-examples
иenb-magic-factory
. На Windows сборка проходит без ошибок на остальных возникает следующая ошибка:Кусок кода отвечающий за сборку примеров и их бандлов:
Ошибка возникает на этапе сборки бандлов(common-desktop и common-mobile) . При сборке которых нет необходимости провайдить
.bemjson.js
.Не много дебага с помощью
node.getTechs()
.На Windows результат будет пустой на OS X/Linux
[ { _options: { target: '?.bemjson.js' } } ]
Хотелось бы разобраться, почему сборка ведет себя по разному на разных платформах?