Мазмұнға өту

Аз болса да — күн сайын.

Үлкен монорепозиторийде Tailwind v3 → v4 миграциясы

5 мин оқу

Осы бетте
Қысқаша
Tailwind v4 конфигурацияны JavaScript-тен CSS-ке көшірді және кластарды файлдардан өзі іздейді. Қарапайым жобада бұл ыңғайлы. Кластар қолданбадан тыс ондаған кітапханада тұратын монорепозиторийде бұл жаңартудан кейін «стильдер жоғалып кетуінің» бірінші себебі. Төменде — не өзгереді, онсыз болмайтын төрт директива (@import, @config, @source, @reference), Sass-пен не істеу керек және нәтижені CI-дағы тексеріспен қалай бекіту керек.

v4-те не өзгерді, қарапайым тілмен

Tailwind — CSS генераторы. Ол файлдарыңды оқып, ішінен кластарды (flex, bg-primary, px-4) табады және тек шынымен қолданылатындарына ғана CSS жазады.

v3-те бұл tailwind.config.js ішінде бапталатын: түстер, қаріптер және content массиві — кластарды қайдан іздеу керек. v4-те:

  • Баптау CSS-ке көшті. Түстер мен қаріптер тікелей CSS-файлда @theme арқылы беріледі.
  • Кластарды іздеу автоматты. content массиві енді жоқ: Tailwind жобаны CSS жатқан папкадан бастап өзі сканерлейді.
  • Өз PostCSS-плагині. PostCSS-тегі tailwindcss орнына — @tailwindcss/postcss пакеті.
  • Autoprefixer енді керек емес — префикстерді v4 өзі қояды.
  • Браузерлер шегі жоғарырақ: шамамен Chrome 111, Safari 16.4, Firefox 128. Пайдаланушыларың ескі Safari-де болса — мұны кейін емес, бастамас бұрын тексер.

1-қадам. PostCSS

Бұрын:

// postcss.config.js
module.exports = {
  plugins: { tailwindcss: {}, autoprefixer: {} },
};

Қазір:

// .postcssrc.json
{ "plugins": { "@tailwindcss/postcss": {} } }

autoprefixer package.json-тен өшіреміз.

2-қадам. Басты CSS-тегі директивалар

v4-те @tailwind base; @tailwind components; @tailwind utilities; директивалары жоқ. Олардың орнына — қабаттар бойынша қарапайым импорттар:

@layer theme, base, components, utilities;

@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities" layer(utilities);

Бір жолмен @import "tailwindcss"; де болады. Біз қабаттарды айқын жаздық, өйткені Tailwind-тің үстінде Angular Material стильдері жатыр, ал қабаттардың реті кім кімді басатынын шешеді.

3-қадам. Ескі JS-конфигті қалдыруға болады

Бүкіл тақырыпты бір-ақ рет @theme-ге қайта жазу міндетті емес. @config директивасы ескі JS-конфигті немесе пресетті қосады:

@config "../tailwind.config.js";

Бізде барлық қолданбалар сілтейтін түс токендері мен қаріп шкаласы бар ортақ пресет бар. Оны CSS-ке қайта жазу — бөлек міндет. Миграцияны кішкентай қадамдармен жасаған жақсы: алдымен «құрастырылады және бұрынғыдай көрінеді», содан кейін — жақсартулар.

v3-те конфигте берілетін (darkMode: '[data-mode="dark"]') атрибут арқылы қараңғы режим v4-те CSS-те жарияланады:

@custom-variant dark ([data-mode="dark"] &);

4-қадам. @source: монорепозиторийдің басты тұзағы

Кластарды автоматты іздеу CSS-файл жатқан папкадан басталады және сізге керек болғандай одан шықпайды. Монорепозиторийде ортақ CSS UI-кит кітапханасында жатады, ал кластар тағы ондаған кітапханада және қолданбаларда қолданылады.

Нәтиже: құрастыру өтеді, қате жоқ, ал беттердің жартысында шегіністер жоқ. Tailwind бұл кластар жазылған файлдарды жай көрмеді де, оларға CSS жасамады.

Шешімі — қайдан іздеу керегін айқын тізіп шығу:

@source "./lib/**/*.{ts,html}";
@source "../../shared/**/*.{ts,html}";
@source "../../apps/my-app/src/**/!(*.stories|*.spec).{ts,html}";

Болашаққа ереже: осы CSS-ті қолданатын жаңа қолданба не кітапхана — жаңа @source жолы. Бұл туралы тікелей файлдың ішінде түсініктеме жазған жөн, әйтпесе келесі адам тағы да «жоғалған стильдерге» тап болады.

5-қадам. Компонент стильдеріндегі @reference

