Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
646 lines (502 sloc) 24.8 KB

bem-tools-create

С помошью bem-tools-create можно создавать БЭМ-сущности в файловой системе:

  • блоки
  • элементы
  • модификаторы блока или элемента

Технологии

БЭМ-сущность создаётся в указанных технологиях и технологиях по умолчанию, которые можно указать в файле конфигурации. Можно отменить все технологии по умолчанию или только некоторые из них.

Если технологий по умолчанию нет — не создаётся ничего.

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

Уровни

Уровень для создания БЭМ-сущности ищется в указанном порядке:

  1. Пытаемся определить текущий уровень, поднимаясь вверх по файловой системе и сравнивая директорию с уровнями, заданными в файле конфигурации
  2. Если не получилось, то используем уровни по умолчанию, если они есть
  3. Иначе используем текущую директорию, как уровень для создания блока

CLI

npm install -g bem-tools/bem-tools-core bem-tools/bem-tools-create

Установите bem-tools-core и bem-tools-create, чтобы использовать bem create в командной строке.

Создание блока

Создание блока с технологиями умолчанию

bem create my-block

Создаёт блок my-block. Если технологий по умолчанию нет — не создаёт ничего.

Создание блока с одной технологией

bem create my-block.css

или

bem create my-block -t css

Создаёт блок my-block в технологии cssтехнологиях по умолчанию, если они есть).

Создание блока с несколькими технологиями

bem create my-block.{css,js}

или

bem create my-block -t css -t js

Создаёт блок my-block в технологиях css и jsтехнологиях по умолчанию, если они есть).

Создание блока только с указанными технологиями

bem create my-block -T css -T js

Создаёт блок my-block только в технологиях css и js (игнорируя технологии по умолчанию).

Создание блока без указанных технологий

bem create my-block.js -n css

Создаёт блок в технологии jsтехнологиях по умолчанию, если они есть), исключая технологию css.

Создание блока на уровне

bem create level/my-block
bem create my-block -l level

Создаёт блок my-block в технологиях по умолчанию на уровне level.

Имя уровня может быть как полным путём к директории уровня, так и сокращённым. В случае использования сокращённых путей, они резолвятся относительно .bemrc. Для этого в проектном .bemrc задаётся параметр root: true и определются уровни.

Создание элемента

bem create my-block__elem

или

bem create -b my-block -e elem

Создаёт элемент elem блока my-block в технологиях по умолчанию.

Остальные ключи командной строки аналогичны созданию блока.

Создание элемента в текущем блоке (TODO: не работает)

bem create __elem

или

bem create -e elem

Создаёт элемент elem в текущем блоке в технологиях по умолчанию. Если технологий по умолчанию нет — не создаёт ничего.

Текущий блок ищется вверх от текущей директории по файловой системе. Если блок не найден — показывается ошибка.

Создание модификатора

Создание модификатора блока

bem create my-block_mod
bem create my-block_mod_val

или

bem create -b my-block -m mod
bem create -b my-block -m mod -v val

Создаёт модификатор mod (со значением val, если указано) блока my-block в технологиях по умолчанию. Если технологий по умолчанию нет — не создаёт ничего.

Остальные ключи командной строки аналогичны созданию блока.

Создание модификатора элемента

bem create my-block__elem_mod
bem create my-block__elem_mod_val

или

bem create -b my-block -e elem -m mod
bem create -b my-block -e elem -m mod -v val

Создаёт модификатор mod (со значением val, если указано) элемента elem блока my-block в технологиях по умолчанию.

Создание модификатора в текущем блоке или элементе (TODO: не работает)

bem create _mod
bem create _mod_val

или

bem create -m mod
bem create -m mod -v val

Создаёт модификатор mod (со значением val, если указано) в текущем блоке или элементе в технологиях по умолчанию.

Текущий блок или элемент ищется вверх от текущей директории по файловой системе. Если блок или элемент не найден — показывается ошибка.

Перезаписывать существующие файлы

По умолчанию существующие файлы не перетираются и выдаётся сообщение о конфликтах. При этом работа команды не прерывается, недостающие файлы создаются. Для модификации этого поведения и принудительной перезаписи существующих файлов можно использовать опцию -f

bem create -f -b bl1

В результате выполнения указанной команды существующие файлы будут перезаписаны без предупреждений.

Задание содержимого файлов

При необходимости можно задать содержимое создаваемых файлов не из шаблонов, а вручную из командной строки. Для этого необходимо использовать опцию -c

bem create -b bl1 -T css -c '.bl1
{
    display: none;
}'

Если опция -c будет использована без значения (содержимое не задано), то утилита будет ожидать поступления данных на сдандартный ввод, что позволяет использовать pipe-режим

cat source_file.css | bem create -b bl1 -T css -c

