Skip to content

Переводит сборку стилей на lightningcss - #1377

Merged
solarrust merged 2 commits into
mainfrom
perevodit-stili-na-lightningcss
Sep 1, 2026
Merged

solarrust merged 2 commits into
mainfrom
perevodit-stili-na-lightningcss

Conversation

@solarrust

@solarrust solarrust commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Продолжение #1376: тот убрал csso с дев-сервера, этот убирает его вообще.

Зачем

Половина css-цепочки — археология, и она уже мешает:

Пакет Последний релиз
postcss-csso август 2022
csso (внутри) февраль 2023
css-tree (внутри csso) 2.2.1, при живых 3.2.1
postcss-media-minmax июнь 2022

css-tree 2.2.1 не знает @container, @scope, вложенных слоёв и CSS-вложенности. Обновиться некуда — новых версий не выходит. Пока современный синтаксис есть только в демках, это ломало дев-сервер; как только он появится в src/styles, упадёт боевая сборка.

Что сделано

lightningcss закрывает всё, чем занимались пять пакетов: собирает @import, ставит префиксы, компилирует синтаксис под browserslist, минифицирует. Ушли postcss, postcss-import, postcss-media-minmax, postcss-csso, autoprefixer, gulp-postcss — шесть пакетов на один, csso пропал из дерева зависимостей целиком.

Targets считаются из поля browserslist в package.json и живут в config/css.js — общем для gulpfile.js и Vite, чтобы дев-сервер и прод не разъезжались.

Тесты — config/__tests__/css.js, 8 штук: сборка @import, префиксы по targets и по одному кейсу на каждый синтаксис, который ронял csso.

Заодно починен browserslist

Раньше это поле почти ни на что не влияло: по нему autoprefixer расставлял префиксы, а компиляцией синтаксиса занимался postcss-media-minmax, который не смотрел ни на какой browserslist и переписывал range-медиазапросы всегда. С lightningcss поле стало настоящим переключателем поддержки — и обнаружилось, что записано там last 2 version, то есть Chrome 150 и Safari 26.5, позавчерашние релизы.

Стало defaults (стандартный набор browserslist: > 0.5%, последние две версии, Firefox ESR, живые браузеры) плюс порог 16.4 по Safari и iOS. Порог не с потолка: в Safari 16.4 приехали разом range-синтаксис медиазапросов, булева логика MQ4 и :has(). Ниже него lightningcss начинает компилировать медиазапросы, а на строгих неравенствах вроде (width < 768px) выдаёт not (min-width: 768px) — синтаксис MQ4, которого в старом Safari всё равно нет, так что правило просто не применится.

Что это даёт по сравнению с тем, что собиралось раньше:

старый пайплайн last 2 version стало: defaults + 16.4
размер index.css 107 675 104 455 104 919
min-width/max-width 166 22 22
range-синтаксис 0 144 144
префиксов 81 24 31
chrome от — 150 109
safari / ios от — 26.5 16.4

Range-синтаксис теперь доезжает до браузера как написан, без перевода в min-width/max-width — все браузеры выборки его понимают. Префиксов больше, чем при last 2 version, и меньше, чем ставил autoprefixer: часть старых ему уже была не нужна.

Ещё пропал @charset 'utf-8': lightningcss его убирает, потому что всегда пишет UTF-8. В файле есть четыре не-ASCII символа (✎, ✅, ❌ в content), а сервер отдаёт text/css без charset — проверила на превью, браузер читает их правильно (U+270E, U+2705, U+274C). По CSS Syntax 3 дефолт и есть UTF-8.

Остальные различия выдачи безобидны: слияние правил с одинаковыми объявлениями, border: 0 → border: none, background-position: center → 50%. Ещё lightningcss добавляет пару служебных переменных --lightningcss-light/--lightningcss-dark — это заготовка полифилла light-dark(), которая срабатывает от color-scheme: light dark в base-colors.css. Сейчас light-dark() в стилях не используется, переменные никто не читает, а когда функция появится — она будет работать.

Чем проверяла

После ребейза на свежий main всё прогнано заново, начиная с npm ci, и потом ещё раз после смены browserslist:

  • npm run check — зелёный целиком, включая 8 новых тестов.
  • npm run build — проходит, dist/styles на месте, кеш-хэши проставились, страницы ссылаются на существующие файлы. Таск styles стал 13 мс вместо секунд.
  • npm start — поднимается, /styles/index.css отдаётся собранным (ни одного @import, 1145 правил, префиксы на месте), в логе ни одной ошибки.
  • Глазами в браузере: главная, статья /css/display/ в светлой теме, страница участника, /css/container/ и её демка — на десктопе, планшете (768) и мобильном (375). Демка @container работает: при ширине контейнера 402px карточки перестраиваются в 2 колонки, container-type: inline-size применён. Демка @container style() и демка @scope тоже отрабатывают по существу, а не просто отдают 200.
  • Демки, которые раньше отдавали 500 — @container, @scope, вложенные слои, вложенность — теперь 200.

npm run lint:html прогнать не удалось: валидатору нужна Java 17, а на машине только 11 и 13. К правке это не относится — HTML эта работа не трогает, в CI (setup-java@v4, java-version: 17) проверка отработает.

Ещё замечание не по теме: npm i на ноде 22 падает — editorconfig-checker@7 требует >=24.14.0, а в .npmrc стоит engine-strict = true. Ставила и собирала на 24.20 из nvm, как и написано в .nvmrc.

🤖 Generated with Claude Code

postcss-csso не выходил с августа 2022, csso — с февраля 2023, и внутри
он держит css-tree 2.2.1, который не знает ни @container, ни @scope, ни
вложенных слоёв, ни вложенности. Обновить нельзя: новых версий просто
нет. postcss-media-minmax из той же эпохи, июнь 2022.

lightningcss закрывает всё разом: собирает @import, ставит префиксы,
компилирует синтаксис под browserslist и минифицирует. Вместе с ним
уезжают postcss, postcss-import, postcss-media-minmax, postcss-csso,
autoprefixer и gulp-postcss — шесть пакетов на один.

Targets считаются из поля browserslist в package.json и лежат в
config/css.js, чтобы дев-сервер и прод-сборка не разъезжались.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Раньше поле browserslist ни на что толком не влияло: autoprefixer по нему
ставил префиксы, а компиляцией синтаксиса занимался postcss-media-minmax,
который смотрел не на browserslist, а никуда. С lightningcss поле стало
настоящим переключателем поддержки, и его значение пора было починить.

`last 2 version` — это Chrome 150 и Safari 26.5, позавчерашние релизы.
`defaults` — стандартный набор browserslist, а порог 16.4 по Safari взят
не с потолка: в этой версии в Safari приехали разом range-синтаксис
медиазапросов, булева логика MQ4 и :has(). Ниже него lightningcss
начинает компилировать медиазапросы и на строгих неравенствах выдаёт
синтаксис, которого в старом Safari всё равно нет.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@solarrust
solarrust merged commit 6904d12 into main Sep 1, 2026
7 checks passed
@solarrust
solarrust deleted the perevodit-stili-na-lightningcss branch September 1, 2026 10:48
Comment thread gulpfile.js

await Promise.all(
styleEntries.map((entry) =>
writeFile(path.join('dist/styles', entry), bundleStyle(path.join('src/styles', entry))),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А зачем тогда Vite?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Валидно, надо будет оставить только его и для локальной и для продакшен сборки. В следующих сериях =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants