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