1 | <div align="center">
|
2 | <a href="https://github.com/webpack/webpack">
|
3 | <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
|
4 | </a>
|
5 | </div>
|
6 |
|
7 | [![npm][npm]][npm-url]
|
8 | [![node][node]][node-url]
|
9 | [![deps][deps]][deps-url]
|
10 | [![tests][tests]][tests-url]
|
11 | [![cover][cover]][cover-url]
|
12 | [![chat][chat]][chat-url]
|
13 | [![size][size]][size-url]
|
14 |
|
15 | # css-minimizer-webpack-plugin
|
16 |
|
17 | This plugin uses [cssnano](https://cssnano.co) to optimize and minify your CSS.
|
18 |
|
19 | 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 caching and works in parallel mode.
|
20 |
|
21 | ## Getting Started
|
22 |
|
23 | To begin, you'll need to install `css-minimizer-webpack-plugin`:
|
24 |
|
25 | ```console
|
26 | $ npm install css-minimizer-webpack-plugin --save-dev
|
27 | ```
|
28 |
|
29 | Then add the plugin to your `webpack` configuration. For example:
|
30 |
|
31 | **webpack.config.js**
|
32 |
|
33 | ```js
|
34 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
35 | const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
36 |
|
37 | module.exports = {
|
38 | module: {
|
39 | rules: [
|
40 | {
|
41 | test: /.s?css$/,
|
42 | use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
43 | },
|
44 | ],
|
45 | },
|
46 | optimization: {
|
47 | minimizer: [
|
48 | // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
|
49 | // `...`,
|
50 | new CssMinimizerPlugin(),
|
51 | ],
|
52 | },
|
53 | plugins: [new MiniCssExtractPlugin()],
|
54 | };
|
55 | ```
|
56 |
|
57 | This will enable CSS optimization only in production mode.
|
58 |
|
59 | If you want to run it also in development set the `optimization.minimize` option to `true`:
|
60 |
|
61 | **webpack.config.js**
|
62 |
|
63 | ```js
|
64 | // [...]
|
65 | module.exports = {
|
66 | optimization: {
|
67 | // [...]
|
68 | minimize: true,
|
69 | },
|
70 | };
|
71 | ```
|
72 |
|
73 | And run `webpack` via your preferred method.
|
74 |
|
75 | ## Note about source maps
|
76 |
|
77 | **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.**
|
78 |
|
79 | Why? Because CSS support only these source map types.
|
80 |
|
81 | The plugin respect the [`devtool`](https://webpack.js.org/configuration/devtool/) and using the `SourceMapDevToolPlugin` plugin.
|
82 | Using supported `devtool` values enable source map generation.
|
83 | Using `SourceMapDevToolPlugin` with enabled the `columns` option enables source map generation.
|
84 |
|
85 | Use source maps to map error message locations to modules (this slows down the compilation).
|
86 | If you use your own `minify` function please read the `minify` section for handling source maps correctly.
|
87 |
|
88 | ## Options
|
89 |
|
90 | | Name | Type | Default | Description |
|
91 | | :-----------------------------------------: | :--------------------------------------------: | :--------------------------------: | :---------------------------------------------------------------------- |
|
92 | | **[`test`](#test)** | `String\|RegExp\|Array<String\|RegExp>` | `/\.css(\?.*)?$/i` | Test to match files against. |
|
93 | | **[`include`](#include)** | `String\|RegExp\|Array<String\|RegExp>` | `undefined` | Files to include. |
|
94 | | **[`exclude`](#exclude)** | `String\|RegExp\|Array<String\|RegExp>` | `undefined` | Files to exclude. |
|
95 | | **[`parallel`](#parallel)** | `Boolean\|Number` | `true` | Enable/disable multi-process parallel running. |
|
96 | | **[`minify`](#minify)** | `Function\|Array<Function>` | `CssMinimizerPlugin.cssnanoMinify` | Allows to override default minify function. |
|
97 | | **[`minimizerOptions`](#minimizeroptions)** | `Object\|Array<Object>` | `{ preset: 'default' }` | Cssnano optimisations [options](https://cssnano.co/docs/optimisations). |
|
98 | | **[`warningsFilter`](#warningsfilter)** | `Function<(warning, file, source) -> Boolean>` | `() => true` | Allow to filter css-minimizer warnings. |
|
99 |
|
100 | ### `test`
|
101 |
|
102 | Type: `String|RegExp|Array<String|RegExp>` - default: `/\.css(\?.*)?$/i`
|
103 |
|
104 | Test to match files against.
|
105 |
|
106 | ```js
|
107 | module.exports = {
|
108 | optimization: {
|
109 | minimize: true,
|
110 | minimizer: [
|
111 | new CssMinimizerPlugin({
|
112 | test: /\.foo\.css$/i,
|
113 | }),
|
114 | ],
|
115 | },
|
116 | };
|
117 | ```
|
118 |
|
119 | ### `include`
|
120 |
|
121 | Type: `String|RegExp|Array<String|RegExp>`
|
122 | Default: `undefined`
|
123 |
|
124 | Files to include.
|
125 |
|
126 | **webpack.config.js**
|
127 |
|
128 | ```js
|
129 | module.exports = {
|
130 | optimization: {
|
131 | minimize: true,
|
132 | minimizer: [
|
133 | new CssMinimizerPlugin({
|
134 | include: /\/includes/,
|
135 | }),
|
136 | ],
|
137 | },
|
138 | };
|
139 | ```
|
140 |
|
141 | ### `exclude`
|
142 |
|
143 | Type: `String|RegExp|Array<String|RegExp>`
|
144 | Default: `undefined`
|
145 |
|
146 | Files to exclude.
|
147 |
|
148 | **webpack.config.js**
|
149 |
|
150 | ```js
|
151 | module.exports = {
|
152 | optimization: {
|
153 | minimize: true,
|
154 | minimizer: [
|
155 | new CssMinimizerPlugin({
|
156 | exclude: /\/excludes/,
|
157 | }),
|
158 | ],
|
159 | },
|
160 | };
|
161 | ```
|
162 |
|
163 | ### `parallel`
|
164 |
|
165 | Type: `Boolean|Number`
|
166 | Default: `true`
|
167 |
|
168 | Use multi-process parallel running to improve the build speed.
|
169 | Default number of concurrent runs: `os.cpus().length - 1`.
|
170 |
|
171 | > ℹ️ Parallelization can speed up your build significantly and is therefore **highly recommended**.
|
172 | > If a parallelization is enabled, the packages in `minimizerOptions` must be required via strings (`packageName` or `require.resolve(packageName)`). Read more in [`minimizerOptions`](#minimizeroptions)
|
173 |
|
174 | #### `Boolean`
|
175 |
|
176 | Enable/disable multi-process parallel running.
|
177 |
|
178 | **webpack.config.js**
|
179 |
|
180 | ```js
|
181 | module.exports = {
|
182 | optimization: {
|
183 | minimize: true,
|
184 | minimizer: [
|
185 | new CssMinimizerPlugin({
|
186 | parallel: true,
|
187 | }),
|
188 | ],
|
189 | },
|
190 | };
|
191 | ```
|
192 |
|
193 | #### `Number`
|
194 |
|
195 | Enable multi-process parallel running and set number of concurrent runs.
|
196 |
|
197 | **webpack.config.js**
|
198 |
|
199 | ```js
|
200 | module.exports = {
|
201 | optimization: {
|
202 | minimize: true,
|
203 | minimizer: [
|
204 | new CssMinimizerPlugin({
|
205 | parallel: 4,
|
206 | }),
|
207 | ],
|
208 | },
|
209 | };
|
210 | ```
|
211 |
|
212 | ### `minify`
|
213 |
|
214 | Type: `Function|Array<Function>`
|
215 | Default: `CssMinimizerPlugin.cssnanoMinify`
|
216 |
|
217 | Allows overriding default minify function.
|
218 | By default, plugin uses [cssnano](https://github.com/cssnano/cssnano) package.
|
219 | Useful for using and testing unpublished versions or forks.
|
220 |
|
221 | Possible options:
|
222 |
|
223 | - CssMinimizerPlugin.cssnanoMinify
|
224 | - CssMinimizerPlugin.cssoMinify
|
225 | - CssMinimizerPlugin.cleanCssMinify
|
226 | - CssMinimizerPlugin.esbuildMinify
|
227 | - CssMinimizerPlugin.parcelCssMinify
|
228 | - `async (data, inputMap, minimizerOptions) => {return {code: "a{color: red}", map: "...", warnings: [], errors: []}}`
|
229 |
|
230 | > ⚠️ **Always use `require` inside `minify` function when `parallel` option enabled**.
|
231 |
|
232 | #### `Function`
|
233 |
|
234 | **webpack.config.js**
|
235 |
|
236 | ```js
|
237 | module.exports = {
|
238 | optimization: {
|
239 | minimize: true,
|
240 | minimizer: [
|
241 | new CssMinimizerPlugin({
|
242 | minimizerOptions: {
|
243 | level: {
|
244 | 1: {
|
245 | roundingPrecision: "all=3,px=5",
|
246 | },
|
247 | },
|
248 | },
|
249 | minify: CssMinimizerPlugin.cleanCssMinify,
|
250 | }),
|
251 | ],
|
252 | },
|
253 | };
|
254 | ```
|
255 |
|
256 | #### `Array`
|
257 |
|
258 | If an array of functions is passed to the `minify` option, the `minimizerOptions` must also be an array.
|
259 | The function index in the `minify` array corresponds to the options object with the same index in the `minimizerOptions` array.
|
260 |
|
261 | **webpack.config.js**
|
262 |
|
263 | ```js
|
264 | module.exports = {
|
265 | optimization: {
|
266 | minimize: true,
|
267 | minimizer: [
|
268 | new CssMinimizerPlugin({
|
269 | minimizerOptions: [
|
270 | {}, // Options for the first function (CssMinimizerPlugin.cssnanoMinify)
|
271 | {}, // Options for the second function (CssMinimizerPlugin.cleanCssMinify)
|
272 | {}, // Options for the third function
|
273 | ],
|
274 | minify: [
|
275 | CssMinimizerPlugin.cssnanoMinify,
|
276 | CssMinimizerPlugin.cleanCssMinify,
|
277 | async (data, inputMap, minimizerOptions) => {
|
278 | // To do something
|
279 | return {
|
280 | code: `a{color: red}`,
|
281 | map: `{"version": "3", ...}`,
|
282 | warnings: [],
|
283 | errors: [],
|
284 | };
|
285 | },
|
286 | ],
|
287 | }),
|
288 | ],
|
289 | },
|
290 | };
|
291 | ```
|
292 |
|
293 | ### `minimizerOptions`
|
294 |
|
295 | Type: `Object|Array<Object>`
|
296 | Default: `{ preset: 'default' }`
|
297 |
|
298 | Cssnano optimisations [options](https://cssnano.co/docs/optimisations).
|
299 |
|
300 | #### `Object`
|
301 |
|
302 | ```js
|
303 | module.exports = {
|
304 | optimization: {
|
305 | minimize: true,
|
306 | minimizer: [
|
307 | new CssMinimizerPlugin({
|
308 | minimizerOptions: {
|
309 | preset: [
|
310 | "default",
|
311 | {
|
312 | discardComments: { removeAll: true },
|
313 | },
|
314 | ],
|
315 | },
|
316 | }),
|
317 | ],
|
318 | },
|
319 | };
|
320 | ```
|
321 |
|
322 | #### `Array`
|
323 |
|
324 | The function index in the `minify` array corresponds to the options object with the same index in the `minimizerOptions` array.
|
325 | If you use `minimizerOptions` like object, all `minify` function accept it.
|
326 |
|
327 | > If a parallelization is enabled, the packages in `minimizerOptions` must be required via strings (`packageName` or `require.resolve(packageName)`). In this case, we shouldn't use `require`/`import`.
|
328 |
|
329 | ```js
|
330 | module.exports = {
|
331 | optimization: {
|
332 | minimize: true,
|
333 | minimizer: [
|
334 | new CssMinimizerPlugin({
|
335 | minimizerOptions: {
|
336 | preset: require.resolve("cssnano-preset-simple"),
|
337 | },
|
338 | }),
|
339 | ],
|
340 | },
|
341 | };
|
342 | ```
|
343 |
|
344 | ##### `processorOptions` (⚠ only cssnano)
|
345 |
|
346 | Type: `Object`
|
347 | Default: `{ from: assetName }`
|
348 |
|
349 | Allows filtering options [`processoptions`](https://postcss.org/api/#processoptions) for the cssnano.
|
350 | The `parser`,` stringifier` and `syntax` can be either a function or a string indicating the module that will be imported.
|
351 |
|
352 | > ⚠️ **If a function is passed, the `parallel` option must be disabled.**.
|
353 |
|
354 | ```js
|
355 | import sugarss from "sugarss";
|
356 |
|
357 | module.exports = {
|
358 | optimization: {
|
359 | minimize: true,
|
360 | minimizer: [
|
361 | new CssMinimizerPlugin({
|
362 | parallel: false,
|
363 | minimizerOptions: {
|
364 | processorOptions: {
|
365 | parser: sugarss,
|
366 | },
|
367 | },
|
368 | }),
|
369 | ],
|
370 | },
|
371 | };
|
372 | ```
|
373 |
|
374 | ```js
|
375 | module.exports = {
|
376 | optimization: {
|
377 | minimize: true,
|
378 | minimizer: [
|
379 | new CssMinimizerPlugin({
|
380 | minimizerOptions: {
|
381 | processorOptions: {
|
382 | parser: "sugarss",
|
383 | },
|
384 | },
|
385 | }),
|
386 | ],
|
387 | },
|
388 | };
|
389 | ```
|
390 |
|
391 | ### `warningsFilter`
|
392 |
|
393 | Type: `Function<(warning, file, source) -> Boolean>`
|
394 | Default: `() => true`
|
395 |
|
396 | Allow filtering css-minimizer warnings (By default [cssnano](https://github.com/cssnano/cssnano)).
|
397 | Return `true` to keep the warning, a falsy value (`false`/`null`/`undefined`) otherwise.
|
398 |
|
399 | > ⚠️ The `source` argument will contain `undefined` if you don't use source maps.
|
400 |
|
401 | **webpack.config.js**
|
402 |
|
403 | ```js
|
404 | module.exports = {
|
405 | optimization: {
|
406 | minimize: true,
|
407 | minimizer: [
|
408 | new CssMinimizerPlugin({
|
409 | warningsFilter: (warning, file, source) => {
|
410 | if (/Dropping unreachable code/i.test(warning)) {
|
411 | return true;
|
412 | }
|
413 |
|
414 | if (/file\.css/i.test(file)) {
|
415 | return true;
|
416 | }
|
417 |
|
418 | if (/source\.css/i.test(source)) {
|
419 | return true;
|
420 | }
|
421 |
|
422 | return false;
|
423 | },
|
424 | }),
|
425 | ],
|
426 | },
|
427 | };
|
428 | ```
|
429 |
|
430 | ## Examples
|
431 |
|
432 | ### Use sourcemaps
|
433 |
|
434 | Don't forget to enable `sourceMap` options for all loaders.
|
435 |
|
436 | ```js
|
437 | const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
438 |
|
439 | module.exports = {
|
440 | devtool: "source-map",
|
441 | module: {
|
442 | rules: [
|
443 | {
|
444 | test: /.s?css$/,
|
445 | use: [
|
446 | MiniCssExtractPlugin.loader,
|
447 | { loader: "css-loader", options: { sourceMap: true } },
|
448 | { loader: "sass-loader", options: { sourceMap: true } },
|
449 | ],
|
450 | },
|
451 | ],
|
452 | },
|
453 | optimization: {
|
454 | minimizer: [new CssMinimizerPlugin()],
|
455 | },
|
456 | plugins: [new MiniCssExtractPlugin()],
|
457 | };
|
458 | ```
|
459 |
|
460 | ### Remove all comments
|
461 |
|
462 | Remove all comments (including comments starting with `/*!`).
|
463 |
|
464 | ```js
|
465 | module.exports = {
|
466 | optimization: {
|
467 | minimizer: [
|
468 | new CssMinimizerPlugin({
|
469 | minimizerOptions: {
|
470 | preset: [
|
471 | "default",
|
472 | {
|
473 | discardComments: { removeAll: true },
|
474 | },
|
475 | ],
|
476 | },
|
477 | }),
|
478 | ],
|
479 | },
|
480 | };
|
481 | ```
|
482 |
|
483 | ### Using custom minifier [csso](https://github.com/css/csso)
|
484 |
|
485 | **webpack.config.js**
|
486 |
|
487 | ```js
|
488 | module.exports = {
|
489 | // Uncomment if you need source maps
|
490 | // devtool: "source-map",
|
491 | optimization: {
|
492 | minimize: true,
|
493 | minimizer: [
|
494 | new CssMinimizerPlugin({
|
495 | minify: CssMinimizerPlugin.cssoMinify,
|
496 | // Uncomment this line for options
|
497 | // minimizerOptions: { restructure: false },
|
498 | }),
|
499 | ],
|
500 | },
|
501 | };
|
502 | ```
|
503 |
|
504 | ### Using custom minifier [clean-css](https://github.com/jakubpawlowicz/clean-css)
|
505 |
|
506 | **webpack.config.js**
|
507 |
|
508 | ```js
|
509 | module.exports = {
|
510 | // Uncomment if you need source maps
|
511 | // devtool: "source-map",
|
512 | optimization: {
|
513 | minimize: true,
|
514 | minimizer: [
|
515 | new CssMinimizerPlugin({
|
516 | minify: CssMinimizerPlugin.cleanCssMinify,
|
517 | // Uncomment this line for options
|
518 | // minimizerOptions: { compatibility: 'ie11,-properties.merging' },
|
519 | }),
|
520 | ],
|
521 | },
|
522 | };
|
523 | ```
|
524 |
|
525 | ### Using custom minifier [esbuild](https://github.com/evanw/esbuild)
|
526 |
|
527 | **webpack.config.js**
|
528 |
|
529 | ```js
|
530 | module.exports = {
|
531 | // Uncomment if you need source maps
|
532 | // devtool: "source-map",
|
533 | optimization: {
|
534 | minimize: true,
|
535 | minimizer: [
|
536 | new CssMinimizerPlugin({
|
537 | minify: CssMinimizerPlugin.esbuildMinify,
|
538 | }),
|
539 | ],
|
540 | },
|
541 | };
|
542 | ```
|
543 |
|
544 | ### Using custom minifier [@parcel/css](https://github.com/parcel-bundler/parcel-css)
|
545 |
|
546 | **webpack.config.js**
|
547 |
|
548 | ```js
|
549 | module.exports = {
|
550 | // Uncomment if you need source maps
|
551 | // devtool: "source-map",
|
552 | optimization: {
|
553 | minimize: true,
|
554 | minimizer: [
|
555 | new CssMinimizerPlugin({
|
556 | minify: CssMinimizerPlugin.parcelCssMinify,
|
557 | // Uncomment this line for options
|
558 | // minimizerOptions: { targets: { ie: 11 }, drafts: { nesting: true } },
|
559 | }),
|
560 | ],
|
561 | },
|
562 | };
|
563 | ```
|
564 |
|
565 | ## Contributing
|
566 |
|
567 | Please take a moment to read our contributing guidelines if you haven't yet done so.
|
568 |
|
569 | [CONTRIBUTING](./.github/CONTRIBUTING.md)
|
570 |
|
571 | ## License
|
572 |
|
573 | [MIT](./LICENSE)
|
574 |
|
575 | [npm]: https://img.shields.io/npm/v/css-minimizer-webpack-plugin.svg
|
576 | [npm-url]: https://npmjs.com/package/css-minimizer-webpack-plugin
|
577 | [node]: https://img.shields.io/node/v/css-minimizer-webpack-plugin.svg
|
578 | [node-url]: https://nodejs.org
|
579 | [deps]: https://david-dm.org/webpack-contrib/css-minimizer-webpack-plugin.svg
|
580 | [deps-url]: https://david-dm.org/webpack-contrib/css-minimizer-webpack-plugin
|
581 | [tests]: https://github.com/webpack-contrib/css-minimizer-webpack-plugin/workflows/css-minimizer-webpack-plugin/badge.svg
|
582 | [tests-url]: https://github.com/webpack-contrib/css-minimizer-webpack-plugin/actions
|
583 | [cover]: https://codecov.io/gh/webpack-contrib/css-minimizer-webpack-plugin/branch/master/graph/badge.svg
|
584 | [cover-url]: https://codecov.io/gh/webpack-contrib/css-minimizer-webpack-plugin
|
585 | [chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
|
586 | [chat-url]: https://gitter.im/webpack/webpack
|
587 | [size]: https://packagephobia.now.sh/badge?p=css-minimizer-webpack-plugin
|
588 | [size-url]: https://packagephobia.now.sh/result?p=css-minimizer-webpack-plugin
|