Организация кода для CSS-препроцессора
Недавно прочитал статью на Frontender Magazine «организация кода для CSS препроцессоров», в которой рассказывается о нескольких вариантах организации файловой структуры стилей в проекте, и решил поделиться своими размышлениями на эту тему. Я полагаю, что вы уже прочитали эту небольшую статью.
Окей, начнём, пожалуй с того, что я выскажу своё «фи» относительно представленных в статье архитектурах. Структуру, носящую название «функциональное разделение» сразу можно забросить, так как она представляет собой мусорку, в которой просто лежат файлы. Вариант «Катана» плох тем, что файл стилей контента будет бесконечным и не совсем ясно, как искать нужные стили. Шаблонное или страничное распределение плохо тем, что количество страниц может быть невелико, а их содержимое достигать предельных значений. Архитектура, предложенная Крисом Койером выглядит ужасно из-за того, что она олицетворяет мусорку из файлов. Коктейль «Хьюго» очень хорошо смотрится на фоне остальных решений, но страдает логикой распределения файлов по директориям. Почему страдает логикой? — вы скоро это узнаете. Относительно дополнения от Игоря Зенича я ничего сказать не могу, потому что не исповедую БЭМ-методологию.
Давайте более подробно пройдёмся по коктейлю «Хьюго». Мне непонятна логика разделения файлов препроцессора на директории. Ниже я сформировал несколько вопросов, на которые ответить себе я так и не смог:
- Почему файл типографики (
_typography.scss
) находится в директории base, а файл стилей кнопок (_buttons.scss
) — в директории components, ведь кнопки — это базовый элемент любой страницы; - Почему файл глобальных констант (
_variables.scss
) находится в директории помощников? — автор предполагает, что переменные, объявленные в этом файле являются вспомогательными, а не глобальными? - Почему примеси собраны в одном файле (
_mixins.scss
), а не вынесены в отдельную директорию? Ведь на большом проекте примеси могут исчисляться десятками и иметь солидные размеры, например, если это генератор сетки.
Как бы я улучшил коктейль «Хьюго»? — придумал свой коктейль, добавив больше логики и уделил должное внимание разбиению файлов препроцессора на директории. Итак, встречайте мои размышления на тему идеальной файловой структуры организации стилей проекта.
Просто взгляните на представленную ниже структуру и попробуйте ответить на вопрос — «куда я должен поместить файл стилей иконок?».
- components/
- _navbar.less
- mixins/
- _buttons.less
- _clearfix.less
- modules/
- _buttons.less
- _forms.less
- _grid.less
- _lists.less
- _normalize.less
- _scaffolding.less
- _tables.less
- _typography.less
- pages/
- _home.less
- partials/
- _footer.less
- _header.less
- _main.less
- _variables.less
- styles.less
Если вы ответили, что файл стилей иконок нужно поместить в директорию modules, то вы уже поняли суть моей структуры. Если же нет, то будем разбираться вместе.
Но перед тем как перейти к подробному разбору структуры, я хочу сказать, что в зависимости от задач здесь могут добавляться дополнительные директории, например, такие как library, helpers, themes. Директория library появляется в том случае, если проект использует библиотеки, которые невозможно найти в bower или npm. Директория helpers добавляется, если проект требует использования помощников (выравнивание текста, отступы и т.д.). И, наконец, директорию themes следует создавать в том случае, если в проекте предусмотрены дополнительные темы.
Теперь обратимся к файлу styles.less
, который является точкой входа для всех стилей. Именно на него настраивается компилятор, и именно он соединяет все файлы препроцессора воедино.
К слову, я использую плагин less-plugin-glob для препроцессора Less, который позволяет импортировать файлы на основе glob-паттерна.
Довольно легко догадаться, что файл _variables.less
содержит глобальные константы. Под ними следует понимать переменные, необходимые всем модулям, компонентам или даже примесям. Однако, в этом файле не должно быть переменных, необходимых только одному компоненту или только одной теме — такие переменные описываются непосредственно в файле компонента или темы.
Mixins, partials и pages
Директория mixins содержит все примеси, используемые в проекте. В идеализированном случае, одна примесь — один файл, но никто не запрещает, допустим, написать две примеси для кнопок в одном файле.
Директория partials обычно включает в себя три файла стилей, которые стилизуют шапку (header), подвал (footer) и то, что между ними — центральную часть (main) сайта. Если вам необходимо поменять цвет фона шапки, то соответствующее свойство следует написать именно в файл _header.less
, а не для каждого компонента, который используется в шапке. Точно такая же история и с подвалом, и с центральной частью.
В директорию pages складываются все файлы специфичных стилей для конкретных страниц. Так уж заведено, что каждая страница имеет уникальный для неё класс, присвоенный тегу body
. Например, главная страница сайта имеет у тега body
класс page-home
, а страницы документации и полной версии записи (поста) имеет классы, соответственно, page-docs
и page-post
. Постараюсь ответить на вопрос: «что должно находиться в этих файлах?». Ответ довольно прост — специфичные для этой страницы стили, например, для изменения отображения какого-либо компонента.
Modules и components
Вот мы и подошли к самому важному — модулям и компонентам.
Модуль — это кирпичик, из которого строятся страницы или компоненты. Модуль включает в себя основные стили для элемента, который он пытается стилизовать. Например, файл _buttons.less
стилизует кнопки и предоставляет различные вариации их отображения: цветные кнопки, групповые кнопки, кнопка как ссылка. Ещё одним примером может служить файл _tables.less
, который стилизует таблицы и предоставляет, допустим, следующие их вариации: таблица с рамкой, таблица с «зеброй» и т.д.
Примеры модулей:
- Кнопки;
- Элементы форм;
- Таблицы;
- Простые списки;
- Типографика;
- Сетка;
- Какие-то общие стили проекта (
_scaffolding.less
).
Теперь я отвечу на вопрос: «почему файл normalize находится в директории модулей?». Ответ довольно прост: потому, что ради одного файла нет смысла создавать целую директорию library, учитывая то, что этот файл может быть отредактирован (например, убраны стили по умолчанию для таблиц).
Компонент — это цельный блок, из которого строится страница. Компонент включает в себя модули и, если это требуется, другие компоненты. Предполагается, что компонент независим и может быть с легкостью и без проблем с отображением, выдернут из одного контекста использования и вставлен в другой.
Такая идея используется в методологии RSCSS и БЭМ-методологии с той лишь разницей, что в их понимании блок — это форма, логотип, список ссылок и, наконец, глобальное меню, а здесь компонент — это нечто цельное, то есть лишь глобальное меню.
Вообще, говорить здесь о методологиях слегка неправильно, потому что мы описываем файловую структуру директории стилей, а не очередную методологию. Разумеется, вы можете создавать компоненты в бесчисленном количестве и так, как вам это удобно.
Примеры компонентов:
- Глобальная навигация;
- Dropdown-меню;
- Рекламные блоки;
- Подсветка кода;
- Список статей;
- Jumbotron;
- Блок социальных кнопок;
- Список категорий или тегов;
- Стилизация контента статьи.
Я бы хотел остановиться на последнем пункте немного подробнее, так как изначально можно подумать, что стилизация контента статьи предполагает под собой лишь работу с типографикой и с легкостью может перекочевать в модуль. Отчасти это так, но стилизация контента статьи предполагает под собой использование модуля «типографика» и нескольких компонентов, что соответствует описанию компонента.
Так что же с ответом на вопрос: «куда я должен поместить файл стилей иконок?». Теперь вы уже точно можете сказать, что файл стилей иконок следует поместить в директорию модулей, потому что иконка сама по себе может называться элементом, который включается и в контексте компонента, и без него.
Выводы
В статье на Frontender Magazine в конце каждого варианта организации стилей проекта приводится список плюсов и минусов, я полагаю, что стоит постараться объективно оценить и предложенный мной вариант:
Плюсы
- Здесь присутствует логика и смысл;
- Строгое разбиение по предназначению;
- Легко поддерживать вручную;
- Каждый файл обещает быть небольшим по объему;
- Вы всегда знаете, что класс типа
.navbar
можно найти в директорииcomponents/_navbar.less
.
Минусы
- Много директорий и файлов;
- Нужно думать: что есть модуль, а что есть компонент?
- Иногда понятие компонента может быть расплывчатым.
Источник: https://www.canonium.com/articles/organizing-code-in-project