Автоматическое разбиение стилей с использованием SASS

3641eea13f21dba397b05e698f39b9dc
Пост для людей использующих SASS и решающих задачи по оптимизации больших файлов стилей с ограниченными человеческими ресурсами. 

Дано: 

  1. Большой сайт с количеством шаблонов 50+.
  2. Большой файл стилей.
  3. Сайт постоянно развивается, правятся баги, пишется новый функционал.
  4. Версия develop и production в одной ветке, репозитарий SVN.
  5. 1-2 человека на поддержание всего этого хозяйства.
  6. Огромное желание не сойти с ума и не наложить на себя руки!



Если вам интересен конец этой эпопеи милости прошу под кат

Предистория


Некоторое время назад я попал на один большой проект, который до меня писали три человека. Эти человеки, к слову сказать, были родом из страшной сказки про «злого разработчика», который слыхом не слыхивал о независимых блоках, препроцессорах и всякой другой оптимизации. Я, конечно, оставить так все не мог и с неимоверным энтузиазмом начал все переписывать. А переписывать, я вам скажу, было что. Все стили были собраны в нескольких файлах, самый большой из которых насчитывал 16к строк. Вот как раз в процессе разгребания этих авгиевых конюшен я и столкнулся с проблемой.

Как в меру ленивый человек я привык отдавать рутинные операции на откуп автоматизации и оная началась с подключения SASS и создания переменных, миксинов и экстендов в одном глобальном файле. По обыкновению работы с SASS на других проектах, я собрал компиляцию всех стилей в один глобальный файл через импорты. Так как это было самое оптимальное решение при разработке сайта. Но, как оказалось, не для продакшена. Сборный файл стилей стал весить без сжатия 2.5 мб! Разбивать вручную и разбрасывать по всем контроллерам подключение отдельных файлов стилей — был для меня не вариант, и я начал думать как все сделать так чтобы машина страдала за меня. Вот как раз с продуктом своих размышлений я и хочу вас познакомить.

Концепция состоит в следующем

 

  • Компиляция происходит только через глобальные файлы, в которых настраиваются все параметры компиляции и контекста. В этих файлах мы передаем переменные, которые задают такие значения как:
    • контекст, определяющий к какому разделу сайта мы будем подключать стили,
    • версия браузера,
    • версия сборки (develop или production),
    • любые другие переменные.
  • На уровне фреймворка создается шаблон, по которому генерируются глобальные файлы. По одному на контроллер или вьюху, решать вам. Переменной контекста и названием в этих файлах служит название контроллера/вьюхи. После успешной генерации эти файлы автоматически подключаются в соответствующие контроллеры/вьюхи в виде css файлов.
  • Все файлы стилей оборачиваются в миксин, который при компиляции автоматически сортирует стили в соответствии с указанными переменными контекста. Если этих переменных несколько можно провести дополнительную сортировку внутри файла по любой переменной указанной в глобальных файлах.
  • Как дополнительный бонус, при использовании данной системы можно хранить несколько версий стилей в одном месте. Например, функционал соответствующий продакшену и девелопу, стили для разных браузеров и их версий.



Модель шаблона для компиляции стилей

 

// Версионность стилей
$develop: false;
$production: true;
...

// Браузерные переменные по которым компилируется код для указанного браузера
$all: true;
$ie9: false;
...

// Файл соответствия документации
$doc: false; 

// Переменная указывающая контекст генерации
$local_var: global;

// Дополнительные переменные для частных случаев
// в данном случае переменная описывает определенный праздник и включает изменение стилей для некоторых элементов сайта
$holydat_var: 8march;


// Файл с импортами всех файлов стилей
@import "includes";



Модель глобального файла с импортами всех стилей

 

// Файл со всеми глобальными переменными
@import "includes/global_var";

// Файлы с остальными стилями проекта
@import "fonts";
@import "header";
@import "login";
@import "news";
@import "jquery.ui.all";
@import "factory";
@import "rooms";
@import "invite";
...



Модель файла стилей для отдельного контроллера

 

// Миксин разделяющий стили на уровне группы или одного "контроллера" или выбранного 
@include style_separator("значение переменной 1", ..."значение переменной N"){

   // Миксин разделяющий стили на уровне отдельного контекста
   @include sub_style_separator("значение переменной 1"){
      .selector{
      ...
      }
   }

   // Миксин разделяющий стили на уровне отдельного контекста
   @include sub_style_separator("значение переменной N"){
      .selector2{
      ...
      }
   }

   .selector3{
   ...
   }
...
}



Модель файла стилей для отдельного контроллера

 

// Код миксинов вызов которых показан выше
@mixin style_separator($var: false, ... $varN: false) {
    @if $var == $local_var or ... $varN == $local_var {
        @content;
    }
}

@mixin sub_style_separator($var: false, ... $varN: false) {
    @if $var == $local_var or ... $varN == $local_var {
        @content;
    }
}



Итого


В результате мы получаем систему, которая не требует серьезных вложений времени и подготовки. Для самого простого использования необходимы только знания в SASS. Кроме того, такой подход дает возможность не тратить много времени на организацию, разделение и подключение стилей. Система пока апробирована мной на одном большом проекте, но уже показала свою эффективность. Буду рад критике любого рода!

P.S.


Советы по мотивам набитых шишек:

  • Экстенды используйте только с «тихими» классами. Иначе в каждом файле «контроллера» будет много лишнего кода.
  • Лучше разделять стили на глобальные и локальные. При этом локальные модификации писать в файлах «контроллеров». Глобальные разделять по блокам типа списки, чекбоксы и тд… Тогда из получившегося набора глобальных вы сможете собрать подобие своего фреймворка.
  • Используйте методологию BEM или все описанное выше теряет смысл.