Seamless integration between Rollup and PostCSS with support for CSS modules, preprocessors, and flexible output options
npx @tessl/cli install tessl/npm-rollup-plugin-postcss@4.0.0Rollup Plugin PostCSS provides seamless integration between Rollup and PostCSS, enabling developers to process CSS files with PostCSS plugins during the bundling process. It supports various CSS preprocessors (Sass, Stylus, Less), offers CSS modules functionality, provides options for CSS extraction or injection, includes source map support, and enables advanced features like CSS minimization and custom loaders.
npm install rollup-plugin-postcss postcss --devimport postcss from 'rollup-plugin-postcss';
// Type definitions (if using TypeScript)
import type { PostCSSPluginConf } from 'rollup-plugin-postcss';For CommonJS:
const postcss = require('rollup-plugin-postcss');// rollup.config.js
import postcss from 'rollup-plugin-postcss';
export default {
plugins: [
postcss({
plugins: []
})
]
};Then import CSS files in your JavaScript:
import './style.css'; // Injects CSS to <head>
import styles from './style.module.css'; // CSS modulesRollup Plugin PostCSS is built around several key components:
Creates a Rollup plugin instance with comprehensive PostCSS processing capabilities.
/**
* Creates a Rollup plugin for PostCSS processing
* @param options - Configuration options for the plugin
* @returns Rollup plugin object
*/
function postcss(options?: Readonly<PostCSSPluginConf>): Plugin;
// Required imports for TypeScript usage
type FunctionType<T = any, U = any> = (...args: readonly T[]) => U;
type CreateFilter = import('rollup-pluginutils').CreateFilter;
interface PostCSSPluginConf {
/** Inject CSS as <style> to <head> */
inject?: boolean | Record<string, any> | ((cssVariableName: string, id: string) => string);
/** Extract CSS to file */
extract?: boolean | string;
/** Callback when CSS is extracted */
onExtract?: (asset: OnExtractAsset) => boolean;
/** Enable CSS modules */
modules?: boolean | Record<string, any>;
/** File extensions to process */
extensions?: string[];
/** Note: Present in TypeScript definitions but not used in current implementation */
name?: any[] | any[][];
/** PostCSS plugins array */
plugins?: any[];
/** Auto-enable CSS modules for .module.* files (default: true) */
autoModules?: boolean;
/** Use named exports alongside default export */
namedExports?: boolean | ((id: string) => string);
/** Minimize CSS with cssnano */
minimize?: boolean | any;
/** PostCSS parser (e.g., 'sugarss') */
parser?: string | FunctionType;
/** PostCSS stringifier */
stringifier?: string | FunctionType;
/** PostCSS syntax */
syntax?: string | FunctionType;
/** Enable PostCSS Parser support in CSS-in-JS */
exec?: boolean;
/** PostCSS config file options */
config?: boolean | { path: string; ctx: any };
/** PostCSS 'to' option hint for plugins */
to?: string;
/** Custom loaders array (simplified as any[] in TypeScript definitions) */
loaders?: any[];
/** Callback when CSS file is imported */
onImport?: (id: string) => void;
/** Preprocessor configuration */
use?: string[] | { [key in 'sass' | 'stylus' | 'less']: any };
/** Source map generation */
sourceMap?: boolean | 'inline';
/** Include patterns for rollup-pluginutils filter */
include?: Parameters<CreateFilter>[0];
/** Exclude patterns for rollup-pluginutils filter */
exclude?: Parameters<CreateFilter>[1];
}
type OnExtractAsset = Readonly<{
code: any;
map: any;
codeFileName: string;
mapFileName: string;
}>;
// Note: While TypeScript definitions use any[] for loaders,
// the actual implementation expects objects with this structure:
interface Loader {
name: string;
test: RegExp;
process: (this: LoaderContext, input: Payload) => Promise<Payload> | Payload;
}
interface LoaderContext {
/** Loader options */
options: any;
/** Source map configuration */
sourceMap: boolean | 'inline';
/** Resource path */
id: string;
/** Files to watch */
dependencies: Set<string>;
/** Emit a warning */
warn: (warning: any) => void;
/** Rollup plugin context */
plugin: any;
}
interface Payload {
/** File content */
code: string;
/** Source map */
map?: string | any;
}Usage Examples:
// Basic usage with PostCSS plugins
import postcss from 'rollup-plugin-postcss';
import autoprefixer from 'autoprefixer';
export default {
plugins: [
postcss({
plugins: [autoprefixer()]
})
]
};
// CSS extraction
import postcss from 'rollup-plugin-postcss';
export default {
plugins: [
postcss({
extract: true, // Extract to [bundle].css
// Or extract to custom file
extract: 'dist/styles.css'
})
]
};
// CSS Modules
import postcss from 'rollup-plugin-postcss';
export default {
plugins: [
postcss({
modules: true,
// Or with custom options
modules: {
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
})
]
};Controls how CSS is injected into the document.
// Configuration options for CSS injection
inject?: boolean | Record<string, any> | ((cssVariableName: string, id: string) => string);When inject is true (default), CSS is injected into the document <head> using the style-inject library. When extract is true, injection is automatically disabled.
Custom injection function:
postcss({
inject: (cssVariableName, id) => `
import styleInject from 'style-inject';
styleInject(${cssVariableName}, { insertAt: 'top' });
`
});Extracts CSS to separate files instead of injecting into JavaScript.
// Configuration options for CSS extraction
extract?: boolean | string;
onExtract?: (asset: ExtractAsset) => boolean;Usage Examples:
// Extract to default location ([bundle].css)
postcss({ extract: true });
// Extract to custom file
postcss({ extract: 'dist/styles.css' });
// Custom extraction logic
postcss({
extract: true,
onExtract(getExtracted) {
const { code, map, codeFileName, mapFileName } = getExtracted();
// Custom processing
return true; // Continue with extraction
}
});Enables CSS Modules for locally scoped CSS classes.
// Configuration options for CSS modules
modules?: boolean | Record<string, any>;
autoModules?: boolean;
namedExports?: boolean | ((id: string) => string);Usage Examples:
// Enable CSS modules
postcss({ modules: true });
// Custom CSS modules configuration
postcss({
modules: {
generateScopedName: '[name]__[local]___[hash:base64:5]',
localsConvention: 'camelCase'
}
});
// Auto-enable for .module.css files
postcss({ autoModules: true });
// Named exports alongside default
postcss({
modules: true,
namedExports: true
});In your JavaScript:
// Default export (object with class mappings)
import styles from './component.module.css';
// Named exports (with namedExports: true)
import styles, { header, content } from './component.module.css';Built-in support for Sass, Stylus, and Less preprocessors. Requires installing the corresponding preprocessor packages:
// Configuration options for preprocessors
use?: string[] | { [key in 'sass' | 'stylus' | 'less']: any };Prerequisites:
npm install sass or npm install node-sassnpm install stylusnpm install lessUsage Examples:
// Default preprocessor support
postcss({
use: ['sass', 'stylus', 'less']
});
// Custom preprocessor options
postcss({
use: {
sass: {
includePaths: ['node_modules'],
data: '$primary-color: #333;'
},
stylus: {
paths: ['src/styles'],
import: ['mixins.styl']
},
less: {
paths: ['src/styles'],
globalVars: { primaryColor: '#333' }
}
}
});
// Specific preprocessors only
postcss({
use: [['sass', { includePaths: ['node_modules'] }]]
});Minimizes CSS output using cssnano.
// Configuration options for CSS minimization
minimize?: boolean | any;Usage Examples:
// Enable minimization
postcss({ minimize: true });
// Custom cssnano options
postcss({
minimize: {
preset: ['default', {
discardComments: { removeAll: true }
}]
}
});Controls PostCSS processing options and configuration loading.
// PostCSS configuration options
plugins?: any[];
parser?: string | Function;
stringifier?: string | Function;
syntax?: string | Function;
exec?: boolean;
config?: boolean | { path: string; ctx: any };
to?: string;Usage Examples:
// PostCSS plugins
postcss({
plugins: [
require('autoprefixer'),
require('postcss-nested')
]
});
// Custom parser (e.g., SugarSS)
postcss({
parser: 'sugarss',
extensions: ['.sss']
});
// PostCSS config file
postcss({
config: {
path: './postcss.config.js',
ctx: { env: 'production' }
}
});
// CSS-in-JS support
postcss({ exec: true });Controls which files are processed and how.
// File processing configuration
extensions?: string[]; // Default: ['.css', '.sss', '.pcss']
include?: Parameters<CreateFilter>[0];
exclude?: Parameters<CreateFilter>[1];
onImport?: (id: string) => void;Usage Examples:
// Custom extensions (default is ['.css', '.sss', '.pcss'])
postcss({
extensions: ['.css', '.pcss', '.sss']
});
// Include/exclude patterns
postcss({
include: ['src/**/*.css'],
exclude: ['**/*.module.css']
});
// Import callback
postcss({
onImport: (id) => {
console.log(`Processing CSS file: ${id}`);
}
});Enables source map generation for CSS.
// Source map configuration
sourceMap?: boolean | 'inline';Usage Examples:
// Enable source maps
postcss({ sourceMap: true });
// Inline source maps
postcss({ sourceMap: 'inline' });Extend the plugin with custom file processing loaders.
// Custom loader configuration (TypeScript types show any[], but implementation expects Loader objects)
loaders?: any[];
// Expected structure for custom loaders:
interface Loader {
name: string;
test: RegExp;
process: (this: LoaderContext, input: Payload) => Promise<Payload> | Payload;
}Usage Example:
postcss({
loaders: [
{
name: 'my-loader',
test: /\.mycss$/,
process({ code }) {
// Transform the code
return { code: transformedCode };
}
}
]
});