Encodera

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

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

Оглавление

Сборка для продакшена

Продакшен — версия сайта, которая выкладывается на сервер для посетителей. Во время работы нужен читаемый 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 выставит переменную сам.

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

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