Angular-да әр компоненттің стильдері бөлек компиляцияланады. Егер компоненттің .scss ішінде @apply болса:

.card { @apply rounded-xl p-4 bg-background-1; }

онда v4-те бұл файл тақырып пен сенің токендерің туралы ештеңе білмейді — олардың анықтамалары басты CSS-те жатыр. Құрастыру «Cannot apply unknown utility class» деп құлайды.

Емі — файлдың бірінші жолында басты CSS-ке сілтеме жасау:

@reference "../../shared-styles.css";

@reference анықтамаларды тартып алады, бірақ CSS-тің өзін әр компонентке қайталамайды. Мұнда қарапайым @import қате болар еді: бүкіл Tailwind әр компоненттің стильдеріне түсер еді.

6-қадам. Sass пен Tailwind v4 тіл табыспайды

Tailwind v4 препроцессордың өзі ол деп есептейді. «Sass, ал ішінде Tailwind директивалары» деген байланыс нашар жұмыс істейді: Sass @source, @reference, @custom-variant-ды Tailwind-тен бұрын талдауға тырысады.

Не істедік:

  • Tailwind директивалары бар басты стиль файлы — қарапайым .css;
  • шынымен Sass талап ететін нәрсені (Sass-миксиндердегі Angular Material тақырыбы) бөлек .scss-ге шығарып, project.json ішінде қатар қостық.

7-қадам. Атауы өзгерген кластар

v4-те кластардың бір бөлігі бір сатыға жылжыды, мысалы shadow-sm → shadow-xs, rounded-sm → rounded-xs, outline-none → outline-hidden, ал ring-тың әдепкі ені 3px орнына 1px. Ресми npx @tailwindcss/upgrade утилитасы көбінің атауын автоматты өзгертеді.

Бірақ көлеңкелер мен радиустар пресеттен алынған өзіңдікі болса — олардың атауларына тиіспе. Атауды соқыр өзгертуге сенбе, көзбен тексер.

Мен жіберген қате

SCSS-файлдарды түзетпес бұрын *.scss.bak көшірмелерін «керек болып қалар» деп сақтадым. Олар коммитке кетіп қалды. Ұсақ-түйек, бірақ:

  • сақтық көшірмелер — git дәл соған арналған; бөлек көшірмелер керек емес;
  • коммиттің алдында — git status және файлдар тізімін қарау, ал .bak — .gitignore ішіне.

Ескіні қалай қайтармау керек

Миграция бәрі құрастырылған сәтте емес, ескі әдеттер қайта орала алмайтын кезде аяқталады. Көшкеннен кейін MR тексерісіне кішкентай скрипт қостық. Ол .css/.scss ішіндегі тек қосылған жолдарды қарап, тексерісті құлатады, егер:

  • түс токеннің орнына қолмен берілсе (#fff, rgb(...));
  • браузерлер шегінен жаңа CSS (@starting-style, anchor positioning, field-sizing және т. б.) @supports-сыз қолданылса.

Мұндай тексерістің оқу нұсқасы — он шақты жол:

// check-styles.mjs (учебный пример)
import { execFileSync } from 'node:child_process';

const diff = execFileSync('git', ['diff', '-U0', 'origin/main', '--', '*.css', '*.scss'], { encoding: 'utf8' });
const added = diff.split('\n').filter(l => l.startsWith('+') && !l.startsWith('+++'));

const bad = added.filter(l => /#[0-9a-f]{3,8}\b|\brgba?\((?!\s*var\()/i.test(l));
if (bad.length) {
  console.error('Цвет задан вручную, используй токен:\n' + bad.join('\n'));
  process.exit(1);
}

Неге тек қосылған жолдар: ескі бұзушылықтар жүздеген болуы мүмкін, және әр MR-да бәрін түзетуді талап ету — тексерісті тез өшіреді деген сөз. Жаңасына болмайды, ескісін біртіндеп ретке келтіреміз.

Чек-лист

  1. Пайдаланушылардың браузерлер шегін тексеру.
  2. PostCSS → @tailwindcss/postcss, autoprefixer-ді алып тастау.
  3. @tailwind ... → қабаттардың @import.
  4. Ескі конфиг — @config арқылы, кейін қайта жазу.
  5. Әр кітапхана мен қолданбаға @source.
  6. @apply бар компоненттің әр стиль файлында @reference.
  7. Tailwind директивалары — .css ішінде, Sass — бөлек.
  8. Экрандарды көзбен аралап шығу: десктоп және 375px.
  9. Ескі қайтып келмеуі үшін CI-дағы тексеріс.

Байланысты жазбалар: nx-monorepo-from-copies, ci-nx-affected.