Прийнятий у методології БЕМ компонентний підхід застосовується і до організації БЕМ-проектів у файловій структурі. У БЕМ не тільки інтерфейс ділиться на незалежні компоненти — блоки, але й реалізація блоків ділиться на незалежні частини — файли.
На цій сторінці ви знайдете:
- Принципи організації файлової структури
- Приклади схем файлових структур БЕМ-проекту
- Приклади використання рівнів перевизначення
У БЕМ-проекті код поділяється на дрібні незалежні частини для зручності роботи з окремими блоками. Перед відправкою в браузер файли збираються і оптимізуються. Таким чином ми розмежовуємо код, з яким працюють люди, і код, що передається в браузер.
У файловій структурі код БЕМ-проекту організовано за такими принципами:
- Реалізація блоку розділяється на окремі файли
- Додаткові елементи і модифікатори виносяться в окремі файли
- Файли об'єднуються за змістом, а не за типом
- Проект розділяється на рівні перевизначення
Набір файлів блоку (наприклад, input.css, input.js) залежить від технологій, що входять у реалізацію блоку.
Навіщо?
- Поліпшення навігації по проекту
Структура проекту побудована за єдиним принципом, а імена блоків унікальні. Це дозволяє розробникам швидко орієнтуватися в різних частинах проекту і знаходити потрібні файли.
- Спрощення перенесення блоків між проектами
Реалізація блоків розділена по окремих файлів. При перенесенні блоку з проекту в проект достатньо скопіювати потрібні файли або теки.
Навіщо?
- Підключення тільки потрібної реалізації блоку
У збірку підключаються тільки файли, які дійсно необхідні для даної реалізації блоку.
Файли блоку групуються з допомогою загальних правил іменування. Для зручності роботи вони можуть бути об'єднані в директорію цього блоку.
Навіщо?
- Підключення у проект тільки необхідних блоків
Блоки реалізовані незалежно. Це дозволяє налаштовувати збірку так, щоб у проект потрапляли тільки потрібні блоки.
Кінцева реалізація блоку може бути розділена за рівнями перевизначення.
Навіщо?
- Відсутність дублювання коду
Винесення загальної реалізації для всіх платформ на окремий рівень дозволяє уникнути дублювання коду та скоротити час на налагодження проекту.
- Перевизначення і доопределение блоків готових бібліотек
Зміна блоку бібліотеки не вимагає його копіювання рівень проекту. Досить створити потрібний файл з правками або новим кодом на іншому рівні перевизначення і підключити в збірку.
- Оновлення підключених в проект бібліотек
Поділ проекту на рівні дозволяє змінювати блоки, не зачіпаючи код бібліотеки. При оновленні бібліотеки модифікація блоків зберігається на іншому рівні проекту.
- Блоку відповідає директорія у файловій структурі.
- Імена блоку і його директорії збігаються.
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
- Директорії для блоків не використовуються.
- Опціональні элеметы і модифікатори реалізовані в окремих файлах.
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 схема досить гнучка по відношенню до організації файлової структури БЕМ-проекту:
- Блоку відповідає окрема директорія.
- Елементи і модифікатори реалізовані в окремих файлах.
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 */