[![npm][npm]][npm-url] [![node][node]][node-url] [![deps][deps]][deps-url] [![tests][tests]][tests-url] [![cover][cover]][cover-url] [![chat][chat]][chat-url] [![size][size]][size-url] # css-minimizer-webpack-plugin This plugin uses [cssnano](https://cssnano.co) to optimize and minify your CSS. Just like [optimize-css-assets-webpack-plugin](https://github.com/NMFR/optimize-css-assets-webpack-plugin) but more accurate with source maps and assets using query string, allows to cache and works in parallel mode. ## Getting Started To begin, you'll need to install `css-minimizer-webpack-plugin`: ```console $ npm install css-minimizer-webpack-plugin --save-dev ``` Then add the plugin to your `webpack` configuration. For example: **webpack.config.js** ```js const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); module.exports = { module: { loaders: [ { test: /.s?css$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'], }, ], }, optimization: { minimize: true, minimizer: [ // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line // `...`, new CssMinimizerPlugin(), ], }, }; ``` This will enable CSS optimization only in production mode. If you want to run it also in development set the `optimization.minimize` option to `true`. And run `webpack` via your preferred method. ## Options ### `test` Type: `String|RegExp|Array` - default: `/\.css(\?.*)?$/i` Test to match files against. ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ test: /\.foo\.css$/i, }), ], }, }; ``` ### `include` Type: `String|RegExp|Array` Default: `undefined` Files to include. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ include: /\/includes/, }), ], }, }; ``` ### `exclude` Type: `String|RegExp|Array` Default: `undefined` Files to exclude. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ exclude: /\/excludes/, }), ], }, }; ``` ### `cache` > ⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache. Type: `Boolean|String` Default: `true` Enable file caching. Default path to cache directory: `node_modules/.cache/css-minimizer-webpack-plugin`. > ℹ️ If you use your own `minify` function please read the `minify` section for cache invalidation correctly. #### `Boolean` Enable/disable file caching. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ cache: true, }), ], }, }; ``` #### `String` Enable file caching and set path to cache directory. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ cache: 'path/to/cache', }), ], }, }; ``` ### `cacheKeys` > ⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache. Type: `Function<(defaultCacheKeys, file) -> Object>` Default: `defaultCacheKeys => defaultCacheKeys` Allows you to override default cache keys. Default cache keys: ```js ({ cssMinimizer: require('cssnano/package.json').version, // cssnano version 'css-minimizer-webpack-plugin': require('../package.json').version, // plugin version 'css-minimizer-webpack-plugin-options': this.options, // plugin options path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file, // asset path hash: crypto.createHash('md4').update(input).digest('hex'), // source file hash }); ``` **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ cache: true, cacheKeys: (defaultCacheKeys, file) => { defaultCacheKeys.myCacheKey = 'myCacheKeyValue'; return defaultCacheKeys; }, }), ], }, }; ``` ### `parallel` Type: `Boolean|Number` Default: `true` Use multi-process parallel running to improve the build speed. Default number of concurrent runs: `os.cpus().length - 1`. > ℹ️ Parallelization can speedup your build significantly and is therefore **highly recommended**. #### `Boolean` Enable/disable multi-process parallel running. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ parallel: true, }), ], }, }; ``` #### `Number` Enable multi-process parallel running and set number of concurrent runs. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ parallel: 4, }), ], }, }; ``` ### `sourceMap` Type: `Boolean|Object` Default: `false` (see below for details around `devtool` value and `SourceMapDevToolPlugin` plugin) Enable (and configure) source map support. Use [PostCss SourceMap options](https://github.com/postcss/postcss-loader#sourcemap). Default configuration when enabled: `{ inline: false }`. **Works only with `source-map`, `inline-source-map`, `hidden-source-map` and `nosources-source-map` values for the [`devtool`](https://webpack.js.org/configuration/devtool/) option.** Why? Because CSS support only these source map types. The plugin respect the [`devtool`](https://webpack.js.org/configuration/devtool/) and using the `SourceMapDevToolPlugin` plugin. Using supported `devtool` values enable source map generation. Using `SourceMapDevToolPlugin` with enabled the `columns` option enables source map generation. Use source maps to map error message locations to modules (this slows down the compilation). If you use your own `minify` function please read the `minify` section for handling source maps correctly. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ sourceMap: true, }), ], }, }; ``` ### `minify` Type: `Function` Default: `undefined` Allows you to override default minify function. By default plugin uses [cssnano](https://github.com/cssnano/cssnano) package. Useful for using and testing unpublished versions or forks. > ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ sourceMap: true, minify: (data, inputMap, minimizerOptions) => { const postcss = require('postcss'); const plugin = postcss.plugin( 'custom-plugin', () => (css, result) => { // custom code } ); const [[filename, input]] = Object.entries(data); const postcssOptions = { from: filename, to: filename, map: { prev: inputMap, }, }; return postcss([plugin]) .process(input, postcssOptions) .then((result) => { return { css: result.css, map: result.map, warnings: result.warnings(), }; }); }, }), ], }, }; ``` ### `minimizerOptions` Type: `Object` Default: `{ preset: 'default' }` Cssnano optimisations [options](https://cssnano.co/docs/optimisations). ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ minimizerOptions: { preset: [ 'default', { discardComments: { removeAll: true }, }, ], }, }), ], }, }; ``` #### `processorOptions` Type: `Object` Default: `{ to: assetName, from: assetName }` Allows to specify options [`processoptions`](https://postcss.org/api/#processoptions) for the cssnano. The `parser`,` stringifier` and `syntax` can be either a function or a string indicating the module that will be imported. > ⚠️ **If a function is passed, the `parallel` option must be disabled.**. ```js import sugarss from 'sugarss'; module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ parallel: false, minimizerOptions: { processorOptions: { parser: sugarss, }, }, }), ], }, }; ``` ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ minimizerOptions: { processorOptions: { parser: 'sugarss', }, }, }), ], }, }; ``` ### `warningsFilter` Type: `Function<(warning, file, source) -> Boolean>` Default: `() => true` Allow to filter css-minimizer warnings (By default [cssnano](https://github.com/cssnano/cssnano)). Return `true` to keep the warning, a falsy value (`false`/`null`/`undefined`) otherwise. > ⚠️ The `source` argument will contain `undefined` if you don't use source maps. **webpack.config.js** ```js module.exports = { optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ warningsFilter: (warning, file, source) => { if (/Dropping unreachable code/i.test(warning)) { return true; } if (/file\.css/i.test(file)) { return true; } if (/source\.css/i.test(source)) { return true; } return false; }, }), ], }, }; ``` ## Examples ### Use sourcemaps Don't forget to enable `sourceMap` options for all loaders. ```js const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); module.exports = { module: { loaders: [ { test: /.s?css$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { sourceMap: true } }, { loader: 'sass-loader', options: { sourceMap: true } }, ], }, ], }, optimization: { minimizer: [ new CssMinimizerPlugin({ sourceMap: true, }), ], }, }; ``` ### Remove all comments Remove all comments (including comments starting with `/*!`). ```js module.exports = { optimization: { minimizer: [ new CssMinimizerPlugin({ minimizerOptions: { preset: [ 'default', { discardComments: { removeAll: true }, }, ], }, }), ], }, }; ``` ### Using custom minifier [csso](https://github.com/css/csso) By default plugin uses [cssnano](https://github.com/cssnano/cssnano) package. It is possible to use another minify function. > ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**. **webpack.config.js** ```js module.exports = { devtool: 'source-map', optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ sourceMap: true, minify: async (data, inputMap) => { const csso = require('csso'); const sourcemap = require('source-map'); const [[filename, input]] = Object.entries(data); const minifiedCss = csso.minify(input, { filename: filename, sourceMap: true, }); if (inputMap) { minifiedCss.map.applySourceMap( new sourcemap.SourceMapConsumer(inputMap), filename ); } return { css: minifiedCss.css, map: minifiedCss.map.toJSON(), }; }, }), ], }, }; ``` ### Using custom minifier [clean-css](https://github.com/jakubpawlowicz/clean-css) By default plugin uses [cssnano](https://github.com/cssnano/cssnano) package. It is possible to use another minify function. > ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**. **webpack.config.js** ```js module.exports = { devtool: 'source-map', optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ sourceMap: true, minify: async (data, inputMap) => { // eslint-disable-next-line global-require const CleanCSS = require('clean-css'); const [[filename, input]] = Object.entries(data); const minifiedCss = await new CleanCSS({ sourceMap: true }).minify({ [filename]: { styles: input, sourceMap: inputMap, }, }); return { css: minifiedCss.styles, map: minifiedCss.sourceMap.toJSON(), warnings: minifiedCss.warnings, }; }, }), ], }, }; ``` ## Contributing Please take a moment to read our contributing guidelines if you haven't yet done so. [CONTRIBUTING](./.github/CONTRIBUTING.md) ## License [MIT](./LICENSE) [npm]: https://img.shields.io/npm/v/css-minimizer-webpack-plugin.svg [npm-url]: https://npmjs.com/package/css-minimizer-webpack-plugin [node]: https://img.shields.io/node/v/css-minimizer-webpack-plugin.svg [node-url]: https://nodejs.org [deps]: https://david-dm.org/webpack-contrib/css-minimizer-webpack-plugin.svg [deps-url]: https://david-dm.org/webpack-contrib/css-minimizer-webpack-plugin [tests]: https://github.com/webpack-contrib/css-minimizer-webpack-plugin/workflows/css-minimizer-webpack-plugin/badge.svg [tests-url]: https://github.com/webpack-contrib/css-minimizer-webpack-plugin/actions [cover]: https://codecov.io/gh/webpack-contrib/css-minimizer-webpack-plugin/branch/master/graph/badge.svg [cover-url]: https://codecov.io/gh/webpack-contrib/css-minimizer-webpack-plugin [chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg [chat-url]: https://gitter.im/webpack/webpack [size]: https://packagephobia.now.sh/badge?p=css-minimizer-webpack-plugin [size-url]: https://packagephobia.now.sh/result?p=css-minimizer-webpack-plugin