Skip to content

Latest commit

Β 

History

History
424 lines (349 loc) Β· 7.9 KB

File metadata and controls

424 lines (349 loc) Β· 7.9 KB

PostCSS Workflows & Best Practices

πŸ”„ Common PostCSS Workflows

1. Development Workflow

src/styles.css β†’ PostCSS β†’ dist/styles.css β†’ Browser
     ↓               ↓           ↓
  Variables      Plugins    Optimized CSS
  Imports        Processing  Source Maps
  Nesting        Minification

Development Setup

// postcss.config.js (Development)
module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("postcss-preset-env")({ stage: 1 }),
    require("autoprefixer"),
    require("postcss-reporter")({ clearAllMessages: true }),
  ],
};

Watch Command

# CLI
postcss src/styles.css -o dist/styles.css --watch

# Gulp
gulp watch

# Vite
npm run dev

2. Production Workflow

src/styles.css β†’ PostCSS β†’ dist/styles.min.css
     ↓               ↓           ↓
  Variables      Plugins    Minified CSS
  Imports        Processing  Optimized
  Nesting        Prefixing   Gzipped
  Custom CSS     Linting     Source Maps

Production Setup

// postcss.config.js (Production)
module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("postcss-preset-env")({ stage: 3 }),
    require("autoprefixer"),
    require("cssnano")({ preset: "advanced" }),
    require("postcss-purgecss")({
      content: ["src/**/*.html", "src/**/*.js"],
    }),
  ],
};

3. Component Library Workflow

components/
  β”œβ”€β”€ Button/
  β”‚   β”œβ”€β”€ Button.css
  β”‚   └── Button.js
  β”œβ”€β”€ Card/
  β”‚   β”œβ”€β”€ Card.css
  β”‚   └── Card.js
  └── index.css

Component Setup

// postcss.config.js
module.exports = {
  plugins: [
    require("postcss-modules")({
      generateScopedName: "[name]__[local]___[hash:base64:5]",
    }),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
  ],
};

4. Multi-Environment Workflow

// postcss.config.js
const env = process.env.NODE_ENV || "development";

module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("postcss-preset-env")({
      stage: env === "production" ? 3 : 1,
    }),
    require("autoprefixer"),
    ...(env === "production"
      ? [
          require("cssnano")({ preset: "advanced" }),
          require("postcss-purgecss")({
            content: ["src/**/*.{html,js}"],
          }),
        ]
      : []),
    require("postcss-reporter")(),
  ],
};

🎯 Best Practices

1. Plugin Order Matters

// Correct order
module.exports = {
  plugins: [
    // 1. Import handling
    require("postcss-import"),

    // 2. Variables & mixins
    require("postcss-simple-vars"),
    require("postcss-mixins"),

    // 3. Syntax enhancement
    require("postcss-nested"),
    require("postcss-preset-env"),

    // 4. Optimization
    require("autoprefixer"),
    require("cssnano"),
  ],
};

2. Environment-Specific Configs

// postcss.dev.js
module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
  ],
};

// postcss.prod.js
module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
    require("cssnano")({ preset: "advanced" }),
  ],
};

3. Error Handling

module.exports = {
  plugins: [
    require("postcss-import"),
    require("postcss-simple-vars"),
    require("autoprefixer"),
    require("postcss-reporter")({
      clearAllMessages: true,
      throwError: true,
    }),
  ],
};

πŸ“ Project Structure Examples

Simple Project

project/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ styles.css
β”‚   └── components/
β”‚       └── button.css
β”œβ”€β”€ dist/
β”‚   └── styles.css
β”œβ”€β”€ postcss.config.js
└── package.json

Component Library

library/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ Button/
β”‚   β”‚   β”‚   β”œβ”€β”€ Button.css
β”‚   β”‚   β”‚   └── Button.js
β”‚   β”‚   └── Card/
β”‚   β”‚       β”œβ”€β”€ Card.css
β”‚   β”‚       └── Card.js
β”‚   β”œβ”€β”€ styles/
β”‚   β”‚   β”œβ”€β”€ variables.css
β”‚   β”‚   β”œβ”€β”€ mixins.css
β”‚   β”‚   └── base.css
β”‚   └── index.css
β”œβ”€β”€ dist/
β”‚   β”œβ”€β”€ components/
β”‚   └── index.css
β”œβ”€β”€ postcss.config.js
└── package.json

Multi-Theme Project

themes/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ themes/
β”‚   β”‚   β”œβ”€β”€ light.css
β”‚   β”‚   β”œβ”€β”€ dark.css
β”‚   β”‚   └── variables.css
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ button.css
β”‚   β”‚   └── card.css
β”‚   └── layouts/
β”‚       └── grid.css
β”œβ”€β”€ dist/
β”‚   β”œβ”€β”€ light.css
β”‚   └── dark.css
β”œβ”€β”€ postcss.config.js
└── package.json

πŸš€ Advanced Workflows

1. Critical CSS Extraction

const postcss = require("postcss");
const fs = require("fs");

// Extract critical CSS
async function extractCritical(html, css) {
  const result = await postcss([
    require("postcss-critical-css")({
      output: "dist/critical.css",
    }),
  ]).process(css);

  return result.css;
}

2. CSS-in-JS Integration

// styled-components with PostCSS
module.exports = {
  plugins: [
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
  ],
};

// styled.js
import styled from "styled-components";

const Button = styled.button`
  color: ${(props) => props.theme.primary};
  font-size: ${(props) => props.theme.fontSize};
`;

3. Design System Build

// Build design tokens
module.exports = {
  plugins: [
    require("postcss-simple-vars"),
    require("postcss-custom-properties"),
    require("postcss-extend"),
    require("postcss-preset-env"),
    require("autoprefixer"),
  ],
};

πŸ”§ Troubleshooting

Common Issues

1. Plugin Conflicts

// Problem: Multiple variable plugins
// Solution: Choose one variable system
module.exports = {
  plugins: [
    // βœ… Use either simple-vars OR custom-properties
    require("postcss-simple-vars"),
    // ❌ Don't use both
    // require('postcss-custom-properties')
  ],
};

2. Import Path Issues

// Problem: Relative imports not working
// Solution: Use absolute paths or configure base
module.exports = {
  plugins: [
    require("postcss-import")({
      path: ["src/styles", "node_modules"],
    }),
  ],
};

3. Source Maps Missing

// Problem: No source maps in production
// Solution: Explicitly enable source maps
// CLI: --map
// Gulp: .pipe(sourcemaps.write('.'))
// Webpack: devtool: 'source-map'

πŸ“Š Performance Optimization

1. Plugin Selection

// Development - Fast processing
module.exports = {
  plugins: [
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
  ],
};

// Production - Full optimization
module.exports = {
  plugins: [
    require("postcss-simple-vars"),
    require("postcss-nested"),
    require("autoprefixer"),
    require("cssnano")({ preset: "advanced" }),
  ],
};

2. Caching Strategy

// gulpfile.js with caching
const cached = require("gulp-cached");
const remember = require("gulp-remember");

gulp.task("css", () => {
  return gulp
    .src("src/**/*.css")
    .pipe(cached("css"))
    .pipe(postcss(plugins))
    .pipe(remember("css"))
    .pipe(gulp.dest("dist/"));
});

3. Parallel Processing

// Parallel CSS processing
const gulp = require("gulp");
const parallel = require("gulp-parallel");

gulp.task("css", parallel(["css:components", "css:utilities", "css:themes"]));