source: frontend/node_modules/mini-css-extract-plugin/README.md

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 30.9 KB
Line 
1<div align="center">
2 <img width="200" height="200" src="https://cdn.worldvectorlogo.com/logos/logo-javascript.svg">
3 <a href="https://webpack.js.org/">
4 <img width="200" height="200" vspace="" hspace="25" src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon-square-big.svg">
5 </a>
6 <h1>mini-css-extract-plugin</h1>
7</div>
8
9[![npm][npm]][npm-url]
10[![node][node]][node-url]
11[![tests][tests]][tests-url]
12[![coverage][cover]][cover-url]
13[![discussion][discussion]][discussion-url]
14[![size][size]][size-url]
15
16# mini-css-extract-plugin
17
18This plugin extracts CSS into separate files. It creates a CSS file for each JS file that contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.
19
20It builds on top of a new webpack v5 feature and requires webpack 5 to work.
21
22Compared to the extract-text-webpack-plugin:
23
24- Async loading
25- No duplicate compilation (performance)
26- Easier to use
27- Specific to CSS
28
29## Getting Started
30
31To begin, you'll need to install `mini-css-extract-plugin`:
32
33```console
34npm install --save-dev mini-css-extract-plugin
35```
36
37or
38
39```console
40yarn add -D mini-css-extract-plugin
41```
42
43or
44
45```console
46pnpm add -D mini-css-extract-plugin
47```
48
49It's recommended to combine `mini-css-extract-plugin` with the [`css-loader`](https://github.com/webpack/css-loader)
50
51Then add the loader and the plugin to your `webpack` configuration. For example:
52
53**style.css**
54
55```css
56body {
57 background: green;
58}
59```
60
61**component.js**
62
63```js
64import "./style.css";
65```
66
67**webpack.config.js**
68
69```js
70const MiniCssExtractPlugin = require("mini-css-extract-plugin");
71
72module.exports = {
73 plugins: [new MiniCssExtractPlugin()],
74 module: {
75 rules: [
76 {
77 test: /\.css$/i,
78 use: [MiniCssExtractPlugin.loader, "css-loader"],
79 },
80 ],
81 },
82};
83```
84
85> [!WARNING]
86>
87> Note that if you import CSS from your webpack entrypoint or import styles in the [initial](https://webpack.js.org/concepts/under-the-hood/#chunks) chunk, `mini-css-extract-plugin` will not load this CSS into the page automatically. Please use [`html-webpack-plugin`](https://github.com/jantimon/html-webpack-plugin) for automatic generation `link` tags or manually include a `<link>` tag in your `index.html` file.
88
89> [!WARNING]
90>
91> Source maps works only for `source-map`/`nosources-source-map`/`hidden-nosources-source-map`/`hidden-source-map` values because CSS only supports source maps with the `sourceMappingURL` comment (i.e. `//# sourceMappingURL=style.css.map`). If you need set `devtool` to another value you can enable source maps generation for extracted CSS using [`sourceMap: true`](https://github.com/webpack/css-loader#sourcemap) for `css-loader`.
92
93## Options
94
95### Plugin Options
96
97- **[`filename`](#filename)**
98- **[`chunkFilename`](#chunkFilename)**
99- **[`ignoreOrder`](#ignoreOrder)**
100- **[`insert`](#insert)**
101- **[`attributes`](#attributes)**
102- **[`linkType`](#linkType)**
103- **[`runtime`](#runtime)**
104- **[`experimentalUseImportModule`](#experimentalUseImportModule)**
105
106#### `filename`
107
108Type:
109
110```ts
111type filename =
112 | string
113 | ((pathData: PathData, assetInfo?: AssetInfo) => string);
114```
115
116Default: `[name].css`
117
118This option determines the name of each output CSS file.
119
120Works like [`output.filename`](https://webpack.js.org/configuration/output/#outputfilename)
121
122#### `chunkFilename`
123
124Type:
125
126```ts
127type chunkFilename =
128 | string
129 | ((pathData: PathData, assetInfo?: AssetInfo) => string);
130```
131
132Default: `Based on filename`
133
134> Specifying `chunkFilename` as a `function` is only available in webpack@5
135
136This option determines the name of non-entry chunk files.
137
138Works like [`output.chunkFilename`](https://webpack.js.org/configuration/output/#outputchunkfilename)
139
140#### `ignoreOrder`
141
142Type:
143
144```ts
145type ignoreOrder = boolean;
146```
147
148Default: `false`
149
150Remove Order Warnings.
151See [examples](#remove-order-warnings) for more details.
152
153#### `insert`
154
155Type:
156
157```ts
158type insert = string | ((linkTag: HTMLLinkElement) => void);
159```
160
161Default: `document.head.appendChild(linkTag);`
162
163Inserts the `link` tag at the given position for [non-initial (async)](https://webpack.js.org/concepts/under-the-hood/#chunks) CSS chunks
164
165> [!WARNING]
166>
167> Only applicable for [non-initial (async)](https://webpack.js.org/concepts/under-the-hood/#chunks) chunks.
168
169By default, the `mini-css-extract-plugin` appends styles (`<link>` elements) to `document.head` of the current `window`.
170
171However in some circumstances it might be necessary to have finer control over the append target or even delay `link` elements insertion.
172For example this is the case when you asynchronously load styles for an application that runs inside of an iframe.
173In such cases `insert` can be configured to be a function or a custom selector.
174
175If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement), make sure that the parent document has sufficient access rights to reach into the frame document and append elements to it.
176
177##### `string`
178
179Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).
180A new `<link>` element will be inserted after the found item.
181
182**webpack.config.js**
183
184```js
185new MiniCssExtractPlugin({
186 insert: "#some-element",
187});
188```
189
190A new `<link>` tag will be inserted after the element with the ID `some-element`.
191
192##### `function`
193
194Allows to override default behavior and insert styles at any position.
195
196> ⚠ Do not forget that this code will run in the browser alongside your application. Since not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc we recommend you to use only ECMA 5 features and syntax.
197>
198> > ⚠ The `insert` function is serialized to string and passed to the plugin. This means that it won't have access to the scope of the webpack configuration module.
199
200**webpack.config.js**
201
202```js
203new MiniCssExtractPlugin({
204 insert(linkTag) {
205 const reference = document.querySelector("#some-element");
206 if (reference) {
207 reference.parentNode.insertBefore(linkTag, reference);
208 }
209 },
210});
211```
212
213A new `<link>` tag will be inserted before the element with the ID `some-element`.
214
215#### `attributes`
216
217Type:
218
219```ts
220type attributes = Record<string, string>;
221```
222
223Default: `{}`
224
225> [!WARNING]
226>
227> Only applies to [non-initial (async)](https://webpack.js.org/concepts/under-the-hood/#chunks) chunks.
228
229If defined, the `mini-css-extract-plugin` will attach given attributes with their values on `<link>` element.
230
231**webpack.config.js**
232
233```js
234const MiniCssExtractPlugin = require("mini-css-extract-plugin");
235
236module.exports = {
237 plugins: [
238 new MiniCssExtractPlugin({
239 attributes: {
240 id: "target",
241 "data-target": "example",
242 },
243 }),
244 ],
245 module: {
246 rules: [
247 {
248 test: /\.css$/i,
249 use: [MiniCssExtractPlugin.loader, "css-loader"],
250 },
251 ],
252 },
253};
254```
255
256> [!NOTE]
257>
258> It's only applied to dynamically loaded CSS chunks.
259> If you want to modify `<link>` attributes inside HTML file, please use [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin)
260
261#### `linkType`
262
263Type:
264
265```ts
266type linkType = string | boolean;
267```
268
269Default: `text/css`
270
271This option allows loading asynchronous chunks with a custom link type, such as `<link type="text/css" ...>`.
272
273##### `string`
274
275Possible values: `text/css`
276
277**webpack.config.js**
278
279```js
280const MiniCssExtractPlugin = require("mini-css-extract-plugin");
281
282module.exports = {
283 plugins: [
284 new MiniCssExtractPlugin({
285 linkType: "text/css",
286 }),
287 ],
288 module: {
289 rules: [
290 {
291 test: /\.css$/i,
292 use: [MiniCssExtractPlugin.loader, "css-loader"],
293 },
294 ],
295 },
296};
297```
298
299##### `boolean`
300
301`false` disables the link `type` attribute entirely.
302
303**webpack.config.js**
304
305```js
306const MiniCssExtractPlugin = require("mini-css-extract-plugin");
307
308module.exports = {
309 plugins: [
310 new MiniCssExtractPlugin({
311 linkType: false,
312 }),
313 ],
314 module: {
315 rules: [
316 {
317 test: /\.css$/i,
318 use: [MiniCssExtractPlugin.loader, "css-loader"],
319 },
320 ],
321 },
322};
323```
324
325#### `runtime`
326
327Type:
328
329```ts
330type runtime = boolean;
331```
332
333Default: `true`
334
335Allows to enable/disable the runtime generation.
336CSS will be still extracted and can be used for a custom loading methods.
337For example, you can use [assets-webpack-plugin](https://github.com/ztoben/assets-webpack-plugin) to retrieve them then use your own runtime code to download assets when needed.
338
339`false` to skip.
340
341**webpack.config.js**
342
343```js
344const MiniCssExtractPlugin = require("mini-css-extract-plugin");
345
346module.exports = {
347 plugins: [
348 new MiniCssExtractPlugin({
349 runtime: false,
350 }),
351 ],
352 module: {
353 rules: [
354 {
355 test: /\.css$/i,
356 use: [MiniCssExtractPlugin.loader, "css-loader"],
357 },
358 ],
359 },
360};
361```
362
363#### `experimentalUseImportModule`
364
365Type:
366
367```ts
368type experimentalUseImportModule = boolean;
369```
370
371Default: `undefined`
372
373Enabled by default if not explicitly enabled (i.e. `true` and `false` allow you to explicitly control this option) and new API is available (at least webpack `5.52.0` is required).
374Boolean values are available since version `5.33.2`, but you need to enable `experiments.executeModule` (not required from webpack `5.52.0`).
375
376Use a new webpack API to execute modules instead of child compilers, significantly improving performance and memory usage.
377
378When combined with `experiments.layers`, this adds a `layer` option to the loader options to specify the layer of the CSS execution.
379
380**webpack.config.js**
381
382```js
383const MiniCssExtractPlugin = require("mini-css-extract-plugin");
384
385module.exports = {
386 plugins: [
387 new MiniCssExtractPlugin({
388 // You don't need this for `>= 5.52.0` due to the fact that this is enabled by default
389 // Required only for `>= 5.33.2 & <= 5.52.0`
390 // Not available/unsafe for `<= 5.33.2`
391 experimentalUseImportModule: true,
392 }),
393 ],
394 module: {
395 rules: [
396 {
397 test: /\.css$/i,
398 use: [MiniCssExtractPlugin.loader, "css-loader"],
399 },
400 ],
401 },
402};
403```
404
405### Loader Options
406
407- **[`publicPath`](#publicPath)**
408- **[`emit`](#emit)**
409- **[`esModule`](#esModule)**
410- **[`defaultExport`](#defaultExport)**
411
412#### `publicPath`
413
414Type:
415
416```ts
417type publicPath =
418 | string
419 | ((resourcePath: string, rootContext: string) => string);
420```
421
422Default: the `publicPath` in `webpackOptions.output`
423
424Specifies a custom public path for the external resources like images, files, etc inside `CSS`.
425Works like [`output.publicPath`](https://webpack.js.org/configuration/output/#outputpublicpath)
426
427##### `string`
428
429**webpack.config.js**
430
431```js
432const MiniCssExtractPlugin = require("mini-css-extract-plugin");
433
434module.exports = {
435 plugins: [
436 new MiniCssExtractPlugin({
437 // Options similar to the same options in webpackOptions.output
438 // both options are optional
439 filename: "[name].css",
440 chunkFilename: "[id].css",
441 }),
442 ],
443 module: {
444 rules: [
445 {
446 test: /\.css$/,
447 use: [
448 {
449 loader: MiniCssExtractPlugin.loader,
450 options: {
451 publicPath: "/public/path/to/",
452 },
453 },
454 "css-loader",
455 ],
456 },
457 ],
458 },
459};
460```
461
462##### `function`
463
464**webpack.config.js**
465
466```js
467const MiniCssExtractPlugin = require("mini-css-extract-plugin");
468
469module.exports = {
470 plugins: [
471 new MiniCssExtractPlugin({
472 // Options similar to the same options in webpackOptions.output
473 // both options are optional
474 filename: "[name].css",
475 chunkFilename: "[id].css",
476 }),
477 ],
478 module: {
479 rules: [
480 {
481 test: /\.css$/,
482 use: [
483 {
484 loader: MiniCssExtractPlugin.loader,
485 options: {
486 publicPath: (resourcePath, context) =>
487 `${path.relative(path.dirname(resourcePath), context)}/`,
488 },
489 },
490 "css-loader",
491 ],
492 },
493 ],
494 },
495};
496```
497
498#### `emit`
499
500Type:
501
502```ts
503type emit = boolean;
504```
505
506Default: `true`
507
508If `true`, emits a file (writes a file to the filesystem).
509If `false`, the plugin will extract the CSS but **will not** emit the file.
510It is often useful to disable this option for server-side packages.
511
512#### `esModule`
513
514Type:
515
516```ts
517type esModule = boolean;
518```
519
520Default: `true`
521
522By default, `mini-css-extract-plugin` generates JS modules that use the ES modules syntax.
523There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).
524
525You can enable a CommonJS syntax using:
526
527**webpack.config.js**
528
529```js
530const MiniCssExtractPlugin = require("mini-css-extract-plugin");
531
532module.exports = {
533 plugins: [new MiniCssExtractPlugin()],
534 module: {
535 rules: [
536 {
537 test: /\.css$/i,
538 use: [
539 {
540 loader: MiniCssExtractPlugin.loader,
541 options: {
542 esModule: false,
543 },
544 },
545 "css-loader",
546 ],
547 },
548 ],
549 },
550};
551```
552
553#### `defaultExport`
554
555Type:
556
557```ts
558type defaultExport = boolean;
559```
560
561Default: `false`
562
563> [!NOTE]
564>
565> This option will work only when you set `namedExport` to `true` in `css-loader`
566
567By default, `mini-css-extract-plugin` generates JS modules based on the `esModule` and `namedExport` options in `css-loader`.
568Using the `esModule` and `namedExport` options will allow you to better optimize your code.
569If you set `esModule: true` and `namedExport: true` for `css-loader` `mini-css-extract-plugin` will generate **only** a named export.
570Our official recommendation is to use only named export for better future compatibility.
571But for some applications, it is not easy to quickly rewrite the code from the default export to a named export.
572
573In case you need both default and named exports, you can enable this option:
574
575**webpack.config.js**
576
577```js
578const MiniCssExtractPlugin = require("mini-css-extract-plugin");
579
580module.exports = {
581 plugins: [new MiniCssExtractPlugin()],
582 module: {
583 rules: [
584 {
585 test: /\.css$/i,
586 use: [
587 {
588 loader: MiniCssExtractPlugin.loader,
589 options: {
590 defaultExport: true,
591 },
592 },
593 {
594 loader: "css-loader",
595 options: {
596 esModule: true,
597 modules: {
598 namedExport: true,
599 },
600 },
601 },
602 ],
603 },
604 ],
605 },
606};
607```
608
609## Examples
610
611### Recommended
612
613For `production` builds, it is recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on. This can be achieved by using the `mini-css-extract-plugin`, because it creates separate css files.
614For `development` mode (including `webpack-dev-server`) you can use [style-loader](https://github.com/webpack/style-loader), because it injects CSS into the DOM using multiple <style></style> and works faster.
615
616> Important: Do not use `style-loader` and `mini-css-extract-plugin` together.
617
618**webpack.config.js**
619
620```js
621const MiniCssExtractPlugin = require("mini-css-extract-plugin");
622
623const devMode = process.env.NODE_ENV !== "production";
624
625module.exports = {
626 module: {
627 rules: [
628 {
629 // If you enable `experiments.css` or `experiments.futureDefaults`, please uncomment line below
630 // type: "javascript/auto",
631 test: /\.(sa|sc|c)ss$/,
632 use: [
633 devMode ? "style-loader" : MiniCssExtractPlugin.loader,
634 "css-loader",
635 "postcss-loader",
636 "sass-loader",
637 ],
638 },
639 ],
640 },
641 plugins: [devMode ? [] : [new MiniCssExtractPlugin()]].flat(),
642};
643```
644
645### Minimal example
646
647**webpack.config.js**
648
649```js
650const MiniCssExtractPlugin = require("mini-css-extract-plugin");
651
652module.exports = {
653 plugins: [
654 new MiniCssExtractPlugin({
655 // Options similar to the same options in webpackOptions.output
656 // all options are optional
657 filename: "[name].css",
658 chunkFilename: "[id].css",
659 ignoreOrder: false, // Enable to remove warnings about conflicting order
660 }),
661 ],
662 module: {
663 rules: [
664 {
665 test: /\.css$/,
666 use: [
667 {
668 loader: MiniCssExtractPlugin.loader,
669 options: {
670 // you can specify a publicPath here
671 // by default it uses publicPath in webpackOptions.output
672 publicPath: "../",
673 },
674 },
675 "css-loader",
676 ],
677 },
678 ],
679 },
680};
681```
682
683### Named export for CSS Modules
684
685> ⚠ Names of locals are converted to `camelCase`.
686
687> ⚠ It is not allowed to use JavaScript reserved words in CSS class names.
688
689> ⚠ Options `esModule` and `modules.namedExport` in `css-loader` should be enabled.
690
691**styles.css**
692
693```css
694.foo-baz {
695 color: red;
696}
697.bar {
698 color: blue;
699}
700```
701
702**index.js**
703
704```js
705import { bar, fooBaz } from "./styles.css";
706
707console.log(fooBaz, bar);
708```
709
710You can enable a ES module named export using:
711
712**webpack.config.js**
713
714```js
715const MiniCssExtractPlugin = require("mini-css-extract-plugin");
716
717module.exports = {
718 plugins: [new MiniCssExtractPlugin()],
719 module: {
720 rules: [
721 {
722 test: /\.css$/,
723 use: [
724 {
725 loader: MiniCssExtractPlugin.loader,
726 },
727 {
728 loader: "css-loader",
729 options: {
730 esModule: true,
731 modules: {
732 namedExport: true,
733 localIdentName: "foo__[name]__[local]",
734 },
735 },
736 },
737 ],
738 },
739 ],
740 },
741};
742```
743
744### The `publicPath` option as function
745
746You can specify `publicPath` as a function to dynamically determine the public path based on each resource’s location relative to the project root or context.
747
748**webpack.config.js**
749
750```js
751const MiniCssExtractPlugin = require("mini-css-extract-plugin");
752
753module.exports = {
754 plugins: [
755 new MiniCssExtractPlugin({
756 // Options similar to the same options in webpackOptions.output
757 // both options are optional
758 filename: "[name].css",
759 chunkFilename: "[id].css",
760 }),
761 ],
762 module: {
763 rules: [
764 {
765 test: /\.css$/,
766 use: [
767 {
768 loader: MiniCssExtractPlugin.loader,
769 options: {
770 publicPath: (resourcePath, context) =>
771 // publicPath is the relative path of the resource to the context
772 // e.g. for ./css/admin/main.css the publicPath will be ../../
773 // while for ./css/main.css the publicPath will be ../
774 `${path.relative(path.dirname(resourcePath), context)}/`,
775 },
776 },
777 "css-loader",
778 ],
779 },
780 ],
781 },
782};
783```
784
785### Advanced configuration example
786
787This plugin should not be used with `style-loader` in the loaders chain.
788
789Here is an example to have both HMR in `development` and your styles extracted in a file for `production` builds.
790
791(Loaders options left out for clarity, adapt accordingly to your needs.)
792
793You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`.
794`webpack-dev-server` enables / disables HMR using `hot` option.
795
796**webpack.config.js**
797
798```js
799const MiniCssExtractPlugin = require("mini-css-extract-plugin");
800const webpack = require("webpack");
801
802const devMode = process.env.NODE_ENV !== "production";
803
804const plugins = [
805 new MiniCssExtractPlugin({
806 // Options similar to the same options in webpackOptions.output
807 // both options are optional
808 filename: devMode ? "[name].css" : "[name].[contenthash].css",
809 chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
810 }),
811];
812if (devMode) {
813 // only enable hot in development
814 plugins.push(new webpack.HotModuleReplacementPlugin());
815}
816
817module.exports = {
818 plugins,
819 module: {
820 rules: [
821 {
822 test: /\.(sa|sc|c)ss$/,
823 use: [
824 MiniCssExtractPlugin.loader,
825 "css-loader",
826 "postcss-loader",
827 "sass-loader",
828 ],
829 },
830 ],
831 },
832};
833```
834
835### Hot Module Reloading (HMR)
836
837> [!NOTE]
838>
839> HMR is automatically supported in webpack 5. No need to configure it. Skip the following:
840
841The `mini-css-extract-plugin` supports hot reloading of actual CSS files in development.
842Some options are provided to enable HMR of both standard stylesheets and locally scoped CSS or CSS modules.
843Below is an example configuration of mini-css for HMR use with CSS modules.
844
845You should not use `HotModuleReplacementPlugin` plugin if you are using a `webpack-dev-server`.
846`webpack-dev-server` enables / disables HMR using `hot` option.
847
848**webpack.config.js**
849
850```js
851const MiniCssExtractPlugin = require("mini-css-extract-plugin");
852const webpack = require("webpack");
853
854const plugins = [
855 new MiniCssExtractPlugin({
856 // Options similar to the same options in webpackOptions.output
857 // both options are optional
858 filename: devMode ? "[name].css" : "[name].[contenthash].css",
859 chunkFilename: devMode ? "[id].css" : "[id].[contenthash].css",
860 }),
861];
862if (devMode) {
863 // only enable hot in development
864 plugins.push(new webpack.HotModuleReplacementPlugin());
865}
866
867module.exports = {
868 plugins,
869 module: {
870 rules: [
871 {
872 test: /\.css$/,
873 use: [
874 {
875 loader: MiniCssExtractPlugin.loader,
876 options: {},
877 },
878 "css-loader",
879 ],
880 },
881 ],
882 },
883};
884```
885
886### Minimizing For Production
887
888To minify the output, use a plugin like [css-minimizer-webpack-plugin](https://github.com/webpack/css-minimizer-webpack-plugin).
889
890**webpack.config.js**
891
892```js
893const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
894const MiniCssExtractPlugin = require("mini-css-extract-plugin");
895
896module.exports = {
897 plugins: [
898 new MiniCssExtractPlugin({
899 filename: "[name].css",
900 chunkFilename: "[id].css",
901 }),
902 ],
903 module: {
904 rules: [
905 {
906 test: /\.css$/,
907 use: [MiniCssExtractPlugin.loader, "css-loader"],
908 },
909 ],
910 },
911 optimization: {
912 minimizer: [
913 // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`).
914 // Uncomment the next line o keep JS minimizers and add CSS minimizer:
915 // `...`,
916 new CssMinimizerPlugin(),
917 ],
918 },
919};
920```
921
922- By default, CSS minimization runs in production mode.
923- If you want to run it also in development set the `optimization.minimize` option to `true`.
924
925### Using preloaded or inlined CSS
926
927The runtime code detects already added CSS via `<link>` or `<style>` tags and avoids duplicating CSS loading.
928
929- This can be useful when injecting CSS on server-side for Server-Side-Rendering (SSR).
930- The `href` of the `<link>` tag has to match the URL that will be used for loading the CSS chunk.
931- The `data-href` attribute can be used for both `<link>` and `<style>` elements.
932- When inlining CSS `data-href` must be used.
933
934### Extracting all CSS in a single file
935
936The CSS can be extracted in one CSS file using `optimization.splitChunks.cacheGroups` with the `type` `"css/mini-extract"`.
937
938**webpack.config.js**
939
940```js
941const MiniCssExtractPlugin = require("mini-css-extract-plugin");
942
943module.exports = {
944 optimization: {
945 splitChunks: {
946 cacheGroups: {
947 styles: {
948 name: "styles",
949 type: "css/mini-extract",
950 chunks: "all",
951 enforce: true,
952 },
953 },
954 },
955 },
956 plugins: [
957 new MiniCssExtractPlugin({
958 filename: "[name].css",
959 }),
960 ],
961 module: {
962 rules: [
963 {
964 test: /\.css$/,
965 use: [MiniCssExtractPlugin.loader, "css-loader"],
966 },
967 ],
968 },
969};
970```
971
972Note that `type` should be used instead of `test` in Webpack 5, or else an extra `.js` file can be generated besides the `.css` file. This is because `test` doesn't know which modules should be dropped (in this case, it won't detect that `.js` should be dropped).
973
974### Extracting CSS based on entry
975
976You may also extract the CSS based on the webpack entry name.
977This is especially useful if you import routes dynamically but want to keep your CSS bundled according to entry.
978This also prevents the CSS duplication issue one had with the ExtractTextPlugin.
979
980```js
981const path = require("path");
982const MiniCssExtractPlugin = require("mini-css-extract-plugin");
983
984module.exports = {
985 entry: {
986 foo: path.resolve(__dirname, "src/foo"),
987 bar: path.resolve(__dirname, "src/bar"),
988 },
989 optimization: {
990 splitChunks: {
991 cacheGroups: {
992 fooStyles: {
993 type: "css/mini-extract",
994 name: "styles_foo",
995 chunks: (chunk) => chunk.name === "foo",
996 enforce: true,
997 },
998 barStyles: {
999 type: "css/mini-extract",
1000 name: "styles_bar",
1001 chunks: (chunk) => chunk.name === "bar",
1002 enforce: true,
1003 },
1004 },
1005 },
1006 },
1007 plugins: [
1008 new MiniCssExtractPlugin({
1009 filename: "[name].css",
1010 }),
1011 ],
1012 module: {
1013 rules: [
1014 {
1015 test: /\.css$/,
1016 use: [MiniCssExtractPlugin.loader, "css-loader"],
1017 },
1018 ],
1019 },
1020};
1021```
1022
1023### Filename Option as function
1024
1025With the `filename` option you can use chunk data to customize the filename.
1026This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk.
1027In the example below, we'll use `filename` to output the generated css into a different directory.
1028
1029**webpack.config.js**
1030
1031```js
1032const MiniCssExtractPlugin = require("mini-css-extract-plugin");
1033
1034module.exports = {
1035 plugins: [
1036 new MiniCssExtractPlugin({
1037 filename: ({ chunk }) => `${chunk.name.replace("/js/", "/css/")}.css`,
1038 }),
1039 ],
1040 module: {
1041 rules: [
1042 {
1043 test: /\.css$/,
1044 use: [MiniCssExtractPlugin.loader, "css-loader"],
1045 },
1046 ],
1047 },
1048};
1049```
1050
1051### Long Term Caching
1052
1053For long term caching use `filename: "[contenthash].css"`. Optionally add `[name]`.
1054
1055**webpack.config.js**
1056
1057```js
1058const MiniCssExtractPlugin = require("mini-css-extract-plugin");
1059
1060module.exports = {
1061 plugins: [
1062 new MiniCssExtractPlugin({
1063 filename: "[name].[contenthash].css",
1064 chunkFilename: "[id].[contenthash].css",
1065 }),
1066 ],
1067 module: {
1068 rules: [
1069 {
1070 test: /\.css$/,
1071 use: [MiniCssExtractPlugin.loader, "css-loader"],
1072 },
1073 ],
1074 },
1075};
1076```
1077
1078### Remove Order Warnings
1079
1080For projects where CSS ordering has been mitigated through consistent use of scoping or naming conventions, such as [CSS Modules](https://github.com/css-modules/css-modules), the css order warnings can be disabled by setting the ignoreOrder flag to true for the plugin.
1081
1082**webpack.config.js**
1083
1084```js
1085const MiniCssExtractPlugin = require("mini-css-extract-plugin");
1086
1087module.exports = {
1088 plugins: [
1089 new MiniCssExtractPlugin({
1090 ignoreOrder: true,
1091 }),
1092 ],
1093 module: {
1094 rules: [
1095 {
1096 test: /\.css$/i,
1097 use: [MiniCssExtractPlugin.loader, "css-loader"],
1098 },
1099 ],
1100 },
1101};
1102```
1103
1104### Multiple Themes
1105
1106Switch themes by conditionally loading different SCSS variants with query parameters.
1107
1108**webpack.config.js**
1109
1110```js
1111const MiniCssExtractPlugin = require("mini-css-extract-plugin");
1112
1113module.exports = {
1114 entry: "./src/index.js",
1115 module: {
1116 rules: [
1117 {
1118 test: /\.s[ac]ss$/i,
1119 oneOf: [
1120 {
1121 resourceQuery: "?dark",
1122 use: [
1123 MiniCssExtractPlugin.loader,
1124 "css-loader",
1125 {
1126 loader: "sass-loader",
1127 options: {
1128 additionalData: "@use 'dark-theme/vars' as vars;",
1129 },
1130 },
1131 ],
1132 },
1133 {
1134 use: [
1135 MiniCssExtractPlugin.loader,
1136 "css-loader",
1137 {
1138 loader: "sass-loader",
1139 options: {
1140 additionalData: "@use 'light-theme/vars' as vars;",
1141 },
1142 },
1143 ],
1144 },
1145 ],
1146 },
1147 ],
1148 },
1149 plugins: [
1150 new MiniCssExtractPlugin({
1151 filename: "[name].css",
1152 attributes: {
1153 id: "theme",
1154 },
1155 }),
1156 ],
1157};
1158```
1159
1160**src/index.js**
1161
1162```
1163import "./style.scss";
1164
1165let theme = "light";
1166const themes = {};
1167
1168themes[theme] = document.querySelector("#theme");
1169
1170async function loadTheme(newTheme) {
1171 console.log(`CHANGE THEME - ${newTheme}`);
1172
1173 const themeElement = document.querySelector("#theme");
1174
1175 if (themeElement) {
1176 themeElement.remove();
1177 }
1178
1179 if (themes[newTheme]) {
1180 console.log(`THEME ALREADY LOADED - ${newTheme}`);
1181
1182 document.head.appendChild(themes[newTheme]);
1183
1184 return;
1185 }
1186
1187 if (newTheme === "dark") {
1188 console.log(`LOADING THEME - ${newTheme}`);
1189
1190 import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => {
1191 themes[newTheme] = document.querySelector("#theme");
1192
1193 console.log(`LOADED - ${newTheme}`);
1194 });
1195 }
1196}
1197
1198document.onclick = () => {
1199 if (theme === "light") {
1200 theme = "dark";
1201 } else {
1202 theme = "light";
1203 }
1204
1205 loadTheme(theme);
1206};
1207```
1208
1209**src/dark-theme/\_vars.scss**
1210
1211```scss
1212$background: black;
1213```
1214
1215**src/light-theme/\_vars.scss**
1216
1217```scss
1218$background: white;
1219```
1220
1221**src/styles.scss**
1222
1223```scss
1224body {
1225 background-color: vars.$background;
1226}
1227```
1228
1229**public/index.html**
1230
1231```html
1232<!DOCTYPE html>
1233<html lang="en">
1234 <head>
1235 <meta charset="UTF-8" />
1236 <meta name="viewport" content="width=device-width, initial-scale=1" />
1237 <title>Document</title>
1238 <link id="theme" rel="stylesheet" type="text/css" href="./main.css" />
1239 </head>
1240 <body>
1241 <script src="./main.js"></script>
1242 </body>
1243</html>
1244```
1245
1246### Media Query Plugin
1247
1248If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:
1249
1250- [Media Query Plugin](https://github.com/SassNinja/media-query-plugin)
1251- [Media Query Splitting Plugin](https://github.com/mike-diamond/media-query-splitting-plugin)
1252
1253## Hooks
1254
1255The mini-css-extract-plugin provides hooks to extend it to your needs.
1256
1257### beforeTagInsert
1258
1259`SyncWaterfallHook`
1260
1261Called before inject the insert code for link tag. Should return a string
1262
1263```javascript
1264MiniCssExtractPlugin.getCompilationHooks(compilation).beforeTagInsert.tap(
1265 "changeHref",
1266 (source, varNames) =>
1267 Template.asString([
1268 source,
1269 `${varNames.tag}.setAttribute("href", "https://github.com/webpack/mini-css-extract-plugin");`,
1270 ]),
1271);
1272```
1273
1274## Contributing
1275
1276We welcome all contributions!
1277If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
1278
1279[CONTRIBUTING](./.github/CONTRIBUTING.md)
1280
1281## License
1282
1283[MIT](./LICENSE)
1284
1285[npm]: https://img.shields.io/npm/v/mini-css-extract-plugin.svg
1286[npm-url]: https://npmjs.com/package/mini-css-extract-plugin
1287[node]: https://img.shields.io/node/v/mini-css-extract-plugin.svg
1288[node-url]: https://nodejs.org
1289[tests]: https://github.com/webpack/mini-css-extract-plugin/workflows/mini-css-extract-plugin/badge.svg
1290[tests-url]: https://github.com/webpack/mini-css-extract-plugin/actions
1291[cover]: https://codecov.io/gh/webpack/mini-css-extract-plugin/branch/main/graph/badge.svg
1292[cover-url]: https://codecov.io/gh/webpack/mini-css-extract-plugin
1293[discussion]: https://img.shields.io/github/discussions/webpack/webpack
1294[discussion-url]: https://github.com/webpack/webpack/discussions
1295[size]: https://packagephobia.now.sh/badge?p=mini-css-extract-plugin
1296[size-url]: https://packagephobia.now.sh/result?p=mini-css-extract-plugin
Note: See TracBrowser for help on using the repository browser.