Форум

Методологія

Інструментарій

Платформа

Спільнота

Організація файлової структури

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

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

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

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

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

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

Набір файлів блоку (наприклад, input.css, input.js) залежить від технологій, що входять у реалізацію блоку.

Навіщо?

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

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

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

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

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

Навіщо?

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

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

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

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

Навіщо?

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

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

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

Кінцева реалізація блоку може бути розділена за рівнями перевизначення.

Навіщо?

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

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

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

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

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

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

Приклади схем файлових структур БЕМ-проекту

Nested

  • Блоку відповідає директорія у файловій структурі.
  • Імена блоку і його директорії збігаються.
blocks/
    input/     # Директорія блоку input
    button/    # Директорія блоку button
  • Реалізація блоку розділена на окремі файли — файли технологій.
  • Імена файлів збігаються з ім'ям блоку.
  • Розширення відповідає технології.
blocks/
    input/
        input.css       # Реалізація блоку input в технології CSS
        input.js        # Реалізація блоку input в технології JavaScript
    button/
        button.css
        button.js
        button.png

Імена файлів і директорій БЕМ-сутностей відповідають згоди щодо іменування:

  • Елемент — 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).

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

blocks/
    input/
        _type/                                 # Директорія модифікатора type
            input_type_search.css              # Реалізація модифікатора type
                                               # зі значенням search в технології CSS
        __box/                                 # Директорія елемента box
            input__box.css
        __clear/                               # Директорія елемента clear
            _visible/                          # Директорія модифікатора visible
                input__clear_visible.css       # Реалізація булевого модифікатора visible
                                               # зі значенням true в технології CSS
            _size/                             # Директорія модифікатора size
                input__clear_size_large.css    # Реалізація модифікатора size
                                               # зі значенням large в технології CSS
            input__clear.css
            input__clear.js
        input.css
        input.js
    button/
        button.css
        button.js
        button.png

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

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

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

Flat

  • Директорії для блоків не використовуються.
  • Опціональні элеметы і модифікатори реалізовані в окремих файлах.
blocks/
    input_type_search.js
    input_type_search.bemhtml.js
    input__box.bemhtml.js
    input.css
    input.js
    input.bemhtml.js
    button.css
    button.js
    button.bemhtml.js
    button.png

Flex

Flex схема досить гнучка по відношенню до організації файлової структури БЕМ-проекту:

  • Блоку відповідає окрема директорія.
  • Елементи і модифікатори реалізовані в окремих файлах.
blocks/
    input/
        input_layout_horiz.css
        input_layout_vertical.css
        input__elem.css
        input.css
        input.js
    button/

  • Блоку відповідає окрема директорія.
  • Елементи і модифікатори реалізовані у файлах блоку.
blocks/
    input/
        input.css
        input.js
    button/
  • Директорії для блоків не використовуються.
  • Елементи і модифікатори реалізовані у файлах блоку.
blocks/
    input.css
    input.js
    button.css
    button.js
  • Директорії для блоків не використовуються.
  • Опціональні элеметы і модифікатори реалізовані в окремих файлах.
blocks/
    input_type_search.js
    input_type_search.bemhtml.js
    input__box.bemhtml.js
    input.css
    input.js
    input.bemhtml.js
    button.css
    button.js
    button.bemhtml.js
    button.png

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

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

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

Реалізація блоку може бути розділена за рівнями перевизначення.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Якщо ви помітили помилку, або хочете доповнити статтю, ви завжди можете або написати нам про це на Гітхабі, або поправити статтю з допомогою prose.io.