Upload
yandex
View
408
Download
9
Embed Size (px)
DESCRIPTION
bem-tools — это набор инструментов для работы с файлами по БЭМ-методологии. Он позволяет создавать сущности, собирать финальный рантайм, работать с build-декларациями, собирать весь проект командой bem make или запускать сервер разработки на дереве исходников проекта (используя bem server). Один из самых популярных способов расширения возможностей bem-tools — написание модулей технологий. В докладе речь пойдет о том, зачем их писать и как убедиться в том, что все сделано правильно.
Citation preview
BEMup в Питере, 29 ноября 2013
Написание технологий для bem-tools
Татаринцев Сергей, Яндекс
bem-tools
!2
bem-tools
• сборщик BEM-проектов
!2
bem-tools
• сборщик BEM-проектов• расширяемый при помощи:
!2
bem-tools
• сборщик BEM-проектов• расширяемый при помощи:
• узлов сборки
!2
bem-tools
• сборщик BEM-проектов• расширяемый при помощи:
• узлов сборки• подкоманд (в 1.0.0)
!2
bem-tools
• сборщик BEM-проектов• расширяемый при помощи:
• узлов сборки• подкоманд (в 1.0.0)• модулей технологий
!2
Ссылки
!3
Ссылки
• документация: ru.bem.info/tools/bem• принимаем пожелания: github.com/bem/bem-tools/issues
!3
Модули технологий
!4
Модули технологий
• технологии — средства описания БЭМ-сущностей
!4
Модули технологий
• технологии — средства описания БЭМ-сущностей• модуль технологии — Node.JS модуль для сборки файлов
технологий
!4
Пример
!5
Пример
• Блок описан в технологиях css, js, bemhtml /block
block.css
block.js
block.bemhtml
!5
Пример
• Блок описан в технологиях css, js, bemhtml /block
block.css
block.js
block.bemhtml
• css страницы собирается модулем технологии css
!5
bemdecl css deps.js dir docs examples ie.css js js-i level level-proto project tech-docs
Технологии в bem-tools
!6
bemhtml bemtree html vanilla.js node.js browser.js browser.js+bemhtml
Технологии в bem-core
!7
Маловато будет!8
На примере CoffeeScript
Пишем свою технологию
Назначение модулей технологий
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)bem create —l common.block --block my-block —T css
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)bem create —l common.block --block my-block —T css
• сборка результатов (bem build)
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)bem create —l common.block --block my-block —T css
• сборка результатов (bem build)• исходные файлы — внутри блоков
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)bem create —l common.block --block my-block —T css
• сборка результатов (bem build)• исходные файлы — внутри блоков• блоки — внутри уровней переопределения
!10
Назначение модулей технологий
• создание файлов по шаблону (bem create)bem create —l common.block --block my-block —T css
• сборка результатов (bem build)• исходные файлы — внутри блоков• блоки — внутри уровней переопределения• результат — в бандл
!10
Результат = префикс + суффиксы + декларация + уровни
Сборка
!11
/path/to/some/file.tech.js !
Префикс и суффикс
!12
Префикс
Суффикс
Декларация
!13
Декларация
• список сущностей для сборки
!13
Декларация
• список сущностей для сборки• строится из bemjson.js бандлов и deps.js блоков
!13
Декларация - пример
!14
bemjson block1.deps.js({ block: 'page', content: [ {block: 'block1'} ] })
({ mustDeps: [ {block: 'block2'} ] })
[ {block: 'page'}, {block: 'block2'}, {block: 'block1'} ]
Декларация
Уровни переопределения
!15
Уровни переопределения
• папки, содержащие bem-сущности
!15
Уровни переопределения
• папки, содержащие bem-сущности• каждая следующая переопределяет предыдущую
!15
Уровни переопределения
• папки, содержащие bem-сущности• каждая следующая переопределяет предыдущую• примеры:
• common • desktop • touch
!15
Let’s code!
• используется вторая версия API • techMixin будет «примешан» к классу TechV2
!exports.API_VER = 2;!exports.techMixin = {! //здесь будет код!};
Заготовка
!17
{! "что": ["из чего", "из чего еще", …],! "что еще": […],! …!}
getBuildSuffixesMap
!18
Собираем js из coffee и js
exports.API_VER = 2;!exports.techMixin = {! getBuildSuffixesMap: function() {! return {"js": ["coffee", "js"]};! }!}
Наш случай
!19
getBuildResults(decl, levels, output, opts);
Процесс сборки
!20
Декларация
Уровни
Префикс результата
Опции
getBuildResults, по умолчанию
!21
getBuildResults, по умолчанию
• сканирует все уровни переопределения
!21
getBuildResults, по умолчанию
• сканирует все уровни переопределения• собирает исходные файлы для сущностей из декларации
!21
getBuildResults, по умолчанию
• сканирует все уровни переопределения• собирает исходные файлы для сущностей из декларации• проверяет, нужна ли пересборка
!21
getBuildResults, по умолчанию
• сканирует все уровни переопределения• собирает исходные файлы для сущностей из декларации• проверяет, нужна ли пересборка• вызывает getBuildResult для каждого выходного файла
!21
Пример
• уровни: common.blocks, desktop.blocks • декларация: [{block: "block1"}, {block: "block2"}] • build suffixes map: {js: ["coffee", "js"]} • файлы: common.blocks/
block1/
block1.bemhtml
block1.css
block1.coffee
block2/
block2.bemhtml
block2.js
desktop.blocks/
block1/
block1.coffee
block1.css
block2/
block2.js
!22
Пример
• уровни: common.blocks, desktop.blocks • декларация: [{block: "block1"}, {block: "block2"}] • build suffixes map: {js: ["coffee", "js"]} • файлы: common.blocks/
block1/
block1.bemhtml
block1.css
block1.coffee
block2/
block2.bemhtml
block2.js
desktop.blocks/
block1/
block1.coffee
block1.css
block2/
block2.js
!23
getBuildResult(files, suffix, output, opts);
Процесс сборки
!24
Исходные файлы
Выходной суффикс
Префикс выходного файла
Опции
getBuildResult(files, suffix, output, opts);
Процесс сборки
!25
Для каждого файла
getBuildResultChunk(relPath, path, suffix);
getBuildResultChunk(relPath, path, suffix);
Процесс сборки
!26
относительный путь
абсолютный путь
исходный суффикс
Пример
• уровни: common.blocks, desktop.blocks • декларация: [{block: "block1"}, {block: «block2"}] • выходоной префикс: desktop.bundles/example/example • build suffixes map: {js: ["coffee", "js"]} • файлы: common.blocks/
block1/
block1.bemhtml
block1.css
block1.coffee block2/
block2.bemhtml
block2.js desktop.blocks/
block1/
block1.coffee block1.css
block2/
block2.js
!27
getBuildResultChunk
getBuildResultChunk
getBuildResultChunk
getBuildResultChunk
desktop.bundles/example/example.js
Полный процесс
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)• сканируются уровни
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)• сканируются уровни• находятся все исходные файлы БЭМ-сущностей из декларации
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)• сканируются уровни• находятся все исходные файлы БЭМ-сущностей из декларации
• для каждого выходного файла зовется getBuildResult(files, suffix, output, opts)
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)• сканируются уровни• находятся все исходные файлы БЭМ-сущностей из декларации
• для каждого выходного файла зовется getBuildResult(files, suffix, output, opts)
• для кажого исходного файла зовется getBuildResultChunk(relPath, path, suffix)
!28
Полный процесс
• вызывается getBuildResults(decl, levels, output, opts)• сканируются уровни• находятся все исходные файлы БЭМ-сущностей из декларации
• для каждого выходного файла зовется getBuildResult(files, suffix, output, opts)
• для кажого исходного файла зовется getBuildResultChunk(relPath, path, suffix)
• результаты склеиваются и записываются на диск
!28
var fs = require('fs'),! coffee = require('coffee-script');!!exports.API_VER = 2;!exports.techMixin = {! getBuildSuffixesMap: function() {! return {'js': ['coffee', 'js']};! },!! getBuildResultChunk: function(relPath, path, suffix) {! var content = fs.readFileSync(path);! if (suffix === 'coffee') {! return coffee.compile(content);! }! return content;! }!};
Завершим код
!29
Подключение
В .bem/levels/blocks.js добавить полный путь к модулю в getTechs:
exports.getTechs = function() {! return {! …! "coffee+js": "/path/to/tech/module.js"! };!};
На уровне блоков
!31
Добавить в BundleNode#getTechs
registry.decl('BundleNode', {! getTechs: function() {! return [! ...! 'coffee+js',! ...! ];! }!});
В make.js
!32
Указать в make.js как технология должна оптимизироваться
registry.decl('BundleNode', {! ! ...!! 'create-coffee+js-optimizer-node': function() {! this['create-js-optimizer-node'].apply(this, arguments);! }!});
Минификация (в 0.6.x и 0.7.x)
!33
Минификация (в 1.0.0)
!34
Минификация (в 1.0.0)
• убедиться, что технология min.js включена в сборку
!34
Минификация (в 1.0.0)
• убедиться, что технология min.js включена в сборку– зарегистрирована на уровне бандлов
!34
Минификация (в 1.0.0)
• убедиться, что технология min.js включена в сборку– зарегистрирована на уровне бандлов– добавлена в BundleNode::getTechs
!34
Что дальше?
Не рассказано
• создание шаблонов • bem create в процессе сборки • тестирование • суммарные технологии
!36
Ссылки
• Документация — bit.ly/techmod-doc • Технологии bem-tools — bit.ly/tech-bemtools • Технологии bem-core — bit.ly/tech-bemcore
!37
Старший разработчик
Спасибо
Татаринцев Сергей
@SevInf