# Принципы разработки БЭМ-библиотек

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

#### Открытый исходный код

Разработка библиотеки ведется на GitHub, где доступны все задачи, планы и сроки. Любой разработчик может принять участие в работе над библиотекой: создать задачу с пожеланиями для команды или прислать пулреквест.

#### Простота использования

Библиотека должна быть максимально простой. Откажитесь от всего, что может расцениваться или использоваться неоднозначно.

#### Минимализм

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

#### Покрытие тестами

Код библиотеки должен быть на 100% покрыт тестами. Это гарантирует меньшее число ошибок и экономию времени на поддержку в будущем. Код не считается законченным и стабильным, пока он не покрыт тестами. Пулреквесты без добавления или изменения тестов не принимаются.

#### Единообразие

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

#### Разделение на приватный и публичный API

Приватный API блока не должен использоваться вне этого блока.

Публичный API следует делать минималистичным, не предоставляя ничего лишнего. Обязательно указывайте в документации возможные способы его использования: в BEMJSON, JavaScript или обоими способами. Стабильность публичного API гарантируется соблюдением правил [семантического версионирования](http://semver.org).

#### Тонкая настройка пользователем

В процессе разработки заранее продумывайте возможность гибкого до- и переопределения  шаблонов, стилей и скриптов на стороне пользователя. [Например](https://github.com/bem/bem-components/blob/v2/common.blocks/button/button.bemhtml#L10), возможность указать HTML-тег во входном BEMJSON, переопределив шаблон.

#### Поддержка нескольких тем

Библиотека должна поддерживать несколько тем. Это позволит корректно создавать правила для каждой темы, а также избежать конфликтов при создании новой темы.
Сейчас основная тема БЭМ-библиотек — islands, в ней выполнен новый дизайн сервисов Яндекса. Реализация нескольких тем внутри одной библиотеки представлена в bem-components, где вместе с islands есть дополнительная тема simple.

#### Явное лучше неявного (в JavaScript API)

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

#### Сокращения в BEMJSON API

Явное лучше неявного, но в некоторых случаях в API допустимо использовать сокращения. Произвольные куски BEMJSON можно передавать только там, где это действительно необходимо — например, если сущность по своей семантике является оберткой или контейнером. Для сложных блоков, где генерация содержимого и есть внутренний API, нужно создавать сокращения, опуская поле content. Это уменьшит объем входного BEMJSON и позволит безболезненно менять внутреннее устройство сложных блоков.

#### Явные умолчания

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

#### Обработка ошибок

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

#### Предметная область БЭМ

Все, что может выражаться через БЭМ-сущность, должно через нее выражаться.

#### БЭМ-события vs. события на изменение модификаторов

Не нужно создавать БЭМ-событие или подписываться на него, если есть возможность работать с событием на изменение модификатора.

#### Модификаторы vs. специализированные поля

Модификатор — это заранее известный набор положений или состояний. Специализированное поле — заранее неизвестный набор вариативных значений.
Все, что может быть выражено в виде конечного набора значений, нужно реализовывать модификатором. Где это невозможно, используйте специализированные поля.

#### Композиция vs. наследование vs. делегирование

Используйте ООП только там, где это оправдано. В остальных случаях следует применять миксы, делегирование и композицию.

#### Иерархия блоков

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

#### Оптимизация на уровне блока

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

#### Автоматизация рутинных процессов

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

#### Мобильные платформы без адаптивной верстки

Библиотека должна поддерживать мобильные платформы. Использовать адаптивную верстку не рекомендуется. Библиотека должна работать во всех браузерах, поддержку которых вы заявляете: допускаются деградации только стилевого оформления компонентов, но не их функциональности. Код на уровне common и desktop должен работать на тач-устройствах. Для примера ознакомьтесь со [списком поддерживаемых браузеров](https://ru.bem.info/libs/bem-components/current/#Поддерживаемые-браузеры) библиотеки [bem-components](https://ru.bem.info/libs/bem-components/).

#### Доступность

Компоненты библиотеки должны быть доступны для чтения программами экранного доступа, но расширять для этого публичный API не следует. Выставление всех необходимых ARIA-атрибутов реализуется на уровне шаблонов и скриптов.

#### Bleeding edge

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