1 | <div align="center">
|
2 | <img
|
3 | width="180"
|
4 | height="180"
|
5 | hspace="10"
|
6 | alt="PostCSS Logo"
|
7 | src="https://api.postcss.org/logo.svg">
|
8 | <a href="https://github.com/webpack/webpack">
|
9 | <img
|
10 | width="200"
|
11 | height="200"
|
12 | hspace="10"
|
13 | src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon.svg">
|
14 | </a>
|
15 | <div align="center">
|
16 | <a href="https://evilmartians.com/?utm_source=postcss">
|
17 | <img
|
18 | src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
|
19 | alt="Sponsored by Evil Martians"
|
20 | width="236"
|
21 | height="54"
|
22 | vspace="10">
|
23 | </a>
|
24 | </div>
|
25 | </div>
|
26 |
|
27 | [![npm][npm]][npm-url]
|
28 | [![node][node]][node-url]
|
29 | [![deps][deps]][deps-url]
|
30 | [![tests][tests]][tests-url]
|
31 | [![coverage][cover]][cover-url]
|
32 | [![size][size]][size-url]
|
33 |
|
34 | Webpack chat: [![chat][chat]][chat-url]
|
35 |
|
36 | PostCSS chat: [![chat-postcss][chat-postcss]][chat-postcss-url]
|
37 |
|
38 | # postcss-loader
|
39 |
|
40 | Loader to process CSS with [`PostCSS`](https://github.com/postcss/postcss).
|
41 |
|
42 | ## Getting Started
|
43 |
|
44 | You need webpack v5 to use the latest version. For Webpack v4, you have to install postcss-loader v4.
|
45 |
|
46 | To begin, you'll need to install `postcss-loader` and `postcss`:
|
47 |
|
48 | ```console
|
49 | npm install --save-dev postcss-loader postcss
|
50 | ```
|
51 |
|
52 | or
|
53 |
|
54 | ```console
|
55 | yarn add -D postcss-loader postcss
|
56 | ```
|
57 |
|
58 | or
|
59 |
|
60 | ```console
|
61 | pnpm add -D postcss-loader postcss
|
62 | ```
|
63 |
|
64 | Then add the plugin to your `webpack` config. For example:
|
65 |
|
66 | > In the following configuration the plugin [`postcss-preset-env`](https://github.com/csstools/postcss-preset-env) is used, which is not installed by default.
|
67 |
|
68 | **file.js**
|
69 |
|
70 | ```js
|
71 | import css from "file.css";
|
72 | ```
|
73 |
|
74 | **webpack.config.js**
|
75 |
|
76 | ```js
|
77 | module.exports = {
|
78 | module: {
|
79 | rules: [
|
80 | {
|
81 | test: /\.css$/i,
|
82 | use: [
|
83 | "style-loader",
|
84 | "css-loader",
|
85 | {
|
86 | loader: "postcss-loader",
|
87 | options: {
|
88 | postcssOptions: {
|
89 | plugins: [
|
90 | [
|
91 | "postcss-preset-env",
|
92 | {
|
93 | // Options
|
94 | },
|
95 | ],
|
96 | ],
|
97 | },
|
98 | },
|
99 | },
|
100 | ],
|
101 | },
|
102 | ],
|
103 | },
|
104 | };
|
105 | ```
|
106 |
|
107 | Alternative use with [config files](#config):
|
108 |
|
109 | **postcss.config.js**
|
110 |
|
111 | ```js
|
112 | module.exports = {
|
113 | plugins: [
|
114 | [
|
115 | "postcss-preset-env",
|
116 | {
|
117 | // Options
|
118 | },
|
119 | ],
|
120 | ],
|
121 | };
|
122 | ```
|
123 |
|
124 | The loader **automatically** searches for configuration files.
|
125 |
|
126 | **webpack.config.js**
|
127 |
|
128 | ```js
|
129 | module.exports = {
|
130 | module: {
|
131 | rules: [
|
132 | {
|
133 | test: /\.css$/i,
|
134 | use: ["style-loader", "css-loader", "postcss-loader"],
|
135 | },
|
136 | ],
|
137 | },
|
138 | };
|
139 | ```
|
140 |
|
141 | And run `webpack` via your preferred method.
|
142 |
|
143 | ## Options
|
144 |
|
145 | - [`execute`](#execute)
|
146 | - [`postcssOptions`](#postcssOptions)
|
147 | - [`sourceMap`](#sourcemap)
|
148 | - [`implementation`](#implementation)
|
149 |
|
150 | ### `execute`
|
151 |
|
152 | Type:
|
153 |
|
154 | ```ts
|
155 | type execute = boolean;
|
156 | ```
|
157 |
|
158 | Default: `undefined`
|
159 |
|
160 | Enable PostCSS Parser support in `CSS-in-JS`.
|
161 | If you use JS styles the [`postcss-js`](https://github.com/postcss/postcss-js) parser, add the `execute` option.
|
162 |
|
163 | **webpack.config.js**
|
164 |
|
165 | ```js
|
166 | module.exports = {
|
167 | module: {
|
168 | rules: [
|
169 | {
|
170 | test: /\.style.js$/,
|
171 | use: [
|
172 | "style-loader",
|
173 | {
|
174 | loader: "css-loader",
|
175 | },
|
176 | {
|
177 | loader: "postcss-loader",
|
178 | options: {
|
179 | postcssOptions: {
|
180 | parser: "postcss-js",
|
181 | },
|
182 | execute: true,
|
183 | },
|
184 | },
|
185 | ],
|
186 | },
|
187 | ],
|
188 | },
|
189 | };
|
190 | ```
|
191 |
|
192 | ### `postcssOptions`
|
193 |
|
194 | Type:
|
195 |
|
196 | ```ts
|
197 | type postcssOptions =
|
198 | | {
|
199 | from: string;
|
200 | map: boolean | SourceMapOptions;
|
201 | parser: string | object | (() => Parser);
|
202 | stringifier: Stringifier | Syntax;
|
203 | syntax: Syntax;
|
204 | to: string;
|
205 | }
|
206 | | ((loaderContext: LoaderContext) => {
|
207 | from: string;
|
208 | map: boolean | SourceMapOptions;
|
209 | parser: string | object | (() => Parser);
|
210 | stringifier: Stringifier | Syntax;
|
211 | syntax: Syntax;
|
212 | to: string;
|
213 | });
|
214 | ```
|
215 |
|
216 | Default: `undefined`
|
217 |
|
218 | Allows to set [`PostCSS options`](https://postcss.org/api/#processoptions) and plugins.
|
219 |
|
220 | All `PostCSS` options are supported.
|
221 | There is the special `config` option for config files. How it works and how it can be configured is described below.
|
222 |
|
223 | We recommend do not specify `from`, `to` and `map` options, because this can lead to wrong path in source maps.
|
224 | If you need source maps please use the [`sourcemap`](#sourcemap) option.
|
225 |
|
226 | #### `object`
|
227 |
|
228 | Setup `plugins`:
|
229 |
|
230 | **webpack.config.js** (**recommended**)
|
231 |
|
232 | ```js
|
233 | const myOtherPostcssPlugin = require("postcss-my-plugin");
|
234 |
|
235 | module.exports = {
|
236 | module: {
|
237 | rules: [
|
238 | {
|
239 | test: /\.sss$/i,
|
240 | loader: "postcss-loader",
|
241 | options: {
|
242 | postcssOptions: {
|
243 | plugins: [
|
244 | "postcss-import",
|
245 | ["postcss-short", { prefix: "x" }],
|
246 | require.resolve("my-postcss-plugin"),
|
247 | myOtherPostcssPlugin({ myOption: true }),
|
248 | // Deprecated and will be removed in the next major release
|
249 | { "postcss-nested": { preserveEmpty: true } },
|
250 | ],
|
251 | },
|
252 | },
|
253 | },
|
254 | ],
|
255 | },
|
256 | };
|
257 | ```
|
258 |
|
259 | **webpack.config.js** (**deprecated**, will be removed in the next major release)
|
260 |
|
261 | ```js
|
262 | module.exports = {
|
263 | module: {
|
264 | rules: [
|
265 | {
|
266 | test: /\.sss$/i,
|
267 | loader: "postcss-loader",
|
268 | options: {
|
269 | postcssOptions: {
|
270 | plugins: {
|
271 | "postcss-import": {},
|
272 | "postcss-short": { prefix: "x" },
|
273 | },
|
274 | },
|
275 | },
|
276 | },
|
277 | ],
|
278 | },
|
279 | };
|
280 | ```
|
281 |
|
282 | Setup `syntax`:
|
283 |
|
284 | **webpack.config.js**
|
285 |
|
286 | ```js
|
287 | module.exports = {
|
288 | module: {
|
289 | rules: [
|
290 | {
|
291 | test: /\.sss$/i,
|
292 | loader: "postcss-loader",
|
293 | options: {
|
294 | postcssOptions: {
|
295 | // Can be `string`
|
296 | syntax: "sugarss",
|
297 | // Can be `object`
|
298 | syntax: require("sugarss"),
|
299 | },
|
300 | },
|
301 | },
|
302 | ],
|
303 | },
|
304 | };
|
305 | ```
|
306 |
|
307 | Setup `parser`:
|
308 |
|
309 | **webpack.config.js**
|
310 |
|
311 | ```js
|
312 | module.exports = {
|
313 | module: {
|
314 | rules: [
|
315 | {
|
316 | test: /\.sss$/i,
|
317 | loader: "postcss-loader",
|
318 | options: {
|
319 | postcssOptions: {
|
320 | // Can be `string`
|
321 | parser: "sugarss",
|
322 | // Can be `object`
|
323 | parser: require("sugarss"),
|
324 | // Can be `function`
|
325 | parser: require("sugarss").parse,
|
326 | },
|
327 | },
|
328 | },
|
329 | ],
|
330 | },
|
331 | };
|
332 | ```
|
333 |
|
334 | Setup `stringifier`:
|
335 |
|
336 | **webpack.config.js**
|
337 |
|
338 | ```js
|
339 | const Midas = require("midas");
|
340 | const midas = new Midas();
|
341 |
|
342 | module.exports = {
|
343 | module: {
|
344 | rules: [
|
345 | {
|
346 | test: /\.sss$/i,
|
347 | loader: "postcss-loader",
|
348 | options: {
|
349 | postcssOptions: {
|
350 | // Can be `string`
|
351 | stringifier: "sugarss",
|
352 | // Can be `object`
|
353 | stringifier: require("sugarss"),
|
354 | // Can be `function`
|
355 | stringifier: midas.stringifier,
|
356 | },
|
357 | },
|
358 | },
|
359 | ],
|
360 | },
|
361 | };
|
362 | ```
|
363 |
|
364 | #### `function`
|
365 |
|
366 | **webpack.config.js**
|
367 |
|
368 | ```js
|
369 | module.exports = {
|
370 | module: {
|
371 | rules: [
|
372 | {
|
373 | test: /\.(css|sss)$/i,
|
374 | loader: "postcss-loader",
|
375 | options: {
|
376 | postcssOptions: (loaderContext) => {
|
377 | if (/\.sss$/.test(loaderContext.resourcePath)) {
|
378 | return {
|
379 | parser: "sugarss",
|
380 | plugins: [
|
381 | ["postcss-short", { prefix: "x" }],
|
382 | "postcss-preset-env",
|
383 | ],
|
384 | };
|
385 | }
|
386 |
|
387 | return {
|
388 | plugins: [
|
389 | ["postcss-short", { prefix: "x" }],
|
390 | "postcss-preset-env",
|
391 | ],
|
392 | };
|
393 | },
|
394 | },
|
395 | },
|
396 | ],
|
397 | },
|
398 | };
|
399 | ```
|
400 |
|
401 | #### `config`
|
402 |
|
403 | Type:
|
404 |
|
405 | ```ts
|
406 | type config = boolean | string;
|
407 | ```
|
408 |
|
409 | Default: `undefined`
|
410 |
|
411 | Allows to set options using config files.
|
412 | Options specified in the config file are combined with options passed to the loader, the loader options overwrite options from config.
|
413 |
|
414 | ##### Config Files
|
415 |
|
416 | The loader will search up the directory tree for configuration in the following places:
|
417 |
|
418 | - a `postcss` property in `package.json`
|
419 | - a `.postcssrc` file in JSON or YAML format
|
420 | - a `.postcssrc.json`, `.postcssrc.yaml`, `.postcssrc.yml`, `.postcssrc.js`, or `.postcssrc.cjs` file
|
421 | - a `postcss.config.js` or `postcss.config.cjs` CommonJS module exporting an object (**recommended**)
|
422 |
|
423 | ##### Examples of Config Files
|
424 |
|
425 | Using `object` notation:
|
426 |
|
427 | **postcss.config.js** (**recommend**)
|
428 |
|
429 | ```js
|
430 | module.exports = {
|
431 | // You can specify any options from https://postcss.org/api/#processoptions here
|
432 | // parser: 'sugarss',
|
433 | plugins: [
|
434 | // Plugins for PostCSS
|
435 | ["postcss-short", { prefix: "x" }],
|
436 | "postcss-preset-env",
|
437 | ],
|
438 | };
|
439 | ```
|
440 |
|
441 | Using `function` notation:
|
442 |
|
443 | **postcss.config.js** (**recommend**)
|
444 |
|
445 | ```js
|
446 | module.exports = (api) => {
|
447 | // `api.file` - path to the file
|
448 | // `api.mode` - `mode` value of webpack, please read https://webpack.js.org/configuration/mode/
|
449 | // `api.webpackLoaderContext` - loader context for complex use cases
|
450 | // `api.env` - alias `api.mode` for compatibility with `postcss-cli`
|
451 | // `api.options` - the `postcssOptions` options
|
452 |
|
453 | if (/\.sss$/.test(api.file)) {
|
454 | return {
|
455 | // You can specify any options from https://postcss.org/api/#processoptions here
|
456 | parser: "sugarss",
|
457 | plugins: [
|
458 | // Plugins for PostCSS
|
459 | ["postcss-short", { prefix: "x" }],
|
460 | "postcss-preset-env",
|
461 | ],
|
462 | };
|
463 | }
|
464 |
|
465 | return {
|
466 | // You can specify any options from https://postcss.org/api/#processoptions here
|
467 | plugins: [
|
468 | // Plugins for PostCSS
|
469 | ["postcss-short", { prefix: "x" }],
|
470 | "postcss-preset-env",
|
471 | ],
|
472 | };
|
473 | };
|
474 | ```
|
475 |
|
476 | **postcss.config.js** (**deprecated**, will be removed in the next major release)
|
477 |
|
478 | ```js
|
479 | module.exports = {
|
480 | // You can specify any options from https://postcss.org/api/#processoptions here
|
481 | // parser: 'sugarss',
|
482 | plugins: {
|
483 | // Plugins for PostCSS
|
484 | "postcss-short": { prefix: "x" },
|
485 | "postcss-preset-env": {},
|
486 | },
|
487 | };
|
488 | ```
|
489 |
|
490 | ##### Config Cascade
|
491 |
|
492 | You can use different `postcss.config.js` files in different directories.
|
493 | Config lookup starts from `path.dirname(file)` and walks the file tree upwards until a config file is found.
|
494 |
|
495 | ```
|
496 | |– components
|
497 | | |– component
|
498 | | | |– index.js
|
499 | | | |– index.png
|
500 | | | |– style.css (1)
|
501 | | | |– postcss.config.js (1)
|
502 | | |– component
|
503 | | | |– index.js
|
504 | | | |– image.png
|
505 | | | |– style.css (2)
|
506 | |
|
507 | |– postcss.config.js (1 && 2 (recommended))
|
508 | |– webpack.config.js
|
509 | |
|
510 | |– package.json
|
511 | ```
|
512 |
|
513 | After setting up your `postcss.config.js`, add `postcss-loader` to your `webpack.config.js`.
|
514 | You can use it standalone or in conjunction with `css-loader` (recommended).
|
515 |
|
516 | Use it **before** `css-loader` and `style-loader`, but **after** other preprocessor loaders like e.g `sass|less|stylus-loader`, if you use any (since [webpack loaders evaluate right to left/bottom to top](https://webpack.js.org/concepts/loaders/#configuration)).
|
517 |
|
518 | **webpack.config.js** (**recommended**)
|
519 |
|
520 | ```js
|
521 | module.exports = {
|
522 | module: {
|
523 | rules: [
|
524 | {
|
525 | test: /\.css$/,
|
526 | use: [
|
527 | "style-loader",
|
528 | {
|
529 | loader: "css-loader",
|
530 | options: {
|
531 | importLoaders: 1,
|
532 | },
|
533 | },
|
534 | "postcss-loader",
|
535 | ],
|
536 | },
|
537 | ],
|
538 | },
|
539 | };
|
540 | ```
|
541 |
|
542 | #### `boolean`
|
543 |
|
544 | Enables/Disables autoloading config.
|
545 |
|
546 | **webpack.config.js**
|
547 |
|
548 | ```js
|
549 | module.exports = {
|
550 | module: {
|
551 | rules: [
|
552 | {
|
553 | test: /\.css$/i,
|
554 | loader: "postcss-loader",
|
555 | options: {
|
556 | postcssOptions: {
|
557 | config: false,
|
558 | },
|
559 | },
|
560 | },
|
561 | ],
|
562 | },
|
563 | };
|
564 | ```
|
565 |
|
566 | #### String
|
567 |
|
568 | Allows to specify the path to the config file.
|
569 |
|
570 | **webpack.config.js**
|
571 |
|
572 | ```js
|
573 | const path = require("path");
|
574 |
|
575 | module.exports = {
|
576 | module: {
|
577 | rules: [
|
578 | {
|
579 | test: /\.css$/i,
|
580 | loader: "postcss-loader",
|
581 | options: {
|
582 | postcssOptions: {
|
583 | config: path.resolve(__dirname, "custom.config.js"),
|
584 | },
|
585 | },
|
586 | },
|
587 | ],
|
588 | },
|
589 | };
|
590 | ```
|
591 |
|
592 | ### `sourceMap`
|
593 |
|
594 | Type:
|
595 |
|
596 | ```ts
|
597 | type sourceMap = boolean;
|
598 | ```
|
599 |
|
600 | Default: depends on the `compiler.devtool` value
|
601 |
|
602 | By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option.
|
603 | All values enable source map generation except `eval` and `false` value.
|
604 |
|
605 | **webpack.config.js**
|
606 |
|
607 | ```js
|
608 | module.exports = {
|
609 | module: {
|
610 | rules: [
|
611 | {
|
612 | test: /\.css$/i,
|
613 | use: [
|
614 | { loader: "style-loader" },
|
615 | { loader: "css-loader", options: { sourceMap: true } },
|
616 | { loader: "postcss-loader", options: { sourceMap: true } },
|
617 | { loader: "sass-loader", options: { sourceMap: true } },
|
618 | ],
|
619 | },
|
620 | ],
|
621 | },
|
622 | };
|
623 | ```
|
624 |
|
625 | Alternative setup:
|
626 |
|
627 | **webpack.config.js**
|
628 |
|
629 | ```js
|
630 | module.exports = {
|
631 | devtool: "source-map",
|
632 | module: {
|
633 | rules: [
|
634 | {
|
635 | test: /\.css$/i,
|
636 | use: [
|
637 | { loader: "style-loader" },
|
638 | { loader: "css-loader" },
|
639 | { loader: "postcss-loader" },
|
640 | { loader: "sass-loader" },
|
641 | ],
|
642 | },
|
643 | ],
|
644 | },
|
645 | };
|
646 | ```
|
647 |
|
648 | ### `implementation`
|
649 |
|
650 | Type:
|
651 |
|
652 | ```ts
|
653 | type implementation = object;
|
654 | ```
|
655 |
|
656 | type of `implementation` should be the same as [postcss.d.ts](https://github.com/postcss/postcss/blob/main/lib/postcss.d.ts)
|
657 |
|
658 | Default: `postcss`
|
659 |
|
660 | The special `implementation` option determines which implementation of PostCSS to use. Overrides the locally installed `peerDependency` version of `postcss`.
|
661 |
|
662 | **This option is only really useful for downstream tooling authors to ease the PostCSS 7-to-8 transition.**
|
663 |
|
664 | #### `function`
|
665 |
|
666 | **webpack.config.js**
|
667 |
|
668 | ```js
|
669 | module.exports = {
|
670 | module: {
|
671 | rules: [
|
672 | {
|
673 | test: /\.css$/i,
|
674 | use: [
|
675 | { loader: "style-loader" },
|
676 | { loader: "css-loader" },
|
677 | {
|
678 | loader: "postcss-loader",
|
679 | options: { implementation: require("postcss") },
|
680 | },
|
681 | { loader: "sass-loader" },
|
682 | ],
|
683 | },
|
684 | ],
|
685 | },
|
686 | };
|
687 | ```
|
688 |
|
689 | #### String
|
690 |
|
691 | **webpack.config.js**
|
692 |
|
693 | ```js
|
694 | module.exports = {
|
695 | module: {
|
696 | rules: [
|
697 | {
|
698 | test: /\.css$/i,
|
699 | use: [
|
700 | { loader: "style-loader" },
|
701 | { loader: "css-loader" },
|
702 | {
|
703 | loader: "postcss-loader",
|
704 | options: { implementation: require.resolve("postcss") },
|
705 | },
|
706 | { loader: "sass-loader" },
|
707 | ],
|
708 | },
|
709 | ],
|
710 | },
|
711 | };
|
712 | ```
|
713 |
|
714 | ## Examples
|
715 |
|
716 | ### SugarSS
|
717 |
|
718 | You'll need to install `sugarss`:
|
719 |
|
720 | ```console
|
721 | npm install --save-dev sugarss
|
722 | ```
|
723 |
|
724 | Using [`SugarSS`](https://github.com/postcss/sugarss) syntax.
|
725 |
|
726 | **webpack.config.js**
|
727 |
|
728 | ```js
|
729 | module.exports = {
|
730 | module: {
|
731 | rules: [
|
732 | {
|
733 | test: /\.sss$/i,
|
734 | use: [
|
735 | "style-loader",
|
736 | {
|
737 | loader: "css-loader",
|
738 | options: { importLoaders: 1 },
|
739 | },
|
740 | {
|
741 | loader: "postcss-loader",
|
742 | options: {
|
743 | postcssOptions: {
|
744 | parser: "sugarss",
|
745 | },
|
746 | },
|
747 | },
|
748 | ],
|
749 | },
|
750 | ],
|
751 | },
|
752 | };
|
753 | ```
|
754 |
|
755 | ### Autoprefixer
|
756 |
|
757 | You'll need to install `autoprefixer`:
|
758 |
|
759 | ```console
|
760 | npm install --save-dev autoprefixer
|
761 | ```
|
762 |
|
763 | Add vendor prefixes to CSS rules using [`autoprefixer`](https://github.com/postcss/autoprefixer).
|
764 |
|
765 | **webpack.config.js**
|
766 |
|
767 | ```js
|
768 | module.exports = {
|
769 | module: {
|
770 | rules: [
|
771 | {
|
772 | test: /\.css$/i,
|
773 | use: [
|
774 | "style-loader",
|
775 | {
|
776 | loader: "css-loader",
|
777 | options: { importLoaders: 1 },
|
778 | },
|
779 | {
|
780 | loader: "postcss-loader",
|
781 | options: {
|
782 | postcssOptions: {
|
783 | plugins: [
|
784 | [
|
785 | "autoprefixer",
|
786 | {
|
787 | // Options
|
788 | },
|
789 | ],
|
790 | ],
|
791 | },
|
792 | },
|
793 | },
|
794 | ],
|
795 | },
|
796 | ],
|
797 | },
|
798 | };
|
799 | ```
|
800 |
|
801 | > :warning: [`postcss-preset-env`](https://github.com/csstools/postcss-preset-env) includes [`autoprefixer`](https://github.com/postcss/autoprefixer), so adding it separately is not necessary if you already use the preset. More [information](https://github.com/csstools/postcss-preset-env#autoprefixer)
|
802 |
|
803 | ### PostCSS Preset Env
|
804 |
|
805 | You'll need to install `postcss-preset-env`:
|
806 |
|
807 | ```console
|
808 | npm install --save-dev postcss-preset-env
|
809 | ```
|
810 |
|
811 | **webpack.config.js**
|
812 |
|
813 | ```js
|
814 | module.exports = {
|
815 | module: {
|
816 | rules: [
|
817 | {
|
818 | test: /\.css$/i,
|
819 | use: [
|
820 | "style-loader",
|
821 | {
|
822 | loader: "css-loader",
|
823 | options: { importLoaders: 1 },
|
824 | },
|
825 | {
|
826 | loader: "postcss-loader",
|
827 | options: {
|
828 | postcssOptions: {
|
829 | plugins: [
|
830 | [
|
831 | "postcss-preset-env",
|
832 | {
|
833 | // Options
|
834 | },
|
835 | ],
|
836 | ],
|
837 | },
|
838 | },
|
839 | },
|
840 | ],
|
841 | },
|
842 | ],
|
843 | },
|
844 | };
|
845 | ```
|
846 |
|
847 | ### CSS Modules
|
848 |
|
849 | What is `CSS Modules`? Please [read](https://github.com/webpack-contrib/css-loader#modules).
|
850 |
|
851 | No additional options required on the `postcss-loader` side.
|
852 | To make them work properly, either add the `css-loader`’s `importLoaders` option.
|
853 |
|
854 | **webpack.config.js**
|
855 |
|
856 | ```js
|
857 | module.exports = {
|
858 | module: {
|
859 | rules: [
|
860 | {
|
861 | test: /\.css$/i,
|
862 | use: [
|
863 | "style-loader",
|
864 | {
|
865 | loader: "css-loader",
|
866 | options: {
|
867 | modules: true,
|
868 | importLoaders: 1,
|
869 | },
|
870 | },
|
871 | "postcss-loader",
|
872 | ],
|
873 | },
|
874 | ],
|
875 | },
|
876 | };
|
877 | ```
|
878 |
|
879 | ### CSS-in-JS and [`postcss-js`](https://github.com/postcss/postcss-js)
|
880 |
|
881 | You'll need to install `postcss-js`:
|
882 |
|
883 | ```console
|
884 | npm install --save-dev postcss-js
|
885 | ```
|
886 |
|
887 | If you want to process styles written in JavaScript, use the [`postcss-js`](https://github.com/postcss/postcss-js) parser.
|
888 |
|
889 | **webpack.config.js**
|
890 |
|
891 | ```js
|
892 | module.exports = {
|
893 | module: {
|
894 | rules: [
|
895 | {
|
896 | test: /\.style.js$/,
|
897 | use: [
|
898 | "style-loader",
|
899 | {
|
900 | loader: "css-loader",
|
901 | options: {
|
902 | importLoaders: 2,
|
903 | },
|
904 | },
|
905 | {
|
906 | loader: "postcss-loader",
|
907 | options: {
|
908 | postcssOptions: {
|
909 | parser: "postcss-js",
|
910 | },
|
911 | execute: true,
|
912 | },
|
913 | },
|
914 | "babel-loader",
|
915 | ],
|
916 | },
|
917 | ],
|
918 | },
|
919 | };
|
920 | ```
|
921 |
|
922 | As result you will be able to write styles in the following way
|
923 |
|
924 | ```js
|
925 | import colors from "./styles/colors";
|
926 |
|
927 | export default {
|
928 | ".menu": {
|
929 | color: colors.main,
|
930 | height: 25,
|
931 | "&_link": {
|
932 | color: "white",
|
933 | },
|
934 | },
|
935 | };
|
936 | ```
|
937 |
|
938 | > :warning: If you are using Babel you need to do the following in order for the setup to work
|
939 |
|
940 | > 1. Add [`babel-plugin-add-module-exports`](https://github.com/59naga/babel-plugin-add-module-exports) to your configuration.
|
941 | > 2. You need to have only one **default** export per style module.
|
942 |
|
943 | ### Extract CSS
|
944 |
|
945 | Using [`mini-css-extract-plugin`](https://github.com/webpack-contrib/mini-css-extract-plugin).
|
946 |
|
947 | **webpack.config.js**
|
948 |
|
949 | ```js
|
950 | const isProductionMode = process.env.NODE_ENV === "production";
|
951 |
|
952 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
953 |
|
954 | module.exports = {
|
955 | mode: isProductionMode ? "production" : "development",
|
956 | module: {
|
957 | rules: [
|
958 | {
|
959 | test: /\.css$/,
|
960 | use: [
|
961 | isProductionMode ? MiniCssExtractPlugin.loader : "style-loader",
|
962 | "css-loader",
|
963 | "postcss-loader",
|
964 | ],
|
965 | },
|
966 | ],
|
967 | },
|
968 | plugins: [
|
969 | new MiniCssExtractPlugin({
|
970 | filename: isProductionMode ? "[name].[contenthash].css" : "[name].css",
|
971 | }),
|
972 | ],
|
973 | };
|
974 | ```
|
975 |
|
976 | ### Emit assets
|
977 |
|
978 | To write a asset from PostCSS plugin to the webpack, need to add a message in `result.messages`.
|
979 |
|
980 | The message should contain the following fields:
|
981 |
|
982 | - `type` = `asset` - Message type (require, should be equal `asset`)
|
983 | - `file` - file name (require)
|
984 | - `content` - file content (require)
|
985 | - `sourceMap` - sourceMap
|
986 | - `info` - asset info
|
987 |
|
988 | **webpack.config.js**
|
989 |
|
990 | ```js
|
991 | const postcssCustomPlugin = (opts = {}) => {
|
992 | return {
|
993 | postcssPlugin: "postcss-custom-plugin",
|
994 | Once: (root, { result }) => {
|
995 | result.messages.push({
|
996 | type: "asset",
|
997 | file: "sprite.svg",
|
998 | content: "<svg>...</svg>",
|
999 | });
|
1000 | },
|
1001 | };
|
1002 | };
|
1003 |
|
1004 | module.exports = {
|
1005 | module: {
|
1006 | rules: [
|
1007 | {
|
1008 | test: /\.css$/i,
|
1009 | use: [
|
1010 | "style-loader",
|
1011 | "css-loader",
|
1012 | {
|
1013 | loader: "postcss-loader",
|
1014 | options: {
|
1015 | postcssOptions: {
|
1016 | plugins: [postcssCustomPlugin()],
|
1017 | },
|
1018 | },
|
1019 | },
|
1020 | ],
|
1021 | },
|
1022 | ],
|
1023 | },
|
1024 | };
|
1025 | ```
|
1026 |
|
1027 | ### Add dependencies, contextDependencies, buildDependencies, missingDependencies
|
1028 |
|
1029 | The dependencies are necessary for webpack to understand when it needs to run recompilation on the changed files.
|
1030 |
|
1031 | There are two way to add dependencies:
|
1032 |
|
1033 | 1. (Recommended). The plugin may emit messages in `result.messages`.
|
1034 |
|
1035 | The message should contain the following fields:
|
1036 |
|
1037 | - `type` = `dependency` - Message type (require, should be equal `dependency`, `context-dependency`, `build-dependency` or `missing-dependency`)
|
1038 | - `file` - absolute file path (require)
|
1039 |
|
1040 | **webpack.config.js**
|
1041 |
|
1042 | ```js
|
1043 | const path = require("path");
|
1044 |
|
1045 | const postcssCustomPlugin = (opts = {}) => {
|
1046 | return {
|
1047 | postcssPlugin: "postcss-custom-plugin",
|
1048 | Once: (root, { result }) => {
|
1049 | result.messages.push({
|
1050 | type: "dependency",
|
1051 | file: path.resolve(__dirname, "path", "to", "file"),
|
1052 | });
|
1053 | },
|
1054 | };
|
1055 | };
|
1056 |
|
1057 | module.exports = {
|
1058 | module: {
|
1059 | rules: [
|
1060 | {
|
1061 | test: /\.css$/i,
|
1062 | use: [
|
1063 | "style-loader",
|
1064 | "css-loader",
|
1065 | {
|
1066 | loader: "postcss-loader",
|
1067 | options: {
|
1068 | postcssOptions: {
|
1069 | plugins: [postcssCustomPlugin()],
|
1070 | },
|
1071 | },
|
1072 | },
|
1073 | ],
|
1074 | },
|
1075 | ],
|
1076 | },
|
1077 | };
|
1078 | ```
|
1079 |
|
1080 | Or you can use ready-made plugin [postcss-add-dependencies](https://www.npmjs.com/package/postcss-add-dependencies).
|
1081 |
|
1082 | 2. Pass `loaderContext` in plugin.
|
1083 |
|
1084 | **webpack.config.js**
|
1085 |
|
1086 | ```js
|
1087 | const path = require("path");
|
1088 |
|
1089 | module.exports = {
|
1090 | module: {
|
1091 | rules: [
|
1092 | {
|
1093 | test: /\.css$/i,
|
1094 | use: [
|
1095 | "style-loader",
|
1096 | "css-loader",
|
1097 | {
|
1098 | loader: "postcss-loader",
|
1099 | options: {
|
1100 | postcssOptions: {
|
1101 | config: path.resolve(__dirname, "path/to/postcss.config.js"),
|
1102 | },
|
1103 | },
|
1104 | },
|
1105 | ],
|
1106 | },
|
1107 | ],
|
1108 | },
|
1109 | };
|
1110 | ```
|
1111 |
|
1112 | **postcss.config.js**
|
1113 |
|
1114 | ```js
|
1115 | module.exports = (api) => ({
|
1116 | plugins: [
|
1117 | require("path/to/postcssCustomPlugin.js")({
|
1118 | loaderContext: api.webpackLoaderContext,
|
1119 | }),
|
1120 | ],
|
1121 | });
|
1122 | ```
|
1123 |
|
1124 | **postcssCustomPlugin.js**
|
1125 |
|
1126 | ```js
|
1127 | const path = require("path");
|
1128 |
|
1129 | const postcssCustomPlugin = (opts = {}) => {
|
1130 | return {
|
1131 | postcssPlugin: "postcss-custom-plugin",
|
1132 | Once: (root, { result }) => {
|
1133 | opts.loaderContext.addDependency(
|
1134 | path.resolve(__dirname, "path", "to", "file")
|
1135 | );
|
1136 | },
|
1137 | };
|
1138 | };
|
1139 |
|
1140 | postcssCustomPlugin.postcss = true;
|
1141 | module.exports = postcssCustomPlugin;
|
1142 | ```
|
1143 |
|
1144 | ## Contributing
|
1145 |
|
1146 | Please take a moment to read our contributing guidelines if you haven't yet done so.
|
1147 |
|
1148 | [CONTRIBUTING](./.github/CONTRIBUTING.md)
|
1149 |
|
1150 | ## License
|
1151 |
|
1152 | [MIT](./LICENSE)
|
1153 |
|
1154 | [npm]: https://img.shields.io/npm/v/postcss-loader.svg
|
1155 | [npm-url]: https://npmjs.com/package/postcss-loader
|
1156 | [node]: https://img.shields.io/node/v/postcss-loader.svg
|
1157 | [node-url]: https://nodejs.org
|
1158 | [deps]: https://david-dm.org/webpack-contrib/postcss-loader.svg
|
1159 | [deps-url]: https://david-dm.org/webpack-contrib/postcss-loader
|
1160 | [tests]: https://github.com/webpack-contrib/postcss-loader/workflows/postcss-loader/badge.svg
|
1161 | [tests-url]: https://github.com/webpack-contrib/postcss-loader/actions
|
1162 | [cover]: https://codecov.io/gh/webpack-contrib/postcss-loader/branch/master/graph/badge.svg
|
1163 | [cover-url]: https://codecov.io/gh/webpack-contrib/postcss-loader
|
1164 | [chat]: https://badges.gitter.im/webpack/webpack.svg
|
1165 | [chat-url]: https://gitter.im/webpack/webpack
|
1166 | [chat-postcss]: https://badges.gitter.im/postcss/postcss.svg
|
1167 | [chat-postcss-url]: https://gitter.im/postcss/postcss
|
1168 | [size]: https://packagephobia.now.sh/badge?p=postcss-loader
|
1169 | [size-url]: https://packagephobia.now.sh/result?p=postcss-loader
|