EN
blond
blond
25 декабря 2015

Привет, пришла и моя очередь рассказать о содеянном на минувшем хакатоне.

Основная мысль, которая преследует меня уже долгое время — возможность сборки БЭМ-проектов с помощью любого инструмента. И именно с этой идеей я пришёл в то раннее утро субботы агитировать собравшихся присоединиться ко мне, в надежде немного приблизить неизбежное будущее, в котором нет ENB.

Несмотря на невнятную речь, ко мне присоединились очень крутые ребята, без которых мы бы не продвинулись так далеко: @arikon, @zxqfox, @awinogradov, спасибо вам огромное!

Ставь задачу правильно

Утверждение «сборка БЭМ-проектов с помощью любого инструмента» звучит слишком абстрактно.

В двухдневный формат хакатона такая задача совсем не укладывалась. Надо было сформулировать что-то более конкретное. Поэтому мы решили, что критерием успеха будет сборка project-stub с помощью gulp.

Сам gulp был выбран практически случайно. Важно было доказать гипотезу о сборке с помощью любого инструмента. На эту роль gulp подходит как нельзя лучше: он популярен, прост, да и ребята из соседней команды уже решили делать сборку с помощью webpack.

Готовь сани летом

На самом деле основная работа была сделана заранее.

Специфика сборки БЭМ проектов заключается в организации уровней переопределения и использовании зависимостей блоков. Подробнее об этом можно почитать на bem.info.

Необходимость модульной сборки была сформулирована уже давно. На прошлогоднем хакатоне мы решили задачу интроспекции уровней — bem-walk.

Кроме того, к этому хакатону я написал прототип модуля для работы с зависимостями блоков — bem-deps.

Работа оказалась проделанной не зря. Модуль для работы с зависимостями пригодился не только нам, но и команде, занимающейся сборкой с помощью webpack. А интроспекция и вовсе оказалась нужна каждой команде.

Результаты

Проект: @bem/gulp.

Сборка project-stub: ветка feature/gulp

Ничто не опишет проект лучше, чем его API. Поэтому без слов пример того, что у нас получилось.

import gulp from 'gulp';
import bem from '@bem/gulp';
import concat from 'gulp-concat';
import merge from 'gulp-merge';
import bemhtml from 'gulp-bemhtml';
import stylus from 'gulp-stylus';
import postcss from 'gulp-postcss';
import postcssUrl from 'postcss-url';

// Создаём хелпер для сборки проекта
var project = bem({
    bemconfig: {
        /* загружаем информацию об уровнях с помощью `bem-config` */ 
    }
});

// Создаём хелпер для сборки бандла
var bundle = project.bundle({
    path: 'desktop.bundles/index',
    declPath: 'index.bemdecl.js'
});

gulp.task('css', function () {
    return bundle.src({tech: 'css', extensions: ['.css', '.styl']})
        .pipe(stylus())            
        .pipe(postcss([
            postcssUrl({ url: 'inline' })            
        ]))
        .pipe(concat(`${bundle.name()}.css`))
        .pipe(gulp.dest('desktop.bundles/index'));
});

gulp.task('js', function () {
    return
        merge(
            gulp.src(require.resolve('ym')),
            bundle.src({ tech: 'js', extensions: ['.js', '.vanilla.js', '.browser.js'] })
        )
        .pipe(concat(`${bundle.name()}.js`))
        .pipe(gulp.dest('desktop.bundles/index'));
});

gulp.task('bemhtml', function () {
    return bundle.src({ tech: 'bemhtml.js', extensions: ['.bemhtml.js', '.bemhtml'] })
        .pipe(concat(`${bundle.name()}.bemhtml.js`))            
        .pipe(bemhtml())
        .pipe(gulp.dest('desktop.bundles/index'));
});

gulp.task('build', gulp.series('css', 'js', 'bemhtml'));
gulp.task('default', gulp.series('build'));

По скорости в текущем состоянии сборка project-stub оказалась соизмеримой со сборкой на стеке ENB.

Что дальше?

Вначале мы приведём код в человеческий вид, покроем тестами и напишем примеры использования с минимальной документацией.

Мы уже получили массу пожеланий и предложений, которые обязательно учтём.

Как только всё будет готово, обязательно расскажем вам. А самое главное — будем внедрять в реальные проекты и реагировать на фидбэк.

Общие модули bem-walk и bem-deps оказались универсальными, и в каком-то смысле уже проверенными в бою. Поэтому, кроме использования их для сборки на gulp и webpack, мы планируем внедрить их в ENB.

Дальше можно будет исходить из потребностей, оптимизировать работу для больших проектов и реализовывать дополнительные плагины, которых будет не хватать.

Присылайте свои идеи и задавайте вопросы на форуме или в ишьюсах к репозиториям из организации gulp-bem.

Спасибо за внимание!

voischev
#voischev
25 декабря 2015

Красиво! :+1:

cyberS7
#cyberS7
4 апреля 2016

это 100% аналог project-stub? То есть я могу все также создавать папки с файлами, создавать файлы bemhtml, bemjson, styl, использовать i-bem, bem-components?

tadatuta
#tadatuta
4 апреля 2016

@cyberS7 да, в ветке https://github.com/bem/project-stub/tree/preparing-for-master обновление этой истории. планируем вскоре влить ее в основную ветку, но уже сейчас можно пользоваться.

cyberS7
#cyberS7
4 апреля 2016

@tadatuta благодарю, осталось только документацию переписать)


А как на счет поддержки bem-components в этой сборке?

Seredinof
#Seredinof
11 апреля 2016

"По скорости в текущем состоянии сборка project-stub оказалась соизмеримой со сборкой на стеке ENB"

С последними правками https://github.com/bem/project-stub/tree/preparing-for-master есть ли изменения в скорости сборки, по сравнению со стеком ENB?

tadatuta
#tadatuta
11 апреля 2016

@Seredinof эти правки пока были не про скорость, а скорее про причесывание и выравнивание поведения с версией на ENB.
Над скоростью работа планируется, когда будут результаты, мы обязательно напишем на форум.