bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Сделайте кто-нибудь урок по bem-xjst #950

Open cyberS7 opened 8 years ago

cyberS7 commented 8 years ago

Добрый день. Прошу сделать урок по bem-xjst. Я вот честно не врубаюсь как пользоваться. Спасибо.

qfox commented 8 years ago

/cc @miripiruni

miripiruni commented 8 years ago

@cyberS7 привет! А есть какие-то конкретные вопросы?

Пример кода, как завести шаблонизатор есть в readme.

Примеры шаблонов можно просмотреть в bem-components.

apsavin commented 8 years ago

А вы читали вот эти доки?

cyberS7 commented 8 years ago

Хотелось бы посмотреть пошаговый небольшой урок, чтобы понять что к чему. Тутор с гитхаба не очень) А еще урок по bem-grid. Чтобы можно было понять в какой файл, что и зачем мы подключаем. У вас в документации часто говорится "просто добавьте этот код". А куда его добавлять вообще для меня, как не для профессионала уровня Яндекса, остается загадкой)

awinogradov commented 8 years ago

@cyberS7 по bem-grid можно дергать меня, за все места и в любой соц сетке или почте)

Oleg2tor commented 8 years ago

Здравствуйте, тоже не могу понять как начать использовать БЕМ с нуля. Все конференции и статьи начинаются с клонирования project-stub. Например:

npm install -g bem
npm install bem enb-bem-techs enb-bemxjst
mkdir .bem
touch .bem/make.js
bem create level blocks
bem create level bundle
bem create -l blocks -b page -T bemhtml

WARNING! Tech module "bemhtml" at C:\Winginx\home\bem\node_modules\bem\lib\tech\index.js is using API V1. Tech modules API V1 is not recommended to use, because it is slow. Please use tech modules API V2, it makes your build process faster! Instructions for migrating to API V2: http://git.io/gbLDOA

echo block('page')(content()(function() { return { elem: 'inner', content: applyNext() }; })); >> blocks/page/page.bemhtml
touch bundle/bundle.bemjson.js
echo module.exports = { block: 'page', content: 'Hello World'}; >> bundle/bundle.bemjson.js
enb make

И получаю на выходе пустой html файл, а в файле bundle.bemhtml.js все вызовы функции buildBemXjst пустые.

Я нашел, что эту часть кода (buildBemXjst) генерит файл bundle.jst (node_modules\enb-bemxjst\lib\assets\bundle.jst), прогоняя requires (из файла node_modules\enb-bemxjst\lib\templates\bundle.js). Так вот почему-то requires пустой объект. А я так понял он должен браться из level blocks который я выше определил. Подскажите, что делаю не так?

tadatuta commented 8 years ago

@Oleg2tor все конференции начинаются с клонирования project-stub, а вы пытаетесь устанавливать какой-то случайный набор пакетов и удивляетесь, что они не работают? :)

если хочется пройти весь путь с нуля (зачем?), то схема такая:

mkdir i-will-create-project-stub-myself-because-i-can # создаем папку проекта

cd !$ # переходим в нее

npm init --yes # инициализируем package.json

npm i --save-dev bower borschik-tech-cleancss enb enb-bem-techs enb-bemxjst enb-borschik enb-js enb-stylus # это список пакетов из package.json в project-stub (https://github.com/bem/project-stub/blob/bem-core/package.json#L12-L23)

echo '{ "directory": "libs" }' > .bowerrc # папка, куда будут ставиться bower-библиотеки. Исключительно для консистентности с project-stub

./node_modules/.bin/bower i bem-components --save # библиотека блоков из bower.json в project-stub. По зависимостям вытянет ядерную библиотеку bem-core. Бояться поставить лишние библиотеки не нужно — сборка не возьмет в проект ничего, что явно не указано в зависимостях

mkdir -p .enb blocks pages/index # создаем папки для конфига сборки, блоков и для индексной страницы

touch .enb/make.js # создаем файл конфига со следующим содержанием (на 99.9% копипаст из project-stub):
var techs = {
        // essential
        fileProvider: require('enb/techs/file-provider'),
        fileMerge: require('enb/techs/file-merge'),

        // optimization
        borschik: require('enb-borschik/techs/borschik'),

        // css
        stylus: require('enb-stylus/techs/stylus'),

        // js
        browserJs: require('enb-js/techs/browser-js'),

        // bemhtml
        bemhtml: require('enb-bemxjst/techs/bemhtml'),
        bemjsonToHtml: require('enb-bemxjst/techs/bemjson-to-html')
    },
    enbBemTechs = require('enb-bem-techs'),
    levels = [
        { path: 'libs/bem-core/common.blocks', check: false },
        { path: 'libs/bem-core/desktop.blocks', check: false },
        { path: 'libs/bem-components/common.blocks', check: false },
        { path: 'libs/bem-components/desktop.blocks', check: false },
        { path: 'libs/bem-components/design/common.blocks', check: false },
        { path: 'libs/bem-components/design/desktop.blocks', check: false },
        'common.blocks'
    ];

