Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Свой плагин за пять минут

Плагин PostCSS — это обычная функция на JavaScript, которая возвращает объект с именем и обработчиками — функциями, которые PostCSS вызывает для узлов дерева: для каждого правила, каждого свойства и так далее. Написать свой плагин проще, чем кажется, и это лучший способ понять, как работают остальные.

Задача

В стилях блога не должно быть !important: он ломает обычный порядок применения правил. Напишем плагин, который убирает !important и предупреждает об этом в терминале.

Код плагина

Создайте папку plugins/ в корне проекта и файл plugins/no-important.js:

// plugins/no-important.js
const noImportant = () => {
  return {
    postcssPlugin: 'no-important',
    Declaration(decl, { result }) {
      if (decl.important) {
        decl.warn(result, `Убран !important у свойства ${decl.prop}`);
        decl.important = false;
      }
    },
  };
};
 
noImportant.postcss = true;
 
export default noImportant;

Разберём по строкам:

СтрокаСмысл
postcssPluginИмя плагина, видно в сообщениях
DeclarationВызывается для каждого объявления вида свойство: значение
decl.importanttrue, если у объявления есть !important
decl.warnДобавляет предупреждение с номером строки
noImportant.postcss = trueМетка, по которой PostCSS узнаёт плагин

Подключение

Импортируйте плагин по относительному пути, как любой модуль:

// postcss.config.js
import postcssPresetEnv from 'postcss-preset-env';
import noImportant from './plugins/no-important.js';
 
export default {
  plugins: [noImportant(), postcssPresetEnv()],
};

Проверьте на файле с !important:

/* styles/main.css */
.post-title {
  color: #1e293b !important;
  margin: 0;
}

После npx postcss styles/main.css -o css/main.css в терминале появится предупреждение с позицией — строка 2, столбец 3:

2:3  ⚠  Убран !important у свойства color [no-important]

А в css/main.css:

.post-title {
  color: #1e293b;
  margin: 0;
}

Другие обработчики

ОбработчикКогда вызывается
Once(root)Один раз для всего файла
Rule(rule)Для каждого правила с селектором, rule.selector
AtRule(atRule)Для каждой директивы вроде @media, atRule.name
Declaration(decl)Для каждого объявления, decl.prop и decl.value

Обработчику Declaration можно передать объект с именами свойств — тогда функция будет вызываться только для них, например Declaration: { color: (decl) => ... }.

Частая ошибка

Убрать строку noImportant.postcss = true и подключить плагин без вызова — noImportant вместо noImportant(). Без метки PostCSS считает функцию плагином старого формата, вызывает её с деревом, а возвращённый объект с обработчиками выбрасывает. Ошибки не будет, но и !important останется на месте. Держите метку postcss в файле плагина и вызывайте его в конфигурации со скобками, как остальные плагины.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.