UNPKG

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