Прямо сейчас я начинаю верстать новый проект. Я решила, что это хороший повод познакомиться с новой для себя технологией, поэтому выбрала в качестве препроцессора PostCSS. Меня привлекает в нем скорость работы и модульность, однако до сих пор не было случая попробовать его на реальном проекте. Сейчас в основном я использую Sass, и невозможность (хоть и временная) использовать node-sass с шестой версией Node.js, и то, как из-за этого у меня поломались стили в проекте, тоже послужило причиной поиска альтернатив.
Для начала расскажу, как сейчас у меня выглядит работа со стилями.
Как я сейчас работаю со стилями
Есть основной файл, main.scss, в который подключаются все остальные файлы стилей, разделенные по папкам. Я использую систему папок, похожую на модель 7-1, с некоторыми отличиями: у меня почти никогда нет папки vendors/
(вместо нее я подключаю сторонние библиотеки через npm), а также папки themes/
(даже в больших проектах у меня не было необходимости выделять отдельные темы). В папке components/
я создаю отдельный файл для каждого нового класса компонентов.
Сборку делаю через Gulp. Для импорта стилей использую gulp-sass-glob, чтобы можно было импортировать папки со стилями целиком, например: @import "../components/**/*.scss";
.
В больших проектах использую миксины Bourbon. К собранным стилям применяю автопрефиксер.
Единообразие написания стилей и отсутствие в них ошибок проверяется при помощи Stylelint или SCSS-lint в виде плагина для редактора Atom (вот мой конфиг .scss-lint.yml, основанный на Sass Guidelines). При помощи CSSComb (и этого плагина для редактора) я автоматически сортирую CSS свойства (конфиг настроен в соответствии с линтером).
Готовый файл минифицируется через CSS Nano в виде плагина для Gulp.
В идеале, мне бы хотелось получить такую конфигурацию, которая будет работать с уже написанными стилями с SCSS-синтаксисом, и чтобы не не нужно было менять привычки написания стилей. Потом, возможно, я подумаю над другими вариантами, но моя задача сейчас – сделать подобие SCSS, но через PostCSS. То есть, мне нужно:
- объявление переменных как
$
, - вложенность стилей, возможность использовать конструкции вида
&__elem
, - миксины, желательно с синтаксисом как в SCSS (
@include mixin-name
), - импорт папок целиком, а не по отдельным файлам
- не критично, но было бы приятно, найти аналоги того, что я делаю через Bourbon; но в крайнем случае можно написать функции самостоятельно
И еще, чтобы был линтер, и все это собиралось бы через Gulp, и быстрее, чем SCSS. В будущем я рассматриваю возможность перехода на NPM-скрипты.
Переход к PostCSS
Как выяснилось, я уже использую два, а в некоторых случаях три инструмента из экосистемы PostCSS: это Автопрефиксер, CSS Nano, и иногда Stylelint. Отлично. Осталось найти что-то, что позволит заменить SCSS.
Как я уже писала, одно из преимуществ PostCSS это модульность, то есть для решения каждой отдельной проблемы существует свой плагин, а если не существует, то его можно написать самостоятельно. Большое количество плагинов размещено здесь.
Синтаксис
Среди плагинов я нашла Precss, который позволяет использовать синтаксис из Scss. Однако его возможности мне показались избыточными, из Scss мне нужны только импорт, переменные, вложенность и миксины. Поэтому я решила взять по отдельности плагины postcss-partial-import, postcss-simple-vars, postcss-nested, postcss-mixins.
К сожалению, мне пока не удалось найти плагин, который бы мог импортировать содержимое директории целиком.
Приятно порадовал плагин stylefmt, который является заменой для CSS Comb и может форматировать стили в соответствии с конфигом от Stylelint. Кроме того, он есть в виде плагина для Атома.
Установка
Вроде бы все нашлось. Теперь можно установить плагины и настроить таск для сборщика Gulp. Я начну с установки плагинов, которые позволят использовать привычный синтаксис, а потом добавлю остальное.
1 |
npm i -D gulp gulp-postcss gulp-sourcemaps autoprefixer postcss-partial-import postcss-simple-vars postcss-nested postcss-mixins |
Потестировала, все работает. Значит, можно добавить CSSNano для минификации.
1 |
npm i -D gulp-cssnano |
В итоге, таск у меня получился такой:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
'use strict'; const gulp = require('gulp'); const sourcemaps = require('gulp-sourcemaps'); gulp.task('css', function () { const postcss = require('gulp-postcss'); const nano = require('gulp-cssnano'); return gulp.src('src/css/*.css') .pipe( sourcemaps.init() ) .pipe( postcss([ require('autoprefixer'), require('postcss-partial-import'), require('postcss-simple-vars'), require('postcss-nested'), require('postcss-mixins') ]) ) .pipe(nano()) .pipe( sourcemaps.write('.') ) .pipe( gulp.dest('build/') ); }); |
Теперь надо добавить линтер и инструмент для форматирования кода. Я хочу, чтобы ошибки в стилях выводились в консоли и в редакторе, поэтому надо установить плагин Stylelint для Атома, настроить таск для Gulp, и создать файл конфига .stylelintrc. Устанавливается все просто.
1 |
npm i -D gulp-stylelint && apm install linter-stylelint |
А вот с конфигом придется помучиться. Все возможные правила перечислены тут, но создавать их придется вручную. Я для начала установила stylelint-config-standard, npm install -D stylelint-config-standard
и прописала в файле .stylelintrc его использование:
1 2 3 |
{ "extends": "/absolute/path/to/stylelint-config-standard" } |
Когда будет время, проверю его соответсвтие со своим конфигом для SCSS-lint.
Таск для линтера стилей получился такой:
1 2 3 4 5 6 7 8 9 10 11 12 |
gulp.task('lint-css', function () { const stylelint = require('gulp-stylelint'); return gulp.src('src/**/*.css') .pipe(stylelint({ failAfterError: false, // disable fail after error reporters: [{ formatter: 'string', console: true }] })); }); |
Добавим инструмент для форматирования кода. Тут, на самом деле, я не до конца разобралась, может ли плагин для Атома работать без установленного npm-пакета.
1 |
npm install -D stylefmt && apm install stylefmt |
Вроде бы, все работает. Для удобства, вот в виде отдельной команды все пакеты, которые я поставила:
1 |
npm i -D gulp gulp-postcss gulp-sourcemaps autoprefixer postcss-partial-import postcss-simple-vars postcss-nested postcss-mixins gulp-cssnano gulp-stylelint stylefmt |
И плагины для Атома:
1 |
apm install linter-stylelint stylefmt |
Все это позволило мне начать проект с привычным мне подходом, но используя PostCSS вместо SCSS. Пока что тестирую, и присматриваюсь. Не исключаю, что во всех новых проектах буду использовать эти инструменты.