Статьи

Как создать свой собственный CSS препроцессор с PostCSS

Какое-то время пользуйтесь CSS-препроцессором, и жизнь станет немыслимой без него. Многие разработчики приняли LESS, Stylus или — текущий фаворит — Sass. В идеале, вы также должны пост-обрабатывать свой CSS с помощью Autoprefixer, чтобы добавлять префиксы в случае необходимости, не прибегая к миксинам или фреймворкам, таким как Compass .

Autoprefixer — плагин для PostCSS ; инструмент, который переводит CSS в объектную модель, которая может использоваться для управления стилями. Есть еще много доступных плагинов, которые реализуют функции, подобные препроцессору, такие как переменные, миксины и вложение.

Недавняя статья Бена Фрейна « Расстаться с Сассом: это не ты, а я» выдвигает интересное предложение. Вам действительно нужны Sass, LESS или Stylus, если вы можете создать препроцессор CSS, который вы хотите, используя PostCSS?

Базовый Sass-подобный парсер может быть создан в процессе сборки. В этом примере я буду использовать файл задачи Gulp.js, но те же понятия применимы к Grunt или любой другой системе сборки. Сначала мы устанавливаем PostCSS и плагины, которые нам нужны, используя npm, например

npm install gulp-postcss postcss-mixins postcss-simple-vars postcss-nested autoprefixer-core --save-dev 

затем создайте массив функций обработки CSS в gulpfile.js , например

 var gulp = require('gulp'), postcss = require('gulp-postcss'), processors = [ require('postcss-mixins'), require('postcss-simple-vars'), require('postcss-nested'), require('autoprefixer-core')({ browsers: ['last 2 versions', '> 2%'] }) ]; 

и написать задачу обработки CSS, например

 // compile CSS gulp.task('css', function() { return gulp.src('source/css/styles.css') .pipe(postcss(processors)) .pipe(gulp.dest('dest/styles/')); }); точки // compile CSS gulp.task('css', function() { return gulp.src('source/css/styles.css') .pipe(postcss(processors)) .pipe(gulp.dest('dest/styles/')); }); 

Вы также можете создавать свои собственные функции обработки с помощью API PostCSS . Например, мы могли бы применить запасной вариант без засечек для всех объявлений font-family :

 processors = [ require('postcss-mixins'), require('postcss-simple-vars'), require('postcss-nested'), function(css) { // sans-serif fallback css.eachDecl('font-family', function(decl) { decl.value = decl.value + ', sans-serif'; }); }, require('autoprefixer-core')({ browsers: ['last 2 versions', '> 2%'] }) ]; 

Если файл /source/css/styles.css содержал этот код:

 $colorfore: #333; $colorback: #fff; @define-mixin reset { padding: 0; margin: 0; } main { font-family: Arial; @mixin reset; color: $colorfore; background-color: $colorback; article { color: $colorback; background-color: $colorfore; } } 

запуск gulp css создаст этот CSS в /dest/css/styles.css :

 main { font-family: Arial, sans-serif; padding: 0; margin: 0; color: #333; background-color: #fff; } main article { color: #fff; background-color: #333; } 

Преимущества

PostCSS освобождает вас от ограничений и выбора, наложенных авторами препроцессора. Подход предлагает несколько преимуществ:

  • модульность
    Вам нужно только добавить плагины и функции, необходимые для вашего проекта.
  • облегченный
    Препроцессоры становятся все более крупными и сложными приложениями. Вы, вероятно, не захотите или не будете использовать все функции, но они все еще присутствуют. PostCSS уменьшает объем.
  • Немедленная реализация
    Вы когда-нибудь ждали, чтобы что-то стало доступно в Sass, LibSass, LESS, Stylus или другом препроцессоре? Теперь вы можете разрабатывать свои собственные функции, используя …
  • Функции JavaScript
    Ваш CSS препроцессор использует JavaScript — настоящий язык программирования (несмотря на то, что некоторые люди говорят!)

    Большинство языковых конструкций препроцессора являются базовыми. Вы часто будете видеть функции и миксины, которые являются более сложными и трудными для понимания, чем необработанный CSS, который они создают. С PostCSS доступны средства, которые никогда не будут реализованы в Sass / LESS / Stylus. Вы можете легко открывать файлы, читать из баз данных, делать HTTP-запросы или создавать сложные вычисления.

  • Обеспечить соблюдение политики развития
    Предположим, вы хотели, чтобы ваша команда избегала объявлений @extend . Никто больше не может использовать @extend если он не добавляет плагин расширения в процесс сборки. Это было бы сразу очевидно.
  • Это быстро — очень быстро
    По оценкам авторов PostCSS в 4 — 40 раз быстрее, чем эквивалентный препроцессор. Я подозреваю, что выигрыш еще выше, если вам требуется всего несколько плагинов. Все решение построено на JavaScript, и нет необходимости переходить в другую библиотеку или интерпретатор языка.

Недостатки

Все хорошо тогда? К сожалению, PostCSS не является идеальным решением:

  • Повышенная сложность
    Ваш процесс сборки станет более сложным для управления.

    Добавление Sass обычно представляет собой одну или две строки кода, но PostCSS требует более тщательного планирования, особенно потому, что плагины должны вызываться в определенном порядке. Например, @import должно быть разрешено до синтаксического анализа переменных. Но что, если у вас есть переменные в ваших объявлениях @import ? В некоторых ситуациях может потребоваться вызвать плагин более одного раза.

  • Другой синтаксис
    Сначала я попытался преобразовать небольшой проект Sass в PostCSS. Даже не пытайся! Хотя в конце концов мне это удалось, плагины PostCSS часто используют немного другой синтаксис, например, @define-mixin а не @mixin . Это может привести к путанице и многочисленным обновлениям кода. Часть причины …
  • PostCSS требует корректного CSS
    Большинство препроцессоров анализируют текстовые файлы, поэтому любой синтаксис теоретически возможен. PostCSS создает объектную модель, поэтому он требует синтаксически корректного CSS с самого начала. Даже // single line comment может привести к сбою. Вы можете предварительно обработать свои CSS-файлы перед передачей в PostCSS, но затем вы вернетесь к использованию препроцессора!

Вы должны отказаться от своего препроцессора?

Пользовательский процессор PostCSS может быть привлекательным вариантом, если вы работаете в команде из одного человека и начинаете небольшой, относительно простой автономный проект.

Я также рекомендую PostCSS для любых подлинных задач постобработки, таких как префиксы поставщиков, упаковка медиазапросов в одно объявление, сокращение уравнений calc() , применение откатов для старых браузеров, поддержка селекторов CSS4, минимизация и т. Д. При использовании этой функции мало пользы. ,

Однако Sass достиг критической массы. Никакой синтаксис препроцессора не идеален, но он будет понятен большинству разработчиков в вашей команде. Все, что немного отличается, вряд ли принесет значительную пользу или понравится всем.

Тем не менее, PostCSS и аналогичные Rework Framework имеют огромный потенциал. Если бы модульная система плагинов CSS могла копировать — и даже смешивать — синтаксис и функциональность, которые мы хотим от Sass, LESS и Stylus, у нас был бы один препроцессор, который побил бы все остальные. Вы можете поспорить, кто-то, где-то сейчас работает над этим проектом …

Вы успешно использовали PostCSS в качестве препроцессора для своего проекта? Вас это увлекло от Sass? Собираетесь ли вы перейти от LESS? Вы откажетесь от стилуса?