1 | <div align="center">
|
2 | <a href="https://github.com/webpack/webpack">
|
3 | <img width="200" height="200"
|
4 | src="https://webpack.js.org/assets/icon-square-big.svg">
|
5 | </a>
|
6 | <h1>Style Loader</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 | # style-loader
|
18 |
|
19 | Inject CSS into the DOM.
|
20 |
|
21 | ## Getting Started
|
22 |
|
23 | To begin, you'll need to install `style-loader`:
|
24 |
|
25 | ```console
|
26 | npm install --save-dev style-loader
|
27 | ```
|
28 |
|
29 | It's recommended to combine `style-loader` with the [`css-loader`](https://github.com/webpack-contrib/css-loader)
|
30 |
|
31 | Then add the loader to your `webpack` config. For example:
|
32 |
|
33 | **style.css**
|
34 |
|
35 | ```css
|
36 | body {
|
37 | background: green;
|
38 | }
|
39 | ```
|
40 |
|
41 | **component.js**
|
42 |
|
43 | ```js
|
44 | import "./style.css";
|
45 | ```
|
46 |
|
47 | **webpack.config.js**
|
48 |
|
49 | ```js
|
50 | module.exports = {
|
51 | module: {
|
52 | rules: [
|
53 | {
|
54 | test: /\.css$/i,
|
55 | use: ["style-loader", "css-loader"],
|
56 | },
|
57 | ],
|
58 | },
|
59 | };
|
60 | ```
|
61 |
|
62 | ## Options
|
63 |
|
64 | | Name | Type | Default | Description |
|
65 | | :-------------------------------------------: | :------------------: | :---------: | :--------------------------------------------------------- |
|
66 | | [**`injectType`**](#injecttype) | `{String}` | `styleTag` | Allows to setup how styles will be injected into the DOM |
|
67 | | [**`attributes`**](#attributes) | `{Object}` | `{}` | Adds custom attributes to tag |
|
68 | | [**`insert`**](#insert) | `{String\|Function}` | `head` | Inserts tag at the given position into the DOM |
|
69 | | [**`styleTagTransform`**](#styleTagTransform) | `{String\|Function}` | `undefined` | Transform tag and css when insert 'style' tag into the DOM |
|
70 | | [**`base`**](#base) | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
|
71 | | [**`esModule`**](#esmodule) | `{Boolean}` | `true` | Use ES modules syntax |
|
72 |
|
73 | ### `injectType`
|
74 |
|
75 | Type: `String`
|
76 | Default: `styleTag`
|
77 |
|
78 | Allows to setup how styles will be injected into the DOM.
|
79 |
|
80 | Possible values:
|
81 |
|
82 | - `styleTag`
|
83 | - `singletonStyleTag`
|
84 | - `autoStyleTag`
|
85 | - `lazyStyleTag`
|
86 | - `lazySingletonStyleTag`
|
87 | - `lazyAutoStyleTag`
|
88 | - `linkTag`
|
89 |
|
90 | #### `styleTag`
|
91 |
|
92 | Automatically injects styles into the DOM using multiple `<style></style>`. It is **default** behaviour.
|
93 |
|
94 | **component.js**
|
95 |
|
96 | ```js
|
97 | import "./styles.css";
|
98 | ```
|
99 |
|
100 | Example with Locals (CSS Modules):
|
101 |
|
102 | **component-with-css-modules.js**
|
103 |
|
104 | ```js
|
105 | import styles from "./styles.css";
|
106 |
|
107 | const divElement = document.createElement("div");
|
108 | divElement.className = styles["my-class"];
|
109 | ```
|
110 |
|
111 | All locals (class names) stored in imported object.
|
112 |
|
113 | **webpack.config.js**
|
114 |
|
115 | ```js
|
116 | module.exports = {
|
117 | module: {
|
118 | rules: [
|
119 | {
|
120 | test: /\.css$/i,
|
121 | use: [
|
122 | // The `injectType` option can be avoided because it is default behaviour
|
123 | { loader: "style-loader", options: { injectType: "styleTag" } },
|
124 | "css-loader",
|
125 | ],
|
126 | },
|
127 | ],
|
128 | },
|
129 | };
|
130 | ```
|
131 |
|
132 | The loader inject styles like:
|
133 |
|
134 | ```html
|
135 | <style>
|
136 | .foo {
|
137 | color: red;
|
138 | }
|
139 | </style>
|
140 | <style>
|
141 | .bar {
|
142 | color: blue;
|
143 | }
|
144 | </style>
|
145 | ```
|
146 |
|
147 | #### `singletonStyleTag`
|
148 |
|
149 | Automatically injects styles into the DOM using one `<style></style>`.
|
150 |
|
151 | > ⚠ Source maps do not work.
|
152 |
|
153 | **component.js**
|
154 |
|
155 | ```js
|
156 | import "./styles.css";
|
157 | ```
|
158 |
|
159 | **component-with-css-modules.js**
|
160 |
|
161 | ```js
|
162 | import styles from "./styles.css";
|
163 |
|
164 | const divElement = document.createElement("div");
|
165 | divElement.className = styles["my-class"];
|
166 | ```
|
167 |
|
168 | All locals (class names) stored in imported object.
|
169 |
|
170 | **webpack.config.js**
|
171 |
|
172 | ```js
|
173 | module.exports = {
|
174 | module: {
|
175 | rules: [
|
176 | {
|
177 | test: /\.css$/i,
|
178 | use: [
|
179 | {
|
180 | loader: "style-loader",
|
181 | options: { injectType: "singletonStyleTag" },
|
182 | },
|
183 | "css-loader",
|
184 | ],
|
185 | },
|
186 | ],
|
187 | },
|
188 | };
|
189 | ```
|
190 |
|
191 | The loader inject styles like:
|
192 |
|
193 | ```html
|
194 | <style>
|
195 | .foo {
|
196 | color: red;
|
197 | }
|
198 | .bar {
|
199 | color: blue;
|
200 | }
|
201 | </style>
|
202 | ```
|
203 |
|
204 | #### `autoStyleTag`
|
205 |
|
206 | Works the same as a [`styleTag`](#styleTag), but if the code is executed in IE6-9, turns on the [`singletonStyleTag`](#singletonStyleTag) mode.
|
207 |
|
208 | #### `lazyStyleTag`
|
209 |
|
210 | Injects styles into the DOM using multiple `<style></style>` on demand.
|
211 | We recommend following `.lazy.css` naming convention for lazy styles and the `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`).
|
212 | When you `lazyStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
|
213 |
|
214 | > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
|
215 |
|
216 | **component.js**
|
217 |
|
218 | ```js
|
219 | import styles from "./styles.lazy.css";
|
220 |
|
221 | styles.use();
|
222 | // For removing styles you can use
|
223 | // styles.unuse();
|
224 | ```
|
225 |
|
226 | **component-with-css-modules.js**
|
227 |
|
228 | ```js
|
229 | import styles from "./styles.lazy.css";
|
230 |
|
231 | styles.use();
|
232 |
|
233 | const divElement = document.createElement("div");
|
234 | divElement.className = styles.locals["my-class"];
|
235 | ```
|
236 |
|
237 | All locals (class names) stored in `locals` property of imported object.
|
238 |
|
239 | **webpack.config.js**
|
240 |
|
241 | ```js
|
242 | module.exports = {
|
243 | module: {
|
244 | rules: [
|
245 | {
|
246 | test: /\.css$/i,
|
247 | exclude: /\.lazy\.css$/i,
|
248 | use: ["style-loader", "css-loader"],
|
249 | },
|
250 | {
|
251 | test: /\.lazy\.css$/i,
|
252 | use: [
|
253 | { loader: "style-loader", options: { injectType: "lazyStyleTag" } },
|
254 | "css-loader",
|
255 | ],
|
256 | },
|
257 | ],
|
258 | },
|
259 | };
|
260 | ```
|
261 |
|
262 | The loader inject styles like:
|
263 |
|
264 | ```html
|
265 | <style>
|
266 | .foo {
|
267 | color: red;
|
268 | }
|
269 | </style>
|
270 | <style>
|
271 | .bar {
|
272 | color: blue;
|
273 | }
|
274 | </style>
|
275 | ```
|
276 |
|
277 | #### `lazySingletonStyleTag`
|
278 |
|
279 | Injects styles into the DOM using one `<style></style>` on demand.
|
280 | We recommend following `.lazy.css` naming convention for lazy styles and the `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`).
|
281 | When you `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
|
282 |
|
283 | > ⚠️ Source maps do not work.
|
284 |
|
285 | > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
|
286 |
|
287 | **component.js**
|
288 |
|
289 | ```js
|
290 | import styles from "./styles.css";
|
291 |
|
292 | styles.use();
|
293 | // For removing styles you can use
|
294 | // styles.unuse();
|
295 | ```
|
296 |
|
297 | **component-with-css-modules.js**
|
298 |
|
299 | ```js
|
300 | import styles from "./styles.lazy.css";
|
301 |
|
302 | styles.use();
|
303 |
|
304 | const divElement = document.createElement("div");
|
305 | divElement.className = styles.locals["my-class"];
|
306 | ```
|
307 |
|
308 | All locals (class names) stored in `locals` property of imported object.
|
309 |
|
310 | **webpack.config.js**
|
311 |
|
312 | ```js
|
313 | module.exports = {
|
314 | module: {
|
315 | rules: [
|
316 | {
|
317 | test: /\.css$/i,
|
318 | exclude: /\.lazy\.css$/i,
|
319 | use: ["style-loader", "css-loader"],
|
320 | },
|
321 | {
|
322 | test: /\.lazy\.css$/i,
|
323 | use: [
|
324 | {
|
325 | loader: "style-loader",
|
326 | options: { injectType: "lazySingletonStyleTag" },
|
327 | },
|
328 | "css-loader",
|
329 | ],
|
330 | },
|
331 | ],
|
332 | },
|
333 | };
|
334 | ```
|
335 |
|
336 | The loader generate this:
|
337 |
|
338 | ```html
|
339 | <style>
|
340 | .foo {
|
341 | color: red;
|
342 | }
|
343 | .bar {
|
344 | color: blue;
|
345 | }
|
346 | </style>
|
347 | ```
|
348 |
|
349 | #### `lazyAutoStyleTag`
|
350 |
|
351 | Works the same as a [`lazyStyleTag`](#lazyStyleTag), but if the code is executed in IE6-9, turns on the [`lazySingletonStyleTag`](#lazySingletonStyleTag) mode.
|
352 |
|
353 | #### `linkTag`
|
354 |
|
355 | Injects styles into the DOM using multiple `<link rel="stylesheet" href="path/to/file.css">` .
|
356 |
|
357 | > ℹ️ The loader will dynamically insert the `<link href="path/to/file.css" rel="stylesheet">` tag at runtime via JavaScript. You should use [MiniCssExtractPlugin](https://webpack.js.org/plugins/mini-css-extract-plugin/) if you want to include a static `<link href="path/to/file.css" rel="stylesheet">`.
|
358 |
|
359 | ```js
|
360 | import "./styles.css";
|
361 | import "./other-styles.css";
|
362 | ```
|
363 |
|
364 | **webpack.config.js**
|
365 |
|
366 | ```js
|
367 | module.exports = {
|
368 | module: {
|
369 | rules: [
|
370 | {
|
371 | test: /\.link\.css$/i,
|
372 | use: [
|
373 | { loader: "style-loader", options: { injectType: "linkTag" } },
|
374 | { loader: "file-loader" },
|
375 | ],
|
376 | },
|
377 | ],
|
378 | },
|
379 | };
|
380 | ```
|
381 |
|
382 | The loader generate this:
|
383 |
|
384 | ```html
|
385 | <link rel="stylesheet" href="path/to/style.css" />
|
386 | <link rel="stylesheet" href="path/to/other-styles.css" />
|
387 | ```
|
388 |
|
389 | ### `attributes`
|
390 |
|
391 | Type: `Object`
|
392 | Default: `{}`
|
393 |
|
394 | If defined, the `style-loader` will attach given attributes with their values on `<style>` / `<link>` element.
|
395 |
|
396 | **component.js**
|
397 |
|
398 | ```js
|
399 | import style from "./file.css";
|
400 | ```
|
401 |
|
402 | **webpack.config.js**
|
403 |
|
404 | ```js
|
405 | module.exports = {
|
406 | module: {
|
407 | rules: [
|
408 | {
|
409 | test: /\.css$/i,
|
410 | use: [
|
411 | { loader: "style-loader", options: { attributes: { id: "id" } } },
|
412 | { loader: "css-loader" },
|
413 | ],
|
414 | },
|
415 | ],
|
416 | },
|
417 | };
|
418 | ```
|
419 |
|
420 | ```html
|
421 | <style id="id"></style>
|
422 | ```
|
423 |
|
424 | ### `insert`
|
425 |
|
426 | Type: `String|Function`
|
427 | Default: `head`
|
428 |
|
429 | By default, the `style-loader` appends `<style>`/`<link>` elements to the end of the style target, which is the `<head>` tag of the page unless specified by `insert`.
|
430 | This will cause CSS created by the loader to take priority over CSS already present in the target.
|
431 | You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
|
432 | If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure you have sufficient access rights, the styles will be injected into the content document head.
|
433 |
|
434 | #### `String`
|
435 |
|
436 | ##### `Selector`
|
437 |
|
438 | Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
|
439 |
|
440 | **webpack.config.js**
|
441 |
|
442 | ```js
|
443 | module.exports = {
|
444 | module: {
|
445 | rules: [
|
446 | {
|
447 | test: /\.css$/i,
|
448 | use: [
|
449 | {
|
450 | loader: "style-loader",
|
451 | options: {
|
452 | insert: "body",
|
453 | },
|
454 | },
|
455 | "css-loader",
|
456 | ],
|
457 | },
|
458 | ],
|
459 | },
|
460 | };
|
461 | ```
|
462 |
|
463 | ##### `Absolute path to function`
|
464 |
|
465 | Allows to setup absolute path to custom function that allows to override default behavior and insert styles at any position.
|
466 |
|
467 | > ⚠ Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc. We recommend using [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) for support latest ECMA features.
|
468 | > ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
|
469 |
|
470 | **webpack.config.js**
|
471 |
|
472 | ```js
|
473 | module.exports = {
|
474 | module: {
|
475 | rules: [
|
476 | {
|
477 | test: /\.css$/i,
|
478 | use: [
|
479 | {
|
480 | loader: "style-loader",
|
481 | options: {
|
482 | insert: require.resolve("modulePath"),
|
483 | },
|
484 | },
|
485 | "css-loader",
|
486 | ],
|
487 | },
|
488 | ],
|
489 | },
|
490 | };
|
491 | ```
|
492 |
|
493 | A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
|
494 |
|
495 | #### `Function`
|
496 |
|
497 | Allows to override default behavior and insert styles at any position.
|
498 |
|
499 | > ⚠ Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, we recommend use only ECMA 5 features, but it is depends what browsers you want to support
|
500 | > ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
|
501 |
|
502 | **webpack.config.js**
|
503 |
|
504 | ```js
|
505 | module.exports = {
|
506 | module: {
|
507 | rules: [
|
508 | {
|
509 | test: /\.css$/i,
|
510 | use: [
|
511 | {
|
512 | loader: "style-loader",
|
513 | options: {
|
514 | insert: function insertAtTop(element) {
|
515 | var parent = document.querySelector("head");
|
516 | // eslint-disable-next-line no-underscore-dangle
|
517 | var lastInsertedElement =
|
518 | window._lastElementInsertedByStyleLoader;
|
519 |
|
520 | if (!lastInsertedElement) {
|
521 | parent.insertBefore(element, parent.firstChild);
|
522 | } else if (lastInsertedElement.nextSibling) {
|
523 | parent.insertBefore(element, lastInsertedElement.nextSibling);
|
524 | } else {
|
525 | parent.appendChild(element);
|
526 | }
|
527 |
|
528 | // eslint-disable-next-line no-underscore-dangle
|
529 | window._lastElementInsertedByStyleLoader = element;
|
530 | },
|
531 | },
|
532 | },
|
533 | "css-loader",
|
534 | ],
|
535 | },
|
536 | ],
|
537 | },
|
538 | };
|
539 | ```
|
540 |
|
541 | Insert styles at top of `head` tag.
|
542 |
|
543 | You can pass any parameters to `style.use(options)` and this value will be passed to `insert` and `styleTagTransform` functions.
|
544 |
|
545 | **webpack.config.js**
|
546 |
|
547 | ```js
|
548 | module.exports = {
|
549 | module: {
|
550 | rules: [
|
551 | {
|
552 | test: /\.css$/i,
|
553 | use: [
|
554 | {
|
555 | loader: "style-loader",
|
556 | options: {
|
557 | injectType: "lazyStyleTag",
|
558 | // Do not forget that this code will be used in the browser and
|
559 | // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
|
560 | // we recommend use only ECMA 5 features,
|
561 | // but it is depends what browsers you want to support
|
562 | insert: function insertIntoTarget(element, options) {
|
563 | var parent = options.target || document.head;
|
564 |
|
565 | parent.appendChild(element);
|
566 | },
|
567 | },
|
568 | },
|
569 | "css-loader",
|
570 | ],
|
571 | },
|
572 | ],
|
573 | },
|
574 | };
|
575 | ```
|
576 |
|
577 | Insert styles to the provided element or to the `head` tag if target isn't provided. Now you can inject styles into Shadow DOM (or any other element).
|
578 |
|
579 | **custom-square.css**
|
580 |
|
581 | ```css
|
582 | div {
|
583 | width: 50px;
|
584 | height: 50px;
|
585 | background-color: red;
|
586 | }
|
587 | ```
|
588 |
|
589 | **custom-square.js**
|
590 |
|
591 | ```js
|
592 | import customSquareStyles from "./custom-square.css";
|
593 |
|
594 | class CustomSquare extends HTMLElement {
|
595 | constructor() {
|
596 | super();
|
597 |
|
598 | this.attachShadow({ mode: "open" });
|
599 |
|
600 | const divElement = document.createElement("div");
|
601 |
|
602 | divElement.textContent = "Text content.";
|
603 |
|
604 | this.shadowRoot.appendChild(divElement);
|
605 |
|
606 | customSquareStyles.use({ target: this.shadowRoot });
|
607 |
|
608 | // You can override injected styles
|
609 | const bgPurple = new CSSStyleSheet();
|
610 | const width = this.getAttribute("w");
|
611 | const height = this.getAttribute("h");
|
612 |
|
613 | bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);
|
614 |
|
615 | this.shadowRoot.adoptedStyleSheets = [bgPurple];
|
616 |
|
617 | // `divElement` will have `100px` width, `100px` height and `red` background color
|
618 | }
|
619 | }
|
620 |
|
621 | customElements.define("custom-square", CustomSquare);
|
622 |
|
623 | export default CustomSquare;
|
624 | ```
|
625 |
|
626 | ### `styleTagTransform`
|
627 |
|
628 | Type: `String | Function`
|
629 | Default: `undefined`
|
630 |
|
631 | #### `String`
|
632 |
|
633 | Allows to setup absolute path to custom function that allows to override default behavior styleTagTransform.
|
634 |
|
635 | > ⚠ Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, we recommend use only ECMA 5 features, but it is depends what browsers you want to support
|
636 |
|
637 | **webpack.config.js**
|
638 |
|
639 | ```js
|
640 | module.exports = {
|
641 | module: {
|
642 | rules: [
|
643 | {
|
644 | test: /\.css$/i,
|
645 | use: [
|
646 | {
|
647 | loader: "style-loader",
|
648 | options: {
|
649 | injectType: "styleTag",
|
650 | styleTagTransform: require.resolve("module-path"),
|
651 | },
|
652 | },
|
653 | "css-loader",
|
654 | ],
|
655 | },
|
656 | ],
|
657 | },
|
658 | };
|
659 | ```
|
660 |
|
661 | #### `Function`
|
662 |
|
663 | Transform tag and css when insert 'style' tag into the DOM.
|
664 |
|
665 | > ⚠ Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, we recommend use only ECMA 5 features, but it is depends what browsers you want to support
|
666 | > ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
|
667 |
|
668 | **webpack.config.js**
|
669 |
|
670 | ```js
|
671 | module.exports = {
|
672 | module: {
|
673 | rules: [
|
674 | {
|
675 | test: /\.css$/i,
|
676 | use: [
|
677 | {
|
678 | loader: "style-loader",
|
679 | options: {
|
680 | injectType: "styleTag",
|
681 | styleTagTransform: function (css, style) {
|
682 | // Do something ...
|
683 | style.innerHTML = `${css}.modify{}\n`;
|
684 |
|
685 | document.head.appendChild(style);
|
686 | },
|
687 | },
|
688 | },
|
689 | "css-loader",
|
690 | ],
|
691 | },
|
692 | ],
|
693 | },
|
694 | };
|
695 | ```
|
696 |
|
697 | ### `base`
|
698 |
|
699 | This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.me.uk/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.:
|
700 |
|
701 | **webpack.dll1.config.js**
|
702 |
|
703 | ```js
|
704 | module.exports = {
|
705 | module: {
|
706 | rules: [
|
707 | {
|
708 | test: /\.css$/i,
|
709 | use: ["style-loader", "css-loader"],
|
710 | },
|
711 | ],
|
712 | },
|
713 | };
|
714 | ```
|
715 |
|
716 | **webpack.dll2.config.js**
|
717 |
|
718 | ```js
|
719 | module.exports = {
|
720 | module: {
|
721 | rules: [
|
722 | {
|
723 | test: /\.css$/i,
|
724 | use: [
|
725 | { loader: "style-loader", options: { base: 1000 } },
|
726 | "css-loader",
|
727 | ],
|
728 | },
|
729 | ],
|
730 | },
|
731 | };
|
732 | ```
|
733 |
|
734 | **webpack.app.config.js**
|
735 |
|
736 | ```js
|
737 | module.exports = {
|
738 | module: {
|
739 | rules: [
|
740 | {
|
741 | test: /\.css$/i,
|
742 | use: [
|
743 | { loader: "style-loader", options: { base: 2000 } },
|
744 | "css-loader",
|
745 | ],
|
746 | },
|
747 | ],
|
748 | },
|
749 | };
|
750 | ```
|
751 |
|
752 | ### `esModule`
|
753 |
|
754 | Type: `Boolean`
|
755 | Default: `true`
|
756 |
|
757 | By default, `style-loader` generates JS modules that use the ES modules syntax.
|
758 | There 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/).
|
759 |
|
760 | You can enable a CommonJS modules syntax using:
|
761 |
|
762 | **webpack.config.js**
|
763 |
|
764 | ```js
|
765 | module.exports = {
|
766 | module: {
|
767 | rules: [
|
768 | {
|
769 | test: /\.css$/i,
|
770 | loader: "style-loader",
|
771 | options: {
|
772 | esModule: false,
|
773 | },
|
774 | },
|
775 | ],
|
776 | },
|
777 | };
|
778 | ```
|
779 |
|
780 | ## Examples
|
781 |
|
782 | ### Recommend
|
783 |
|
784 | For `production` builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
|
785 | This can be achieved by using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin), because it creates separate css files.
|
786 | For `development` mode (including `webpack-dev-server`) you can use `style-loader`, because it injects CSS into the DOM using multiple `<style></style>` and works faster.
|
787 |
|
788 | > ⚠ Do not use together `style-loader` and `mini-css-extract-plugin`.
|
789 |
|
790 | **webpack.config.js**
|
791 |
|
792 | ```js
|
793 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
794 | const devMode = process.env.NODE_ENV !== "production";
|
795 |
|
796 | module.exports = {
|
797 | module: {
|
798 | rules: [
|
799 | {
|
800 | test: /\.(sa|sc|c)ss$/,
|
801 | use: [
|
802 | devMode ? "style-loader" : MiniCssExtractPlugin.loader,
|
803 | "css-loader",
|
804 | "postcss-loader",
|
805 | "sass-loader",
|
806 | ],
|
807 | },
|
808 | ],
|
809 | },
|
810 | plugins: [].concat(devMode ? [] : [new MiniCssExtractPlugin()]),
|
811 | };
|
812 | ```
|
813 |
|
814 | ### Named export for CSS Modules
|
815 |
|
816 | > ⚠ Names of locals are converted to `camelCase`.
|
817 |
|
818 | > ⚠ It is not allowed to use JavaScript reserved words in css class names.
|
819 |
|
820 | > ⚠ Options `esModule` and `modules.namedExport` in `css-loader` should be enabled.
|
821 |
|
822 | **styles.css**
|
823 |
|
824 | ```css
|
825 | .foo-baz {
|
826 | color: red;
|
827 | }
|
828 | .bar {
|
829 | color: blue;
|
830 | }
|
831 | ```
|
832 |
|
833 | **index.js**
|
834 |
|
835 | ```js
|
836 | import { fooBaz, bar } from "./styles.css";
|
837 |
|
838 | console.log(fooBaz, bar);
|
839 | ```
|
840 |
|
841 | You can enable a ES module named export using:
|
842 |
|
843 | **webpack.config.js**
|
844 |
|
845 | ```js
|
846 | module.exports = {
|
847 | module: {
|
848 | rules: [
|
849 | {
|
850 | test: /\.css$/,
|
851 | use: [
|
852 | {
|
853 | loader: "style-loader",
|
854 | },
|
855 | {
|
856 | loader: "css-loader",
|
857 | options: {
|
858 | modules: {
|
859 | namedExport: true,
|
860 | },
|
861 | },
|
862 | },
|
863 | ],
|
864 | },
|
865 | ],
|
866 | },
|
867 | };
|
868 | ```
|
869 |
|
870 | ### Source maps
|
871 |
|
872 | The loader automatically inject source maps when previous loader emit them.
|
873 | Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader.
|
874 |
|
875 | **webpack.config.js**
|
876 |
|
877 | ```js
|
878 | module.exports = {
|
879 | module: {
|
880 | rules: [
|
881 | {
|
882 | test: /\.css$/i,
|
883 | use: [
|
884 | "style-loader",
|
885 | { loader: "css-loader", options: { sourceMap: true } },
|
886 | ],
|
887 | },
|
888 | ],
|
889 | },
|
890 | };
|
891 | ```
|
892 |
|
893 | ### Nonce
|
894 |
|
895 | There are two ways to work with `nonce`:
|
896 |
|
897 | - using the `attributes` option
|
898 | - using the `__webpack_nonce__` variable
|
899 |
|
900 | > ⚠ the `attributes` option takes precedence over the `__webpack_nonce__` variable
|
901 |
|
902 | #### `attributes`
|
903 |
|
904 | **component.js**
|
905 |
|
906 | ```js
|
907 | import "./style.css";
|
908 | ```
|
909 |
|
910 | **webpack.config.js**
|
911 |
|
912 | ```js
|
913 | module.exports = {
|
914 | module: {
|
915 | rules: [
|
916 | {
|
917 | test: /\.css$/i,
|
918 | use: [
|
919 | {
|
920 | loader: "style-loader",
|
921 | options: {
|
922 | attributes: {
|
923 | nonce: "12345678",
|
924 | },
|
925 | },
|
926 | },
|
927 | "css-loader",
|
928 | ],
|
929 | },
|
930 | ],
|
931 | },
|
932 | };
|
933 | ```
|
934 |
|
935 | The loader generate:
|
936 |
|
937 | ```html
|
938 | <style nonce="12345678">
|
939 | .foo {
|
940 | color: red;
|
941 | }
|
942 | </style>
|
943 | ```
|
944 |
|
945 | #### `__webpack_nonce__`
|
946 |
|
947 | **create-nonce.js**
|
948 |
|
949 | ```js
|
950 | __webpack_nonce__ = "12345678";
|
951 | ```
|
952 |
|
953 | **component.js**
|
954 |
|
955 | ```js
|
956 | import "./create-nonce.js";
|
957 | import "./style.css";
|
958 | ```
|
959 |
|
960 | Alternative example for `require`:
|
961 |
|
962 | **component.js**
|
963 |
|
964 | ```js
|
965 | __webpack_nonce__ = "12345678";
|
966 |
|
967 | require("./style.css");
|
968 | ```
|
969 |
|
970 | **webpack.config.js**
|
971 |
|
972 | ```js
|
973 | module.exports = {
|
974 | module: {
|
975 | rules: [
|
976 | {
|
977 | test: /\.css$/i,
|
978 | use: ["style-loader", "css-loader"],
|
979 | },
|
980 | ],
|
981 | },
|
982 | };
|
983 | ```
|
984 |
|
985 | The loader generate:
|
986 |
|
987 | ```html
|
988 | <style nonce="12345678">
|
989 | .foo {
|
990 | color: red;
|
991 | }
|
992 | </style>
|
993 | ```
|
994 |
|
995 | #### Insert styles at top
|
996 |
|
997 | Inserts styles at top of `head` tag.
|
998 |
|
999 | **webpack.config.js**
|
1000 |
|
1001 | ```js
|
1002 | module.exports = {
|
1003 | module: {
|
1004 | rules: [
|
1005 | {
|
1006 | test: /\.css$/i,
|
1007 | use: [
|
1008 | {
|
1009 | loader: "style-loader",
|
1010 | options: {
|
1011 | insert: function insertAtTop(element) {
|
1012 | var parent = document.querySelector("head");
|
1013 | var lastInsertedElement =
|
1014 | window._lastElementInsertedByStyleLoader;
|
1015 |
|
1016 | if (!lastInsertedElement) {
|
1017 | parent.insertBefore(element, parent.firstChild);
|
1018 | } else if (lastInsertedElement.nextSibling) {
|
1019 | parent.insertBefore(element, lastInsertedElement.nextSibling);
|
1020 | } else {
|
1021 | parent.appendChild(element);
|
1022 | }
|
1023 |
|
1024 | window._lastElementInsertedByStyleLoader = element;
|
1025 | },
|
1026 | },
|
1027 | },
|
1028 | "css-loader",
|
1029 | ],
|
1030 | },
|
1031 | ],
|
1032 | },
|
1033 | };
|
1034 | ```
|
1035 |
|
1036 | #### Insert styles before target element
|
1037 |
|
1038 | Inserts styles before `#id` element.
|
1039 |
|
1040 | **webpack.config.js**
|
1041 |
|
1042 | ```js
|
1043 | module.exports = {
|
1044 | module: {
|
1045 | rules: [
|
1046 | {
|
1047 | test: /\.css$/i,
|
1048 | use: [
|
1049 | {
|
1050 | loader: "style-loader",
|
1051 | options: {
|
1052 | insert: function insertBeforeAt(element) {
|
1053 | const parent = document.querySelector("head");
|
1054 | const target = document.querySelector("#id");
|
1055 |
|
1056 | const lastInsertedElement =
|
1057 | window._lastElementInsertedByStyleLoader;
|
1058 |
|
1059 | if (!lastInsertedElement) {
|
1060 | parent.insertBefore(element, target);
|
1061 | } else if (lastInsertedElement.nextSibling) {
|
1062 | parent.insertBefore(element, lastInsertedElement.nextSibling);
|
1063 | } else {
|
1064 | parent.appendChild(element);
|
1065 | }
|
1066 |
|
1067 | window._lastElementInsertedByStyleLoader = element;
|
1068 | },
|
1069 | },
|
1070 | },
|
1071 | "css-loader",
|
1072 | ],
|
1073 | },
|
1074 | ],
|
1075 | },
|
1076 | };
|
1077 | ```
|
1078 |
|
1079 | #### Custom Elements (Shadow DOM)
|
1080 |
|
1081 | You can define custom target for your styles for the `lazyStyleTag` type.
|
1082 |
|
1083 | **webpack.config.js**
|
1084 |
|
1085 | ```js
|
1086 | module.exports = {
|
1087 | module: {
|
1088 | rules: [
|
1089 | {
|
1090 | test: /\.css$/i,
|
1091 | use: [
|
1092 | {
|
1093 | loader: "style-loader",
|
1094 | options: {
|
1095 | injectType: "lazyStyleTag",
|
1096 | // Do not forget that this code will be used in the browser and
|
1097 | // not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc,
|
1098 | // we recommend use only ECMA 5 features,
|
1099 | // but it is depends what browsers you want to support
|
1100 | insert: function insertIntoTarget(element, options) {
|
1101 | var parent = options.target || document.head;
|
1102 |
|
1103 | parent.appendChild(element);
|
1104 | },
|
1105 | },
|
1106 | },
|
1107 | "css-loader",
|
1108 | ],
|
1109 | },
|
1110 | ],
|
1111 | },
|
1112 | };
|
1113 | ```
|
1114 |
|
1115 | Insert styles to the provided element or to the `head` tag if target isn't provided.
|
1116 |
|
1117 | **custom-square.css**
|
1118 |
|
1119 | ```css
|
1120 | div {
|
1121 | width: 50px;
|
1122 | height: 50px;
|
1123 | background-color: red;
|
1124 | }
|
1125 | ```
|
1126 |
|
1127 | **custom-square.js**
|
1128 |
|
1129 | ```js
|
1130 | import customSquareStyles from "./custom-square.css";
|
1131 |
|
1132 | class CustomSquare extends HTMLElement {
|
1133 | constructor() {
|
1134 | super();
|
1135 |
|
1136 | this.attachShadow({ mode: "open" });
|
1137 |
|
1138 | const divElement = document.createElement("div");
|
1139 |
|
1140 | divElement.textContent = "Text content.";
|
1141 |
|
1142 | this.shadowRoot.appendChild(divElement);
|
1143 |
|
1144 | customSquareStyles.use({ target: this.shadowRoot });
|
1145 |
|
1146 | // You can override injected styles
|
1147 | const bgPurple = new CSSStyleSheet();
|
1148 | const width = this.getAttribute("w");
|
1149 | const height = this.getAttribute("h");
|
1150 |
|
1151 | bgPurple.replace(`div { width: ${width}px; height: ${height}px; }`);
|
1152 |
|
1153 | this.shadowRoot.adoptedStyleSheets = [bgPurple];
|
1154 |
|
1155 | // `divElement` will have `100px` width, `100px` height and `red` background color
|
1156 | }
|
1157 | }
|
1158 |
|
1159 | customElements.define("custom-square", CustomSquare);
|
1160 |
|
1161 | export default CustomSquare;
|
1162 | ```
|
1163 |
|
1164 | ## Contributing
|
1165 |
|
1166 | Please take a moment to read our contributing guidelines if you haven't yet done so.
|
1167 |
|
1168 | [CONTRIBUTING](./.github/CONTRIBUTING.md)
|
1169 |
|
1170 | ## License
|
1171 |
|
1172 | [MIT](./LICENSE)
|
1173 |
|
1174 | [npm]: https://img.shields.io/npm/v/style-loader.svg
|
1175 | [npm-url]: https://npmjs.com/package/style-loader
|
1176 | [node]: https://img.shields.io/node/v/style-loader.svg
|
1177 | [node-url]: https://nodejs.org
|
1178 | [deps]: https://david-dm.org/webpack-contrib/style-loader.svg
|
1179 | [deps-url]: https://david-dm.org/webpack-contrib/style-loader
|
1180 | [tests]: https://github.com/webpack-contrib/style-loader/workflows/style-loader/badge.svg
|
1181 | [tests-url]: https://github.com/webpack-contrib/style-loader/actions
|
1182 | [cover]: https://codecov.io/gh/webpack-contrib/style-loader/branch/master/graph/badge.svg
|
1183 | [cover-url]: https://codecov.io/gh/webpack-contrib/style-loader
|
1184 | [chat]: https://badges.gitter.im/webpack/webpack.svg
|
1185 | [chat-url]: https://gitter.im/webpack/webpack
|
1186 | [size]: https://packagephobia.now.sh/badge?p=style-loader
|
1187 | [size-url]: https://packagephobia.now.sh/result?p=style-loader
|