При этом все создаваемые командой файлы (например, файлы разных технологий создаваемых одновременно или блоки разных уровней по умолчанию) получат указанное содержимое. По этой причине полезно использовать эту опцию совместно с -T и явным указанием уровня.

JavaScript API

var create = require('bem-tools-create');

// Создаёт блок `b1` в технологиях `css` и `js` (и технологиях по умолчанию)
// на уровне `level1`
create('level1/b1.{css,js}');

// Создаёт элемент `e1` блока `b1` в технологиях `css` и `js`
// (и технологиях по умолчанию) на уровнях по умолчанию или текущей директории
create('b1__e1.{css,js}');

// Создаёт указанные БЭМ-сущности на уровнях `level1` и `level2` в технологиях
// `css`, `js`, `bemhtml.js` (и технологиях по умолчанию)
create(
    [
        { block: 'b1' },
        { block: 'b1', modName: 'm1', modVal: true },
        { block: 'b1', elem: 'e2' },
        { block: 'b1', elem: 'e2', modName: 'elemMod', modVal: true },
        { block: 'b1', modName: 'm1', modVal: 'v1' }
    ],
    ['level1', 'level2'],
    ['css', 'js', 'bemhtml.js']
);

// Создаёт `b1` только в технологии `jsx` на уровне `level1`, игнорируя переданные
// в третьем параметры технологии и технологии по умолчанию
create(
    ['b1'],
    ['level1'],
    ['css', 'js', 'bemhtml.js'],
    {
        onlyTech: ['jsx'],

        excludeTech: ['js'],

        fileContent: ['Some file content']

        forceRewrite: true

        // настройки, которые передаются в bem-config при инициализации
        // см. https://ru.bem.info/toolbox/sdk/bem-config/
    }
);

Настройка

Используйте bem-config для настройки bem-tools-create.

Минимальный пример файла конфигурации проекта

module.exports = {
    root: true,

    levels: [
        { path: 'blocks' },
        { path: 'bundles' }
    ],

    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    // Настройки уровней, которые используются только
                    // в `bem-tools-create`
                    levels: {
                        blocks: {
                            // Уровень по умолчанию, создаём сущности тут,
                            // если уровень не задан
                            default: true,

                            // Технологии по умолчанию для создания блоков на уровне
                            techs: ['css', 'js'],
                        }
                    }
                }
            }
        }
    }
}

Расширенный пример файла конфигурации

module.exports = {
    root: true,

    levels: [
        {
            path: 'level1',
            // Смотри https://ru.bem.info/toolbox/sdk/bem-fs-scheme/
            scheme: 'nested',
            schemeOptions: 'react'

            // Смотри https://ru.bem.info/toolbox/sdk/bem-naming/#В-стиле-Гарри-Робертса
            naming: 'two-dashes'
        },

        {
            path: 'level2'
            // Для уровня используются настройки по умолчанию.
            //
            // Задаём его в файле конфигурации для возможности создавать
            // в нём блоки, указывая краткое имя уровня (`level2`)
        },

        {
            path: 'path/to/level2',
            // Значение по умолчанию, можно не указывать
            scheme: 'nested',

            // Смотри https://ru.bem.info/toolbox/sdk/bem-naming/#Собственный-стиль
            naming: {
                delims: {
                    elem: '-',
                    mod: { name: '--', val: '_' }
                },
                wordPattern: '[a-zA-Z0-9]+'
            }
        }
    ],

    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    // Технологии по умолчанию для создания блоков. Используются
                    // для всех уровней, у которых нет своего определения технологий
                    techs: ['css', 'js'],

                    templateFolder: '.bem/templates',

                    templates: {
                        'js-ymodules': '.bem/templates/js'
                    },

                    // маппинг технологий, если нужно использовать один шаблон для
                    // нескольких технологий
                    techsTemplates: {
                        js: 'js-ymodules',
                        'bemtree.js': 'bemhtml.js'
                    },

                    // Настройки уровней, которые используются только
                    // в `bem-tools-create`
                    levels: {
                        level1: {
                            // Уровень по умолчанию, создаём сущности тут,
                            // если уровень не задан
                            default: true
                        },

                        'path/to/level2': {
                            // На этом уровне по умолчанию создаём только
                            // технологию 'bemhtml.js'
                            techs: ['bemhtml.js'],

                            // Уровней по умолчанию может быть несколько
                            default: true
                        }
                    }
                }
            }
        }
    }
}

Рассмотрим по отдельности, что можно задать в .bemrc.

Настройки уровня

В корне конфигурационного файла можно задать схему именования БЭМ-сущностей (см. соглашение по именованию) и схему файловой структруры (значение по умолчанию nested).

