# Організація файлової системи

Прийнятий у методології БЕМ компонентний підхід застосовується і до організації БЕМ-проектів у файловій системі. В БЭМ не только интерфейс делится на независимые компоненты — блоки, но и реализация блоков делится на независимые части — файлы.

На цій сторінці ви знайдете:

* [Принципи організації файлової системи](#Принципи організації файлової системи-БЕМ-проекту)
* [Приклад файлової системи БЕМ-проекту](#Організація файлової системи-БЕМ-проекту)
* [Приклади використання рівнів перевизначення](#Приклади використання-рівнів-перевизначення)

## Принципи організації файлової системи БЕМ-проекту

У БЕМ-проекті код поділяється на дрібні незалежні частини для зручності роботи з окремими блоками. Перед відправкою в браузер файли збираються і оптимізуються. Таким чином ми розмежовуємо код, за яким працюють люди, і код, який передається в браузер.

У файловій системі код БЕМ-проекту організовано за такими принципами:

* [Реалізація блоку розділяється на окремі файли](#Реалізація-блоку-поділяється на окремі файли)
* [Необов'язкові елементи і модифікатори виносяться в окремі файли](#Опціональні-елементи-і-модифікатори-виносяться в окремі файли)
* [Файли об'єднуються за змістом, а не за типом](#Файли-об'єднуються-за змістом-а-не-по-типу)
* [Проект розділяється на рівні перевизначення](#Проект розділяється на рівні-перевизначення)

### Реалізація блоку розділяється на окремі файли

Набір файлів блоку (наприклад, `input.css`, `input.js`) залежить від [технологій](../key-concepts/key-concepts.ru.md#Технологія-реалізації), що входять в реалізацію блоку.

*Навіщо?*

* **Поліпшення навігації по проекту**

  Структура проекту побудована за єдиним принципом, а імена блоків унікальні. Це дозволяє розробникам швидко орієнтуватися в різних частинах проекту і знаходити потрібні файли.

* **Спрощення перенесення блоків між проектами**

  Реалізація блоків розділена по окремих файлів. При перенесенні блоку з проекту в проект достатньо скопіювати потрібні файли або теки.

### Додаткові елементи і модифікатори виносяться в окремі файли

*Навіщо?*

* **Підключення тільки потрібної реалізації блоку**

  У збірку підключаються тільки файли, які дійсно необхідні для даної реалізації блоку.

### Файли об'єднуються за змістом, а не за типом

Файли блоку групуються з допомогою загальних [правил іменування](../naming-convention/naming-convention.ru.md). Для зручності роботи вони можуть бути об'єднані в директорію цього блоку.

*Навіщо?*

* **Підключення у проект тільки необхідних блоків**

  Блоки реалізовані незалежно. Це дозволяє налаштовувати збірку так, щоб у проект потрапляли тільки потрібні блоки.

### Проект розділяється на рівні перевизначення

Кінцева реалізація блоку може бути розділена за [рівнями перевизначення](#Приклади використання-рівнів-перевизначення).

*Навіщо?*

* **Відсутність дублювання коду**

  Винесення загальної реалізації для всіх платформ на окремий рівень дозволяє уникнути дублювання коду та скоротити час на налагодження проекту.

* **Перевизначення і доопределение блоків готових бібліотек**

  Зміна блоку бібліотеки не вимагає його копіювання рівень проекту. Досить створити потрібний файл з правками або новим кодом на іншому рівні перевизначення і підключити в збірку.

* **Оновлення підключених в проект бібліотек**

  Поділ проекту на рівні дозволяє змінювати блоки, не зачіпаючи код бібліотеки. При оновленні бібліотеки модифікація блоків зберігається на іншому рівні проекту.

## Організація файлової системи БЕМ-проекту

Блоку відповідає директорія у файловій системі. Імена блоку і його директорії збігаються.

```files
blocks/
    input/     # Директорія блоку input
    button/    # Директорія блоку button
```

Реалізація блоку розділена на окремі файли — файли технологій. Імена файлів збігаються з ім'ям блоку. Розширення відповідає технології.

```files
blocks/
    input/
        input.css       # Реалізація блоку `input` в технології CSS
        input.js        # Реалізація блоку `input` в технології JavaScript
    button/
        button.css
        button.js
        button.png
```

Імена файлів і директорій [БЕМ-сутностей](../key-concepts/key-concepts.ru.md#БЕМ-сутність) відповідають [згоди щодо іменування](../naming-convention/naming-convention.ru.md):

* Элемент — `block__elem.extension` (`input__box.css`).
* Модифікатор блоку — `block_mod_val.extension` (`input_type_search.css`) або `block_mod.extension` (`input_disabled.css`). Значення булевого модифікатора не вказується.
* Модифікатор елемента — `block__elem_mod_val.extension` (`input__clear_size_large.css`) або `block__elem_mod.extension` (`input__clear_visible.css`).


Модифікатори і елементи виділяються в окремі файли групуються в піддиректорії блоку з відповідними іменами.

```files
blocks/
    input/
        _type/                        # Директорія модифікатора `type`
            input_type_search.css     # Реалізація модифікатора `type`
                                      # зі значенням `search` в технології CSS
        __box/                        # Директорія елемента `box`
            input__box.css
        input.css
        input.js
    button/
        button.css
        button.js
        button.png
```

При створенні модифікаторів з різними значеннями (наприклад, `popup_target_anchor.extension` і `popup_target_position.extension`), загальний код може бути винесений в окремий файл (`popup_target.extension`) без зазначення значення модифікатора в імені.

```files
blocks/
    popup/
        _target/
            popup_target.css           # Загальний код модифікатора `target`
            popup_target_anchor.css    # Модифікатор `target` у значенні `якір`
            popup_target_position.css  # Модифікатор `target` у значенні `position`
        _visible/
            popup_visible.css          # Булевий модифікатор visible
    popup.css
    popup.js
```

### Приклади з життя

* [bem-core](https://github.com/bem/bem-core/tree/v2/common.blocks/page)
* [bem-components](https://github.com/bem/bem-components/tree/v2/common.blocks/button)

## Приклади використання рівнів перевизначення

Реалізація блоку може бути розділена за [рівнями перевизначення](../key-concepts/key-concepts.ru.md#Рівень-перевизначення).

Розглянемо кілька прикладів:

* [Підключення бібліотеки](#Підключення бібліотеки)
* [Поділ проекту на платформи](#Поділ проекту на-платформи)

### Підключення бібліотеки

У проект можна підключити бібліотеку як окремий рівень. Змінювати (до - або ігнорувати) блоки можна на іншому рівні проекту. При складанні підключиться вихідна реалізація блоків з бібліотеки рівня і переопределенная — з рівня проекту.

Такий поділ дозволяє зберегти зміни в блоках при оновленні бібліотеки. Код бібліотеки оновиться, а специфічна реалізація блоків проекту залишиться колишньою, так як знаходиться на іншому рівні проекту.

```files
library.blocks/
    button/
        button.css    # CSS-реалізація кнопки в бібліотеці (висота 20px)

project.blocks/
    button/
        button.css    # Перевизначення на рівні проекту (висота 24px)
```

### Поділ проекту на платформи

Проект розділений на платформи (`mobile` і `desktop") та відповідні рівні зміни у файловій системі. Рівень `common` містить загальну реалізацію блоків для всіх платформ. На рівні `desktop` і `mobile` знаходиться специфіка реалізацій блоків, характерна для кожної з платформ.

Розглянемо на прикладі:

```files
common.blocks/
    button/
        button.css    # Базова CSS-реалізація кнопки

desktop.blocks/
    button/
        button.css    # Особливості кнопки для desktop

mobile.blocks/
    button/
        button.css # Особливості кнопки для mobile
```

При зборці в файл `desktop.css` потраплять всі базові CSS-правила кнопки з рівня `common` і перевизначені правила з рівня `desktop`.

```css
@import "common.blocks/button/button.css";    /* Базові CSS-правила */
@import "desktop.blocks/button/button.css";   /* Особливості desktop */
```

Файл `mobile.css` буде включати базові CSS-правила кнопки з рівня `common` і перевизначені правила з рівня `mobile`.

```css
@import "common.blocks/button/button.css";    /* Базові CSS-правила */
@import "mobile.blocks/button/button.css";    /* Особливості mobile */
```