module.exports = function(config) {
    var isProd = process.env.YENV === 'production';

    config.nodes('*pages/*', function(nodeConfig) {
        nodeConfig.addTechs([
            // essential
            [enbBemTechs.levels, { levels: levels }],
            [techs.fileProvider, { target: '?.bemjson.js' }],
            [enbBemTechs.bemjsonToBemdecl],
            [enbBemTechs.deps],
            [enbBemTechs.files],

            // css
            [techs.stylus, {
                target: '?.css',
                sourcemap: false,
                autoprefixer: {
                    browsers: ['ie >= 10', 'last 2 versions', 'opera 12.1', '> 2%']
                }
            }],

            // bemhtml
            [techs.bemhtml, { sourceSuffixes: ['bemhtml', 'bemhtml.js'] }],

            // html
            [techs.bemjsonToHtml],

            // client bemhtml
            [enbBemTechs.depsByTechToBemdecl, {
                target: '?.bemhtml.bemdecl.js',
                sourceTech: 'js',
                destTech: 'bemhtml'
            }],
            [enbBemTechs.deps, {
                target: '?.bemhtml.deps.js',
                bemdeclFile: '?.bemhtml.bemdecl.js'
            }],
            [enbBemTechs.files, {
                depsFile: '?.bemhtml.deps.js',
                filesTarget: '?.bemhtml.files',
                dirsTarget: '?.bemhtml.dirs'
            }],
            [techs.bemhtml, {
                target: '?.browser.bemhtml.js',
                filesTarget: '?.bemhtml.files',
                sourceSuffixes: ['bemhtml', 'bemhtml.js']
            }],

            // js
            [techs.browserJs, { includeYM: true }],
            [techs.fileMerge, {
                target: '?.js',
                sources: ['?.browser.js', '?.browser.bemhtml.js']
            }],

            // borschik
            [techs.borschik, { source: '?.js', target: '?.min.js', minify: isProd }],
            [techs.borschik, { source: '?.css', target: '?.min.css', tech: 'cleancss', minify: isProd }]
        ]);

        nodeConfig.addTargets(['?.html', '?.min.css', '?.min.js']);
    });
};
touch pages/index/index.bemjson.js # создаем декларацию страницы со следующим содержанием:
module.exports = {
    block : 'page',
    title : 'Title of the page',
    favicon : '/favicon.ico',
    head : [
        { elem : 'meta', attrs : { name : 'description', content : '' } },
        { elem : 'meta', attrs : { name : 'viewport', content : 'width=device-width, initial-scale=1' } },
        { elem : 'css', url : 'index.min.css' }
    ],
    scripts: [{ elem : 'js', url : 'index.min.js' }],
    mods : { theme : 'islands' },
    content : [
        'this is my awesome project-stub!'
    ]
};
./node_modules/.bin/enb make # собираем проект

open pages/index/index.html # открываем полученную страницу

Как вариант вместо сборки можно запустить dev-сервер: ./node_modules/.bin/enb server.

Поздравляю, вы только что получили project-stub с помощью 10 команд вместо трех :)

awinogradov commented 8 years ago

Но кажется лучше пойти сюда https://github.com/bem/project-stub ;)

vithar commented 8 years ago

@tadatuta

Oleg2tor commented 8 years ago

@tadatuta

Спасибо конечно, но вы, видимо, меня не так поняли. Я не собирался делать свой project-stub с блэкджеком. У меня была цель сделать минимальный конфиг для генерации html файлов из bemhtml.

Разобрался в чем дело, оказывается команда bem create -l blocks -b page -T bemhtml создает файл с расширением .bemhtml, а в .make прописано правило для node.addTarget('?.bemhtml.js') (взято из примера https://github.com/enb/enb-bemxjst). Прекрасно генерит без всяких bem-core, bem-comonents и прочего. Осталось tech добавить для css.

tadatuta commented 8 years ago

@Oleg2tor в такой постановке минимальным и достаточным будет: npm i bem-xjst и require('bem-xjst').bemhtml.compile('текст шаблона').apply(bemjson);

Работающий пример:

mkdir myproj
cd !$
npm init --yes
npm i bem-xjst --save # ставим пакет bem-xjst, который предоставляет технологии BEMHTML и BEMTREE
touch generateHtml.js # создаем файл, где будет вызываться применение шаблонов
touch templates.bemhtml.js # создаем файл, куда будем писать шаблоны (на самом деле опционально)
// templates.bemhtml.js 
block('list')(
    tag()('ul'),
    elem('item').tag()('li')
);
// generateHtml.js
var fs = require('fs');
var bemhtml = require('bem-xjst').bemhtml;
var bemjson = {
    block: 'list',
    content: ['e1', 'e2', 'e3'].map(e => ({ elem: 'item', content: e }))
};
var html = bemhtml.compile(fs.readFileSync('templates.bemhtml.js', 'utf8')).apply(bemjson);

fs.writeFileSync('page.html', html);
// '<div class="list"><div class="list__item">e1</div><div class="list__item">e2</div><div class="list__item">e3</div></div>'
Oleg2tor commented 8 years ago

@tadatuta Спасибо, то что нужно!