Tailwind CSSSeniorCoding

Что такое плагины Tailwind CSS и как создать пользовательский плагин?

Плагины Tailwind — функции, регистрирующие новые утилиты, компоненты или варианты через API addUtilities/addComponents. Создаются через plugin() и подключаются в tailwind.config.

Плагины Tailwind CSS

Плагин — это функция, которая получает набор вспомогательных методов и регистрирует собственные утилиты, компоненты, базовые стили или варианты (variants). Плагины подключаются в секции plugins конфигурационного файла.

Базовая структура плагина

// tailwind.config.js
const plugin = require('tailwindcss/plugin');

module.exports = {
  plugins: [
    plugin(function ({ addUtilities, addComponents, addBase, matchUtilities, theme }) {
      // Добавляем статические утилиты
      addUtilities({
        '.text-shadow': {
          textShadow: '2px 2px 4px rgba(0,0,0,0.3)',
        },
        '.text-shadow-lg': {
          textShadow: '4px 4px 8px rgba(0,0,0,0.5)',
        },
      });
    }),
  ],
};

Динамические утилиты через matchUtilities

matchUtilities позволяет создавать утилиты, которые принимают произвольные значения из темы или произвольные значения в квадратных скобках ([value]).

plugin(function ({ matchUtilities, theme }) {
  matchUtilities(
    {
      'text-shadow': (value) => ({
        textShadow: value,
      }),
    },
    { values: theme('textShadow') }
  );
})

После этого можно писать text-shadow-md (из темы) или text-shadow-[0_2px_4px_red] (произвольное значение).

Добавление компонентов

plugin(function ({ addComponents }) {
  addComponents({
    '.btn': {
      padding: '0.5rem 1rem',
      borderRadius: '0.375rem',
      fontWeight: '600',
      display: 'inline-flex',
      alignItems: 'center',
    },
    '.btn-primary': {
      backgroundColor: '#3b82f6',
      color: '#ffffff',
      '&:hover': {
        backgroundColor: '#2563eb',
      },
    },
  });
})

Плагин с опциями

// my-plugin.js
const plugin = require('tailwindcss/plugin');

module.exports = plugin.withOptions(
  function (options = {}) {
    return function ({ addUtilities }) {
      const prefix = options.prefix || 'custom';
      addUtilities({
        [`.${prefix}-center`]: {
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        },
      });
    };
  },
  function (options = {}) {
    // Расширение темы через второй аргумент
    return {
      theme: {
        extend: {
          spacing: {
            '128': '32rem',
          },
        },
      },
    };
  }
);

// tailwind.config.js
module.exports = {
  plugins: [
    require('./my-plugin')({ prefix: 'flex' }),
  ],
};

Добавление кастомных вариантов

plugin(function ({ addVariant }) {
  // Вариант для :nth-child(odd)
  addVariant('odd', '&:nth-child(odd)');
  // Вариант для data-атрибута
  addVariant('data-active', '&[data-active]');
  // Вариант для родительского состояния
  addVariant('group-hovered', ':merge(.group):hover &');
})

После регистрации можно использовать: odd:bg-gray-100, data-active:text-blue-500.

Публикация плагина как npm-пакета

// package.json
{
  "name": "tailwindcss-text-shadow",
  "main": "index.js",
  "peerDependencies": {
    "tailwindcss": ">=3.0.0"
  }
}

Подводные камни

  • Статические утилиты из addUtilities не поддерживают произвольные значения в квадратных скобках — для этого нужен matchUtilities.
  • CSS-свойства в объектах плагина указываются в camelCase (textShadow), а не в kebab-case — иначе свойство молча игнорируется.
  • Плагины, добавляющие утилиты через addUtilities, по умолчанию не получают все варианты (hover, focus и т.д.) — нужно явно передать { variants: ['hover', 'focus'] } вторым аргументом (в v3) или использовать matchUtilities.
  • При использовании addBase стили попадают в базовый слой и не могут быть переопределены утилитами без !important — не злоупотребляйте.
  • theme() внутри плагина — это функция, а не объект; вызов theme('colors.blue') вернёт объект с оттенками, а не строку.
  • Плагин с plugin.withOptions нельзя использовать без вызова — require('./plugin') вернёт фабрику, а не сам плагин.
  • В Tailwind v4 API плагинов изменился: используется CSS-native подход с @plugin директивой, а JS-плагины подключаются иначе — проверьте совместимость.
  • Порядок плагинов важен: если два плагина регистрируют одинаковые классы, победит последний.

Common mistakes

  • Смешивать «плагины Tailwind» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «плагины Tailwind» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет расширение framework новыми utilities, variants или компонентными классами.
  • Показывает на примере, как работает: плагин добавляет CSS в генератор Tailwind и должен быть связан с токенами темы, чтобы не создать параллельную неподдерживаемую систему стилей.
  • Называет production-нюанс и граничный случай для темы «плагины Tailwind».

Sources

Related topics