bem-sdk-archive / bem-deps

🎯 Manage BEM dependencies. DEPRECATED →
https://github.com/bem/bem-sdk/tree/master/packages/deps
Other
10 stars 5 forks source link

Multi selectors #52

Open blond opened 8 years ago

blond commented 8 years ago

There are cases when several entities depend on other entity.

The dependency should be added only when both entities are in declaration.

Example:

var bemDeps = require('@bem/deps');

var relations = {
    entity: { block: 'A' },
    onlyWith: [
        { entity: { block: 'B' } }
    ],
    dependOn: [
        { entity: { block: 'C' } }
    ]
};

bemDeps.resolve([{ block: 'A' }, { block: 'B' }], relations);

// [
// { block: 'A' },
// { block: 'B' },
// { block: 'C' }
// ]

bemDeps.resolve([{ block: 'A' }], relations);

// [
// { block: 'A' }
// ]

Real examples:

  1. { block: 'checkbox', modName: 'theme', modVal: 'islands' with { block: 'checkbox', modName: 'type', modVal: 'button' } depend on { block: 'button', modName: 'theme', modVal: 'islands' }.

    islands theme of button should be added only if checkbox has type_button modifier with islands theme.

    Code in bem-componentshttps://github.com/bem/bem-components/blob/5406834d2f35911574ec49f974c0788c800d7835/design/common.blocks/checkbox/_theme/checkbox_theme_islands.deps.js

  2. { block: 'dropdown', modName: 'theme', modVal: 'islands' with { block: 'dropdown', modName: 'switcher', modVal: 'link' } depend on { block: 'link', modName: 'theme', modVal: 'islands' }.

    islands theme of link should be added only if dropdown has switcher_link modifier with islands theme.

    Code in bem-componentshttps://github.com/bem/bem-components/blob/5406834d2f35911574ec49f974c0788c800d7835/design/common.blocks/dropdown/_theme/dropdown_theme_islands.deps.js

Quotes:

Taken from https://github.com/bem/bem-tools/pull/463.

Это позволяет указывать зависимости между сущностями, но без подключения самих сущностей. Например, блок B не зависит от кода блока A напрямую, но если вдруг какой-то другой блок будет явно зависеть от A, то его код (код блока A) должен подключаться раньше подключения кода B. Для этого в B пишется такая зависимость (с ключом include: false), которая влияет только на порядок, без явного подключения самой сущности.


представьте, что есть блок input и у него есть 1) разные темы input_theme_{dark,light} и 2) опциональный элемент input__label

в стилях для темы написано переопределение базовых стилей для лейбла, поэтому input_theme_{dark,light} должен идти после input__label -- т.е. нужен mustDeps: input_theme_{dark,light} mustDeps input__label, но если так написать сейчас, то всегда с темой будет подцепляться input__label (т.к. у нас понятия "это должно идти перед этим" и "это должно попадать в финальную сборку вместе с этим" не разделены)

чтобы можно было указать зависимость по порядку следования в сборке, но при этом не требовать обязательного подключения опционального элемента мы сделали include: false -- input_theme_{dark,light} mustDeps input__label include: false -- в этом случае мы запомним факт про зависимость, но не будем подключать input__label до тех пор, пока кто-то его не попросит без include: false

qfox commented 8 years ago
var relations = {
    entity: { block: 'A' },
    onlyWith: [
        { entity: { block: 'B' } }
    ],
    dependOn: [
        { entity: { block: 'C' } }
    ]
};

Т.е. это надо будет дважды прописывать? И для блока A, и для B?

qfox commented 8 years ago

Real examples could be easily a bad architecture.

    onlyWith: [
        { entity: { block: 'B' } }
    ],

You sure that we need entity here?

Do you specified RelationNode types (or something like that) already?

blond commented 8 years ago

Т.е. это надо будет дважды прописывать? И для блока A, и для B?

Нет. Если в декларации есть A и B то работает, если чего-то нет, то не работает. В какой последовательности записали — неважно.

Смущает синтаксис? Есть идеи как лучше?

blond commented 8 years ago

You sure that we need entity here?

Yes. This is consistent with other cases. And we can specify the technology.

onlyWith: [
    {
        entity: { block: 'B' },
        tech: 'js'
    }
]

Do you specified RelationNode types (or something like that) already?

What do you mean by RelationNode types?

qfox commented 8 years ago

Смущает синтаксис? Есть идеи как лучше?

Смущает то, что надо будет помнить про вхождение блока B в зависимостях блока А Если удаляем блок В, то надо будет лезть во все блоки и чистить зависимости.

qfox commented 8 years ago

What do you mean by RelationNode types?

I mean we need specification for node types.

blond commented 8 years ago

Смущает то, что надо будет помнить про вхождение блока B в зависимостях блока А

Так это жизненная необходимость :) Без такого рода зависимостей не избежать избыточного кода.

Такие зависимости можно писать не в файлах блока, а каких-нибудь файлах уровня или проекта. Но это уже дело вкуса.

blond commented 8 years ago

I mean we need specification for node types.

Relations is not graph, although very similar. Therefore, there are no nodes and their types.

Or do you mean that we should describe the relations format?

qfox commented 8 years ago

@blond The question of missing terminology. What is relation? Where are dependency-edges?