module.exports = {
    levels: [
        {
            path: 'level1',
            // Смотри https://ru.bem.info/toolbox/sdk/bem-fs-scheme/
            scheme: 'flat',

            // Смотри https://ru.bem.info/toolbox/sdk/bem-naming/#В-стиле-Гарри-Робертса
            naming: 'two-dashes'
        },

        {
            path: 'level2'
            // Для уровня используются настройки по умолчанию.
            //
            // Задаём его в файле конфигурации для возможности создавать
            // в нём блоки, указывая краткое имя уровня (`level2`)
        },

        {
            path: 'path/to/level2',
            // Значение по умолчанию, можно не указывать
            scheme: 'nested',

            // Смотри https://ru.bem.info/toolbox/sdk/bem-naming/#Собственный-стиль
            naming: {
                delims: {
                    elem: '-',
                    mod: { name: '--', val: '_' }
                },
                wordPattern: '[a-zA-Z0-9]+'
            }
        }
    ]
}

Лучше в .bemrc перечислять все проектные уровни, даже если для них не задаются никакие специальные настройки. Это позволит создавать блоки на уровне, указывая только его краткое имя (ключ).

В настройках плагина можно указать секцию levels, где задать настройки уровней, которые используются только модулем bem-tools-create.

К таким настройкам относятся уровни по умолчанию и технологии по умолчанию.

module.exports = {
    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    // Настройки уровней, которые используются только
                    // в `bem-tools-create`
                    levels: {
                        level1: {
                            // Уровень по умолчанию, создаём сущности тут,
                            // если уровень не задан
                            default: true
                        },

                        'path/to/level2': {
                            // На этом уровне по умолчанию создаём только
                            // технологию 'bemhtml.js'
                            techs: ['bemhtml.js'],

                            // Уровней по умолчанию может быть несколько
                            default: true
                        }
                    }
                }
            }
        }
    }
}

Уровни по умолчанию

Уровню в настройках плагина можно задать значение default: true и этот уровень будет использоваться для создания БЭМ-сущностей в случае, когда уровень не указан явно и нет возможности определить текущую сущность из контекста по файловой системе.

Уровней по умолчанию может быть несколько.

module.exports = {
    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    // Настройки уровней, которые используются только
                    // в `bem-tools-create`
                    levels: {
                        level1: {
                            // Уровень по умолчанию, создаём сущности тут,
                            // если уровень не задан. Уровней по умолчанию
                            // может быть несколько
                            default: true
                        }
                    }
                }
            }
        }
    }
}

Технологии по умолчанию

В настройках плагина можно задать технологии по умолчанию. Они используются всегда при создании всех БЭМ-сущностей, кроме случаев, когда явно выбран вариант создания только этой технологии (опция -T в командной строке или onlyTech в API).

module.exports = {
    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    // Технологии по умолчанию для создания блоков. Используются
                    // для всех уровней, у которых нет своего определения технологий
                    techs: ['css', 'js']
                }
            }
        }
    }
}

Технологии по умолчанию для уровня

Уровню в настройках плагина можно задать свои Технологии по умолчанию, которые будут использоваться для этого уровня, перекрывая глобальную настройку.

module.exports = {
    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    levels: {
                        'path/to/level2': {
                            // На этом уровне по умолчанию создаём только
                            // технологию 'bemhtml.js'
                            techs: ['bemhtml.js']
                        }
                    }
                }
            }
        }
    }
}

Шаблоны технологий

При создании файла технологии может применяться шаблон.

Шаблон это модуль, принимающий на вход БЭМ-сущность и схему именования, и возвращающий содержимое файла технологии.

Пример шаблона технологии CSS:

'use strict';

var EOL = require('os').EOL;

module.exports = function(entity, naming) {
    return [
        '.' + naming.stringify(entity) + ' {',
        '    ',
        '}',
        ''
    ].join(EOL);
};

Для часто используемых технологий в bem-tools-create есть шаблоны по умолчанию.

Есть возможность создавать свои шаблоны и указывать их в файле конфигурации.

Настройка шаблонов технологий

В настройках плагина можно задать свои шаблоны:

  • templateFolder — директория с шаблонами, все js-файлы в этой директории считаются шаблонами технологий, имя которых соответствует имени файла без расширения
  • templates — возможность задать шаблоны для определённых технологий в дополнение к templateFolder
  • techsTemplates — маппинг технологий, если нужно использовать один шаблон для нескольких технологий
module.exports = {
    modules: {
        'bem-tools': {
            plugins: {
                create: {
                    templateFolder: '.bem/templates',

                    templates: {
                        'js-ymodules': '.bem/templates/js'
                    },

                    // маппинг технологий, если нужно использовать один шаблон для
                    // нескольких технологий
                    techsTemplates: {
                        js: 'js-ymodules',
                        'bemtree.js': 'bemhtml.js'
                    }
                }
            }
        }
    }
}