Forum

Methodology

Toolbox

Platform

Community

The translation of this article into your language is missing, you can help us translate.

Спецификация 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-файле можно используя:

  1. Круглые скобки ().

    ({
       /* DEPS-сущность */
    })
    
  2. Литерал массива [].

    [{
       /* 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: 'v1'
      }
    ]
})

Тип: 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' }
})
If you notice a mistake or want something to supplement the article, you can always write to us at GitHub, or correct an article using prose.io.