Open webhive opened 7 years ago
Вообще это странно. Я только что проделал эти же действия
diff --git a/.enb/make.js b/.enb/make.js
index 8289757..e37b58b 100644
--- a/.enb/make.js
+++ b/.enb/make.js
@@ -25,7 +25,7 @@ var techs = {
browserJs: require('enb-js/techs/browser-js'),
// bemtree
- // bemtree: require('enb-bemxjst/techs/bemtree'),
+ bemtree: require('enb-bemxjst/techs/bemtree'),
// bemhtml
bemhtml: require('enb-bemxjst/techs/bemhtml'),
@@ -63,7 +63,7 @@ module.exports = function(config) {
}],
// bemtree
- // [techs.bemtree, { sourceSuffixes: ['bemtree', 'bemtree.js'] }],
+ [techs.bemtree, { sourceSuffixes: ['bemtree', 'bemtree.js'] }],
// bemhtml
[techs.bemhtml, {
@@ -109,6 +109,6 @@ module.exports = function(config) {
[techs.borschik, { source: '?.css', target: '?.min.css', minify: isProd }]
]);
- nodeConfig.addTargets([/* '?.bemtree.js', */ '?.html', '?.min.css', '?.min.js']);
+ nodeConfig.addTargets(['?.bemtree.js', '?.html', '?.min.css', '?.min.js']);
});
};
и у меня вот такой результат:
15:24:25.914 - build started
15:24:25.934 - [rebuild] [desktop.bundles/index/index.bemjson.js] file-provider
15:24:25.991 - [rebuild] [desktop.bundles/index/index.levels] levels
15:24:25.992 - [rebuild] [desktop.bundles/index/index.bemdecl.js] bemjson-to-bemdecl
15:24:26.042 - [rebuild] [desktop.bundles/index/index.deps.js] deps
15:24:26.048 - [rebuild] [desktop.bundles/index/index.files] files
15:24:26.049 - [rebuild] [desktop.bundles/index/index.dirs] files
15:24:26.366 - [rebuild] [desktop.bundles/index/index.bemtree.js] bemtree
15:24:26.367 - [rebuild] [desktop.bundles/index/index.bemhtml.bemdecl.js] deps-by-tech-to-bemdecl
15:24:26.384 - [rebuild] [desktop.bundles/index/index.browser.js] browser-js
15:24:26.385 - [rebuild] [desktop.bundles/index/index.bemhtml.deps.js] deps
15:24:26.386 - [rebuild] [desktop.bundles/index/index.bemhtml.files] files
15:24:26.386 - [rebuild] [desktop.bundles/index/index.bemhtml.dirs] files
15:24:26.393 - [rebuild] [desktop.bundles/index/index.browser.bemhtml.js] bemhtml
15:24:26.398 - [rebuild] [desktop.bundles/index/index.js] file-merge
15:24:26.572 - [rebuild] [desktop.bundles/index/index.css] enb-postcss
15:24:26.577 - [rebuild] [desktop.bundles/index/index.bemhtml.js] bemhtml
15:24:26.647 - [rebuild] [desktop.bundles/index/index.html] bemjson-to-html
15:24:26.650 - [rebuild] [desktop.bundles/index/index.min.js] borschik
15:24:26.794 - [rebuild] [desktop.bundles/index/index.min.css] borschik
15:24:26.795 - build finished - 1917ms
Но вообще, если нужно по BEMTREE генерировать статические HTML-страницы, то имеет смысл использовать https://github.com/tadatuta/bem-bemtree-static-project-stub (это примерно тот же project-stub + технология для генерации страничек с учетом BEMTREE).
Попробовал на чистом project-stub
(не merged). Раскомментировано всё как у вас. С виду вывод такой-же. Создал блок test
в папке common.blocks
.
test.bemtree.js
block('test').content()(function(){
return {
tag: 'h1',
content: 'Hello!'
}
})
Добавляю его в bemjson
index
-a
...
block: 'header',
content: [
'header content goes here',
{ block: 'test' }
]
...
В итоговом html
-е получаю .... <div class="test"></div> ....
, т.е. я так понимаю bemtree
файл не отработал. Насколько я понимаю вывод должен быть .... <div class="test"><h1>Hello!</h1></div> ....
Или чего-то я ещё упустил?
PS: bem-bemtree-static-project-stub уже ковырял, но не помогло
У меня на project-stub
тоже не собирает из index.bemjson.js
, после того как де-комментировал про bemtree
bem-bemtree-static-project-stub
предлагает по умолчанию index.bemdecl.js
в котором вызывается root
и всё... нет bemjson'а
Ребята, может у вас там рабочий проект... и вся среда разработки закешировалось!? ))))))))
А если без шуток. Пожалуйста дайте рабочий пример... не первый раз прошу - не ответили. С открытым сердцем, готов помочь - чем могу, хоть про bemtree
запилить статью про стартовый проект, или еще чего. Но особо не чем делиться, пишу 5ую простыню в 5000 строк bemjson'а
нет bemjson'а
Ну он как раз должен сгенерироваться с помощью bemtree. Вот тока не работает оно почему-то.
@tadatuta Но вообще, если нужно по BEMTREE генерировать статические HTML-страницы, то имеет смысл использовать https://github.com/tadatuta/bem-bemtree-static-project-stub (это примерно тот же project-stub + технология для генерации страничек с учетом BEMTREE).
Всё чудесатее и чудесатее. Вопрос - почему в .enb\make.js
нет addTarget
для bemtree
? А в project-stub
есть?
Второй момент - bem-bemtree-static-project-stub
использует bemdecl
вместо bemjson
-а, но если я пробую сделать так-же на project-stub
-е то получаю ошибку.
Что-то тут видимо в enb
накручено не так, но я в виду неопытности не могу сообразить в чём проблема.
Блин - сижу сверяю диффом make.js -ы. Бред какой-то.
Ёёёёёперный театр - сколько же там магии и ручного кода. Заставил я это дело пинками работать, перетащив часть конструкций из bem-bemtree-static-project-stub
. Но ..... просто слов нет и тут вместо своего тестового блока с нехитрым именем test
получаю на выходе блок с именем root
. Занавес!!! Как оказалось в bem-bemtree-static-project-stub
подключается своя вручную писана технология .enb/techs/bemtree-to-html.js
в которой прошито
...
return BEMHTML.apply(BEMTREE.apply({ block: 'root' }));
...
Т.е. как ты жопой ни крути, а корневым должен быть блок root
. Ну почему вот всё вот так? Да - я в конце-концов разобрался, но сколько сил потрачено впустую. Вместо того, чтоб работать над проектом, я должен ковырять ваши исходники, выдирать из разных подпроектов какие-то куски кода, да ещё их модифицировать.
Ну и насколько я понял раз уж @tadatuta для bemtree
вручную код пишет, то видимо на enb
по умолчанию с bemtree
работать никак.
@webhive Причина о том, что не бывает никакого «по умолчанию». Есть конкретные задачи и для них специфичные решения.
Если говорить именно в контексте ENB, то с точки зрения сборки самого BEMTREE-бандла нет вообще ни малейших отличий от сборки BEMHTML. Отличия есть в источнике данных и в том, что именно хочется сгенерировать в результате.
В частности, если нужно собирать по одной HTML-странице на основе BEMTREE, то не обязательно что-либо делать руками, можно просто брать https://github.com/tadatuta/bem-bemtree-static-project-stub, репозиторий для того и существует (блок root
, разумеется, не является чем-то обязательным, это просто произвольное название, которое написано вот тут, его можно заменить на то, что больше нравится).
Есть другая схема: когда на вход некоторая модель данных, а на выход произвольная структура HTML-страниц. Так, например, генерируется bem.info по вот такой модельке.
Еще вариант — когда сайт динамический. Для такого подхода можно использовать репозиторий https://github.com/bem/bem-express.
Все три варианта используют BEMTREE, но используют по-разному. Поэтому сделать что-то по-умолчанию и не получится.
Ну и, наконец, не вижу ничего военного в том, чтобы написать под себя технологию для ENB. Если смотреть на https://github.com/tadatuta/bem-bemtree-static-project-stub/blob/master/.enb/techs/bemtree-to-html.js, то там менее двух десятков строк кода, остальное JSDoc. По смыслу там написано буквально следующее: возьми BEMTREE-бандл, передай в него данные, то, что получится передай в BEMHTML, а результат запиши на диск.
В коде это еще проще, чем текстом:
BEMHTML.apply(BEMTREE.apply({ block: 'root' }));
Ну и оставшиеся вопросы:
почему в
.enb\make.js
нетaddTarget
дляbemtree
? А вproject-stub
есть?
Потому что технология получения HTML сама автоматически потребует сгенерировать BEMTREE-бандл. Указывать его в таргетах явно не обязательно (хотя и можно).
bem-bemtree-static-project-stub
используетbemdecl
вместоbemjson
-а, но если я пробую сделать так-же на project-stub-е то получаю ошибку
Тут может быть 2 причины:
enb-bemxjst
ожидает на вход готовый BEMJSON. Если хочется использовать для генерации HTML-страниц BEMTREE, нужна соответствующая технология.Такая уж ли это прямо магия? ;)
@DjonyBastone
bem-bemtree-static-project-stub предлагает по умолчанию index.bemdecl.js в котором вызывается root и всё... нет bemjson'а
Ну как так-то? Там в качестве примера из коробки рисуется шапка с логотипом:
root
, он генерирует обвязку страницы: https://github.com/tadatuta/bem-bemtree-static-project-stub/blob/master/common.blocks/root/root.bemtree.jspage
рисуются верхнеуровневые блоки header
, main
и footer
внутри <body>
: https://github.com/tadatuta/bem-bemtree-static-project-stub/blob/master/common.blocks/page/page.bemtree.jsheader
-е добавляется логотип: https://github.com/tadatuta/bem-bemtree-static-project-stub/blob/master/common.blocks/header/header.bemtree.jsВозможно, проблема в том, что при создании собственных блоков они не указываются в депсах? В отличии от сборки по готовому BEMJSON-файлу, BEMTREE-шаблоны сначала необходимо собирать, поэтому депсы приходится писать руками (примеры там же рядом с bemtree-шаблонами).
@tadatuta Причина о том, что не бывает никакого «по умолчанию».
Не вполне соглашусь. В качестве примера сошлюсь на себя :-) Про сборку всё понятно - в смысле как оно работает, вернее даже как оно должно работать. Я немного про другое. Вот беру я project-stub
- ну не нужен мне bemtree
(пока). Поигрался я и хочу подключить bemtree
. Ну вроде как в теории всё понятно - надо подключить технологию и типа оно заработает - вау - да там и в make.js строчки закомментареные. Расскоментариваем и ничего .... далее идет куча вопросов - может я bemtree
файл неправильный сделал, может не туда его положил, может ещё чего. Далее начинаю ползать по bem проектам на github-е и сравнивать make.js -ы. Самое безобразное-то, что отличие-то там где его и не ждали.
bemjsonToHtml: require('./techs/bemtree-to-html')
Названия не смущают? В обоих проектах вызывается [techs.bemjsonToHtml] но вот только внутренности разные. Это ли не магия?
Тут может быть 2 причины:
На самом деле вот разница: https://github.com/bem/project-stub/blob/master/.enb/make.js#L54
В project-stub
bemdecl
генерируется из bemjson
.
В общем как ни верти - много нюансов и неоднозначных мест. И простая казалось бы штука превращается в лютый геморрой.
@webhive На самом-то деле при раскомментировании строк про сборку bemtree
в project-stub
, бандл с bemtree-шаблонами собирается. Тут все честно.
А вот дальше начинается кастомщина про то, как собиранный бандл использовать: собрать из каждого бандла отдельный HTML или одного бандла много разных, записать его на диск или отдавать на каждый запрос динамически и так далее.
В обоих проектах вызывается [techs.bemjsonToHtml] но вот только внутренности разные. Это ли не магия?
Это скорее неудачный копипаст. Стоит поправить, с радостью приму pull request ;)
В
project-stub
bemdecl
генерируется изbemjson
.
Прикол в том, что при желании эту схему можно сохранить и с BEMTREE. Например, использовать исходный bemjson-файл вместо захардкодженного в технологии блока root
в качестве стартового контекста при вызове BEMTREE.apply()
.
Тут нет «правильного» решения, есть решения для конкретной задачи.
@tadatuta
С deps
вообще нет проблем, напишу их сколько надо, хоть тысячу
Вопрос в том:
main
со своим контентом(наполнением).
Что нужно сделать, для того что бы сработало?
а именно:main
@DjonyBastone проблема ещё актуальна?
По поводу deps
.
Вот для примера такой граф построения страницы (который описал @tadatuta https://github.com/bem-site/bem-forum-content-ru/issues/1317#issuecomment-294950202)
header - logo
/
root - page - main
\
footer
root
- это просто вспомогательный "захардкоженный" блок. По факту это может быть любой блок, откуда начать построение. Данный блок генерирует блок page
, значит в его зависимостях должен быть данный блок.
// blocks/root/root.deps.js
[{
shouldDeps : [
{ block : 'page' }
]
}];
Далее шаблонизатор попадает в блок page
, который генерирует header
, main
, footer
.
// blocks/page/page.deps.js
[{
shouldDeps : [
{ block : 'header' },
{ block : 'main' },
{ block : 'footer' }
]
}];
При попадании в header
генерируется logo
, значит укажем его в зависимостях.
// blocks/header/header.deps.js
[{
shouldDeps : [
{ block : 'logo' }
]
}];
deps
файлы нужны для того, чтобы собрать нужные шаблоны. Если нужного шаблона не будет в сборке, то шаблонизатор не сможет обработать дерево (и соответственно ничего не построится).
По факту все зависимости можно указать в одном месте (например root
), но это очень плохая (даже ужасная) практика.
// blocks/root/root.deps.js
[{
shouldDeps : [
{ block : 'page' },
{ block : 'header' },
{ block : 'main' },
{ block : 'footer' },
{ block : 'logo' }
]
}];
По поводу построения нужных страниц, @tadatuta а действительно... Как генерировать нужные страницы?
Раз https://github.com/tadatuta/bem-bemtree-static-project-stub/blob/master/.enb/make.js#L75
Тут что-то странное.
@belozer Вопрос актуальный.
И так как ответа нет, и сам не сообразил - то, забросил это дело, всю разработку по бэм. Если будет решение - продолжу... нет - дак, нет. Захожу периодически на форум, в надежде увидеть для себя ответ.
Вопрос вообще важный, влияющий на принятие решения об архитектуре проекта. И очень жаль что ребята игнорируют данную тему.
@DjonyBastone архитектурно нет ничего сложного :) Просто из коробки решения не самые удачные для старта, к сожалению... Проблема в том, что они часто запутывают или ведут в тупик (как project-stub). На следующих выходных постараюсь собрать стартовый набор для разработки (с выжимкой граблей, которые отгрёб за время изучения). Надеюсь он тебе поможет :)
Это очень хорошая идея!!!
Если что смогу помочь с документацией, вдруг потребуется.
Есть опыт - доходчиво оформлять инструкции, минирегламенты, руководства
архитектурно нет ничего сложного :)
Блин, в том-то и загвоздка - архитектурно всё отлично и даже заманчиво, но реализация- жуть и мрак. Всё время уходит на борьбу с бэм-ом, а не на разработку.
то, забросил это дело
Я вот уже несколько раз забрасываю, потом опять - дай думаю попробую - опять шаг вперёд и снова как в болото то одно не работает то другое и опять рукой махну.
@webhive @DjonyBastone Накидал "своё видение" стартового набора для обучения бэм разработке. https://github.com/bem-contrib/bem-starter-kit
Он во многом похож на репозиторий @tadatuta, практически идентичен.
Основная его идея приучить работать с deps
и bemtree
на ранних этапах и при этом сохранить простоту project-stub
.
Из плюсов данного подхода:
Из минусов:
Создаётся бандл/страница bundles/my-page/my-page.bemjson.js
, в которой описывается блок page
и его содержание.
В общем на этом этапе сохраняется простота project-stub. Всё что объявлено в этом bemjson
подтягивается из файловой системы автоматически (например блок greeting
).
Чтобы не городить длинные полотна из bemjson
разбиваем проект по блокам со своими зависимостями, т.е. работает эта схема https://github.com/bem-site/bem-forum-content-ru/issues/1317#issuecomment-299576350 Основная идея не захломлять вёрстку кучей вложенности (https://github.com/bem/project-stub/issues/159#issuecomment-240557915)
В общем как-то так. Всё просто.
bemtree
бандлы собираются в файл bundles/my-page.bemtree.js
bemhtml
бандлы собираются в файл bundles/my-page.bemhtml.js
browser.js
бандлы собираются в файл bundles/my-page.browser.js
(js и min.js это склееные browser.js + bemhtml.js)
и т.д. Технические/промежуточные бандлы типа декларций я постарался отделить точкой в начале имени файла, чтобы они прятались системой от глаз.
Так выглядит собранный бандл (без промежуточных файлов)
bundles
└── index
├── index.bemhtml.js
├── index.bemjson.js
├── index.bemtree.js
├── index.browser.js
├── index.css
├── index.html
├── index.js
├── index.min.css
└── index.min.js
П.Н. И не стоит забывать что это только один из вариантов настройки сборки, не более :) Но с заложенными принципами, которые нужны при любой настройке сборки.
Пробуйте :) Получается или нет в такой схеме вам работать. Буду ждать отзывов, т.к. буду его дорабатывать время от времени.
Я конечно дико извиняюсь, но действительно в чём тут принципиально отличие от project-stub
?
И опять в качестве примера один тривиальный бандл. Таких примеров полно и с ними как раз проблем нет.
Сделайте внятный пример с как минимум 2-мя разными бандлами, где будет допустим общий header/footer, но разный контент.
Создаётся бандл/страница bundles/my-page/my-page.bemjson.js
Опять у нас bemjson "first-class citizen" на входе у нас данные, а bemjsоn надо ещё сгенерировать. Давайте уж перейдём к реальным примерам из реальной жизни, а не абстрактным вещам "берём bemjson и он прекрасно превращается в html".
У меня нет сомнений, что обе технологии bemhtml и bemtree работают (это суть одно и то-же). Вопрос как их применять на практике в реальных задачах.
Чтоб подлить масла в огонь подкину идею - теперь выложите проект на сервер и чтоб там оно работало и на реальные запросы отвечало в динамике. Не просто сгенерированный html отдавать как статику, а чтоб весь цикл отрабатывал data -> bemtree -> bemhtml -> html. Насколько я понял придётся писать свою middleware и внутри вызывать bemtree и bemhtml из библиотеки, а не пользоваться сборщиком. И вот там ещё больше ада, хотя опять на одной простой страничке с одним блоком всё вроде бы и нормально, но шаг влево шаг вправо и начинаются проблемы.
Итого прорезюмирую - такие примитивные примеры как у вас смысла не имеют. Времена когда для демонстрации хватало вывести "Hello world!" уже давно прошли.
Сделайте реальный пример на полном стэке -- data -> bemtree -> bemhtml -> html
где бандлы состоят и общих блоков и своих уникальных, типа классического общий header/footer + свой контент. Причём копипаста блоков header/footer не считается.
@webhive спасибо за отзыв. Не всё совсем так, как ты описал. Этот кит немного хитрей и больше представляет собой "статический" набор для вёрстки, которую потом намного проще подключить к динамике.
bemjson
в данном случае выступает точкой для построения всего дерева.
data + bemjson(root) -> bemtree -> bemjson -> bemhtml -> html
На сервер выкладывать не буду, а вот функцию для рендера данных добавлю.
@belozer спасибо большое!!!
Еще не ознакомился, на неделе обкатывать буду. Будут вопросы обязательно напишу!
По документации параллельно прилагать усилия?
Поставил project-stub из merged ветки. В нём есть 3 места где закомментировано использование bemtree. Соответственно раскомментировал, но bemtree-файлы почему-то не подхватываются.
Даже упоминания нет. Соответственно вопрос - что делать?