Сборка для продакшена
Продакшен — версия сайта, которая выкладывается на сервер для посетителей. Во время работы нужен читаемый CSS с картами исходников, а для публикации — сжатый и без карт. Соберём все плагины курса в одну цепочку с переключателем между этими режимами.
Структура проекта
blog/
├── index.html
├── css/
│ └── main.css ← результат сборки
├── styles/
│ ├── main.css
│ ├── base.css
│ └── post-card.css
├── postcss.config.js
└── package.jsonУстановите все плагины разом:
npm install --save-dev postcss postcss-cli postcss-import postcss-preset-env cssnanoНастройки с переключателем
Файл настроек может экспортировать не объект, а функцию. postcss-cli передаёт ей объект ctx, где ctx.env — значение переменной окружения NODE_ENV:
// postcss.config.js
import postcssImport from 'postcss-import';
import postcssPresetEnv from 'postcss-preset-env';
import cssnano from 'cssnano';
export default (ctx) => {
const isProduction = ctx.env === 'production';
return {
map: isProduction ? false : { inline: false },
plugins: [
postcssImport(),
postcssPresetEnv(),
isProduction ? cssnano() : false,
],
};
};В режиме разработки cssnano заменяется на false — такие элементы списка PostCSS пропускает. Карта исходников, наоборот, пишется только при разработке.
Скрипты
Флаг --env задаёт NODE_ENV одинаково в Windows, macOS и Linux:
{
"scripts": {
"dev": "postcss styles/main.css -o css/main.css --watch",
"build": "postcss styles/main.css -o css/main.css --env production"
},
"browserslist": ["defaults"]
}Исходные стили
/* styles/main.css */
@import "./base.css";
@import "./post-card.css";/* styles/base.css */
@custom-media --tablet (width >= 768px);
body {
margin: 0;
font-family: system-ui, sans-serif;
}/* styles/post-card.css */
.post-card {
padding: 16px;
border-radius: 8px;
user-select: none;
& h2 {
margin: 0;
}
@media (--tablet) {
padding: 32px;
}
}Разработка
npm run dev следит за всеми тремя файлами — postcss-cli знает, какие из них подключены через @import. В css/main.css читаемый CSS и ссылка на карту:
body {
margin: 0;
font-family: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans, sans-serif;
}
.post-card {
padding: 16px;
border-radius: 8px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.post-card h2 {
margin: 0;
}
@media (min-width: 768px) {
.post-card {
padding: 32px;
}
}
/*# sourceMappingURL=main.css.map */Файлы склеены, вложенность развёрнута, --tablet заменён условием, добавлены префиксы, а для старых браузеров к system-ui добавлен список похожих системных шрифтов.
Публикация
npm run build выдаёт одну строку без карты:
body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif}.post-card{padding:16px;border-radius:8px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.post-card h2{margin:0}@media(min-width:768px){.post-card{padding:32px}}На сервер выкладываются index.html и папка css/. Папку styles/ и node_modules/ загружать не нужно.
В проекте на Vite
В Vite цепочка короче: @import и сжатие он делает сам, поэтому в postcss.config.js остаётся только postcssPresetEnv(). Команда npm run build положит готовый CSS в dist/assets/.
Частая ошибка
Писать в скрипте NODE_ENV=production postcss .... Такая запись работает в macOS и Linux, но в обычной командной строке Windows выдаёт ошибку, и коллега на Windows не сможет собрать проект. Используйте флаг --env production — postcss-cli выставит переменную сам.