Спецификация DEPS
Введение
DEPS — технология для описания зависимостей в БЭМ.
DEPS-сущность — сущность, определяющая зависимость между БЭМ-сущностями.
Зависимости описываются в виде JavaScript-объекта в файлах с расширением .deps.js
.
Полная запись DEPS-сущности имеет следующий вид:
/* DEPS-сущность */
({
block: 'block-name',
elem: 'elem-name',
mod: 'modName',
val: 'modValue',
tech: 'techName',
shouldDeps: [ /* БЭМ-сущность */ ],
mustDeps: [ /* БЭМ-сущность */ ],
noDeps: [ /* БЭМ-сущность */ ]
})
Примечание Все поля являются опциональными.
Используемые обозначения
Для короткой записи зависимостей в комментариях используются следующие условные обозначения:
/* b1 → b2 */
— блокb1
зависит от блокаb2
(shouldDeps
);/* b1 ⇒ b2 */
— блокb1
зависит от блокаb2
(mustDeps
);/* b1 → b1__e1 */
— блокb1
зависит от своего элементаb1__e1
;/* b1 → b1_m1_v1 */
— блокb1
зависит от своего модификатораb1_m1_v1
;/* b1 → b1__e1_m1_v1 */
— блокb1
зависит от модификатора своего элементаb1__e1_m1_v1
;/* b1.js → b2.bemhtml */
— блокb1
в технологии реализации JavaScript зависит от блокаb2
в технологии реализации BEMHTML.
Синтаксис DEPS
Представить DEPS-сущность в .deps.js
-файле можно используя:
Круглые скобки
()
.
({
/* DEPS-сущность */
})
Литерал массива
[]
.
[{
/* DEPS-сущность */
},
{
/* DEPS-сущность */
}]
Поля DEPS-сущности
Можно разделить на следующие группы:
Определяющие БЭМ-сущность:
Определяющее технологию реализации БЭМ-сущности:
Определяющие зависимость:
Примечание Кроме описанных полей, вы можете использовать синтаксический сахар для повышения читаемости кода.
Поля определяющие БЭМ-сущность
Указывают для какой БЭМ-сущности необходимо подключить зависимость. Они являются опциональными и могут быть восстановлены из контекста по имени файла.
Поэтому записи для файла b1__e1_m1_v1.deps.js
эквивалентны:
/* b1__e1_m1_v1 → b2 */
({
block: 'b1',
elem: 'e1',
mod: 'm1',
val: 'v1',
shouldDeps: { block: 'b2' }
})
/* b1__e1_m1_v1 → b2 */
({
shouldDeps: { block: 'b2' }
})
block
Поле block
задает имя блока.
Тип: String
.
// Блок b1
({
block: 'b1'
})
elem
Поле elem
задает имя элемента.
Тип: String
.
// Элемент b1__e1
({
block: 'b1',
elem: 'e1'
})
mod
Поле mod
задает имя модификатора блока или элемента.
Тип: String
.
// Модификатор блока b1_m1 со значением true
({
block: 'b1',
mod: 'm1'
})
// Модификатор элемента b1__e1_m1 со значением true
({
block: 'b1',
elem: 'e1',
mod: 'm1'
})
val
Поле val
задает значение модификатора. Если val
не указано, считается что значение модификатора равно true
.
Тип: String
, Boolean
.
Ниже приведены примеры с указанием типа принимаемых данных:
Строка (
String
).// Модификатор b1_m1_v1 со значением v1 ({ block: 'b1', mod: 'm1', val: 'v1' })
Булев, Логический тип (
Boolean
).// Модификатор b1_m1 со значением true ({ block: 'b1', mod: 'm1', val: true })
Поле определяющее технологию реализации БЭМ-сущности
Поле tech
указывает, для какой технологии реализации необходимо подключить зависимость. В случае, когда tech
не указано, зависимость считается общей и относится ко всем технологиям.
Подключение зависимостей по технологии используется, например, для того, чтобы собрать в клиентский JavaScript-бандл шаблоны только тех блоков, которые будут использованы в браузере. При такой схеме часть шаблонизации происходит на стороне сервера и, следовательно, некоторые шаблоны на клиенте никогда не используются.
Тип: String
.
({
// Блок b1 в технологии JavaScript
block: 'b1',
tech: 'js'
})
Поля определяющие зависимость
Поля shouldDeps
, mustDeps
определяют зависимость, а noDeps
отменяет
shouldDeps
Поле shouldDeps
определяет зависимости, порядок подключения которых не важен.
Тип: Object[]
.
/* b1 → БЭМ-сущность */
({
block: 'b1',
shouldDeps: [
{ /* БЭМ-сущность */ }
]
})
mustDeps
Поле mustDeps
определяет зависимости, которые попадут в результаты сборки до кода БЭМ-сущности, в которой эти зависимости объявляются.
Тип: Object[]
.
/* b1 ⇒ БЭМ-сущность */
({
block: 'b1',
mustDeps: [
{ /* БЭМ-сущность */ }
]
})
noDeps
Поле noDeps
отменяет существующие зависимости, объявленные на других уровнях переопределения.
Тип: Object[]
.
/* common.blocks
b1 → БЭМ-сущность */
({
block: 'b1',
shouldDeps: [
{ /* БЭМ-сущность */ }
]
})
/* desktop.blocks */
({
block: 'b1',
noDeps: [
{ /* БЭМ-сущность */ }
]
})
В данном примере на уровне common.blocks
по зависимостям подключается некая БЭМ-сущность, необходимая для реализации блока b1
. На уровне desktop.blocks
данная зависимость отменяется.
Синтаксический сахар
elem
Поле elem
в качестве значения также может принимать массив строк (String[]
):
// Элементы b1__e1 и b1__e2
({
block: 'b1',
elem: [
'e1',
'e2'
]
})
elems
Поле elems
задает имя элемента и раскрывается в shouldDeps
. Поэтому записи для файла b1.deps.js
равнозначны:
({
/* b1 → b1__e1; b1 → b1__e2 */
block: 'b1',
elems: [
'e1',
'e2'
]
})
({
/* b1 → b1__e1; b1 → b1__e2 */
block: 'b1',
shouldDeps: [
{
elem: [
'e1',
'e2'
]
}
]
})
Тип: String
, Object
, String[]
, Object[]
.
Ниже приведены примеры с указанием типа принимаемых данных:
String
./* b1 → b1__e1 */ ({ block: 'b1', elems: 'e1' })
Объект (
Object
)./* b1 → { ElemDepsEntity } */ ({ block: 'b1', elems: { /* { ElemDepsEntity } */ } })
Массив строк (
String[]
)./* b1 → b1__e1; b1 → b1__e2 */ ({ block: 'b1', elems: [ 'e1', 'e2' ] })
Массив объектов (
Object[]
)./* b1 → { ElemDepsEntity }; b1 → { ElemDepsEntity } */ ({ block: 'b1', elems: [ { /* { ElemDepsEntity } */ }, { /* { ElemDepsEntity } */ } ] })
ElemDepsEntity — это JavaScript-объект со следующими полями:
/* elemDepsEntity */
({
elem: 'elem-name',
mod: 'modName',
val: 'modValue',
tech: 'techName',
shouldDeps: [ /* БЭМ-сущность */ ],
mustDeps: [ /* БЭМ-сущность */ ],
noDeps: [ /* БЭМ-сущность */ ]
})
Примечание Поле
elem
является обязательным.
mods
Поле mods
задает имя и значение модификатора и раскрывается в shouldDeps
. Поэтому записи для файла b1.deps.js
равнозначны:
({
/* b1 → b1_m1_v1; b1 → b1_m1_v2 */
block: 'b1',
mods: { m1: [
'v1',
'v2'
]
}
})
({
/* b1 → b1_m1_v1; b1 → b1_m1_v2 */
block: 'b1',
shouldDeps: [
{
block: 'b1',
mod: 'm1',
val: 'v1'
},
{
block: 'b1',
mod: 'm1',
val: 'v2'
}
]
})
Тип: String[]
, Object
.
Ниже приведены примеры с указанием типа принимаемых данных:
Массив строк (
String[]
)./* b1 → b1_m1; b1 → b1_m2 */ ({ block: 'b1', mods: [ 'm1', 'm2' ] })
Объект, где значением свойства может быть:
Строка (
String
)./* b1 → b1_m1_v1 */ ({ block: 'b1', mods: { m1: 'v1' } })
Булев, Логический тип (
Boolean
)./* b1 → b1_m1 */ ({ block: 'b1', mods: { m1: true } })
Массив строк (
String[]
)./* b1 → b1_m1_v1; b1 → b1_m1_v2 */ ({ block: 'b1', mods: { m1: [ 'v1', 'v2' ] } })
shouldDeps, mustDeps, noDeps
Тип: String
, Object
, String[]
.
Ниже приведены примеры с указанием типа принимаемых данных:
Строка (
String
)./* b1 → b2 */ ({ block: 'b1', shouldDeps: 'b2' })
Объект (
Object
)./* b1 → БЭМ-сущность */ ({ block: 'b1', shouldDeps: { /* БЭМ-сущность */ } })
Массив строк (
String[]
)./* b1 → b2; b1 → b3 */ ({ block: 'b1', shouldDeps: [ 'b2', 'b3' ] })
Примеры деклараций
Подключение блока
b1 → b2
— блок b1
зависит от блока b2
.
Зависимость может быть объявлена в виде:
Массива объекта (
Object[]
)./* b1 → b2 */ ({ block: 'b1', shouldDeps: [ { block: 'b2' } ] })
Синтаксический сахар
Строки (
String
)./* b1 → b2 */ ({ block: 'b1', shouldDeps: 'b2' })
Объекта (
Object
)./* b1 → b2 */ ({ block: 'b1', shouldDeps: { block: 'b2' } })
Массива строк (
String[]
)./* b1 → b2 */ ({ block: 'b1', shouldDeps: [ 'b2' ] })
Подключение элемента
b1 → b1__e1
— блок b1
зависит от своего элемента b1__e1
.
Зависимость может быть объявлена в виде:
Массива объектов (
Object[]
)./* b1 → b1__e1 */ ({ block: 'b1', shouldDeps: [ { block: 'b1', elem: 'e1' } ] })
Синтаксический сахар
Строки (
String
)./* b1 → b1__e1 */ ({ block: 'b1', elems: 'e1' })
Объекта (
Object
)./* b1 → b1__e1 */ ({ block: 'b1', shouldDeps: { elem: 'e1' } })
/* b1 → b1__e1 */ ({ block: 'b1', elems: { elem: 'e1' } })
Массива строк (
String[]
)./* b1 → b1__e1 */ ({ block: 'b1', elems: [ 'e1' ] })
Массива объектов (
Object[]
)./* b1 → b1__e1 */ ({ block: 'b1', elems: [ { elem: 'e1' } ] })
Подключение булевого модификатора
b1 → b1_m1
— блок b1
зависит от своего булевого модификатора b1_m1
.
Зависимость может быть объявлена в виде:
Массива объектов (
Object[]
)./* b1 → b1_m1 */ ({ block: 'b1', shouldDeps: [ { block: 'b1', mod: 'm1', val: true } ] })
Синтаксический сахар
Объекта (
Object
)./* b1 → b1_m1 */ ({ block: 'b1', shouldDeps: { block: 'b1', mod: 'm1', val: true } })
/* b1 → b1_m1 */ ({ block: 'b1', shouldDeps: { mod: 'm1', val: true } })
/* b1 → b1_m1 */ ({ block: 'b1', mods: { m1: true } })
Массива строк (
String[]
)./* b1 → b1_m1 */ ({ block: 'b1', mods: [ 'm1' ] })
Подключение модификатора вида «ключ-значение»
b1 → b1_m1_v1
— блок b1
зависит от своего модификатора вида «ключ-значение» b1_m1_v1
.
Зависимость может быть объявлена в виде:
Массива объектов (
Object[]
)./* b1 → b1_m1_v1 */ ({ block: 'b1', shouldDeps: [ { block: 'b1', mod: 'm1', val: 'v1' } ] })
Синтаксический сахар
Объекта (
Object
)./* b1 → b1_m1_v1 */ ({ block: 'b1', shouldDeps: { mod: 'm1', val: 'v1' } })
/* b1 → b1_m1_v1 */ ({ block: 'b1', mods: { m1: 'v1' } })
/* b1 → b1_m1_v1 */ ({ block: 'b1', mods: { m1: [ 'v1' ] } })
Подключение зависимостей по технологии
b1.js → b2.bemhtml
— блок b1
в технологии реализации JavaScript зависит от блока b2
в технологии реализации BEMHTML.
Зависимость может быть объявлена в виде:
Массива объектов (
Object[]
)./* b1.js → b2.bemhtml */ ({ block: 'b1', tech: 'js', shouldDeps: [ { block: 'b2', tech: 'bemhtml' } ] })
Синтаксический сахар
Объекта (
Object
)./* b1.js → b2.bemhtml */ ({ block: 'b1', tech: 'js', shouldDeps: { block: 'b2', tech: 'bemhtml' } })
elem & elems
Совместное использование полей elem
и elems
.
/* b1__e1 → b1__e2 */
({
block: 'b1',
elem: 'e1',
elems: [
'e1',
'e2'
]
})
Примечание Зависимости сами на себя
/* b1__e1 → b1__e1 */
не имеют смысла и поэтому игнорируются.
mod & mods
Совместное использование полей mod
и mods
.
/* b1_m1_v1 → b1_m1_v2 */
({
block: 'b1',
mod: 'm1',
val: 'v1',
mods: { m1: [
'v1',
'v2'
]
}
})
Примечание Зависимости сами на себя
/* b1_m1_v1 → b1_m1_v1 */
не имеют смысла и поэтому игнорируются.
elems & mods
Совместное использование полей elems
и mods
.
/* b1 → b1__e1; b1 → b1_m1_v1 */
({
block: 'b1',
elems: 'e1',
mods: { m1: 'v1' }
})