1 | <div align="center">
|
2 | <img height="170"
|
3 | src="https://worldvectorlogo.com/logos/sass-1.svg">
|
4 | <a href="https://github.com/webpack/webpack">
|
5 | <img width="200" height="200"
|
6 | src="https://webpack.js.org/assets/icon-square-big.svg">
|
7 | </a>
|
8 | </div>
|
9 |
|
10 | [![npm][npm]][npm-url]
|
11 | [![node][node]][node-url]
|
12 | [![tests][tests]][tests-url]
|
13 | [![coverage][cover]][cover-url]
|
14 | [![chat][chat]][chat-url]
|
15 | [![size][size]][size-url]
|
16 |
|
17 | # sass-loader
|
18 |
|
19 | Loads a Sass/SCSS file and compiles it to CSS.
|
20 |
|
21 | ## Getting Started
|
22 |
|
23 | To begin, you'll need to install `sass-loader`:
|
24 |
|
25 | ```console
|
26 | npm install sass-loader sass webpack --save-dev
|
27 | ```
|
28 |
|
29 | or
|
30 |
|
31 | ```console
|
32 | yarn add -D sass-loader sass webpack
|
33 | ```
|
34 |
|
35 | or
|
36 |
|
37 | ```console
|
38 | pnpm add -D sass-loader sass webpack
|
39 | ```
|
40 |
|
41 | `sass-loader` requires you to install either [Dart Sass](https://github.com/sass/dart-sass), [Node Sass](https://github.com/sass/node-sass) on your own (more documentation can be found below) or [Sass Embedded](https://github.com/sass/embedded-host-node).
|
42 |
|
43 | This allows you to control the versions of all your dependencies, and to choose which Sass implementation to use.
|
44 |
|
45 | > **Note**
|
46 | >
|
47 | > We highly recommend using [Dart Sass](https://github.com/sass/dart-sass).
|
48 |
|
49 | > **Warning**
|
50 | >
|
51 | > [Node Sass](https://github.com/sass/node-sass) does not work with [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) feature and doesn't support [@use rule](https://sass-lang.com/documentation/at-rules/use).
|
52 |
|
53 | > **Warning**
|
54 | >
|
55 | > [Sass Embedded](https://github.com/sass/embedded-host-node) is experimental and in `beta`, therefore some features may not work
|
56 |
|
57 | Chain the `sass-loader` with the [css-loader](https://github.com/webpack-contrib/css-loader) and the [style-loader](https://github.com/webpack-contrib/style-loader) to immediately apply all styles to the DOM or the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract it into a separate file.
|
58 |
|
59 | Then add the loader to your Webpack configuration. For example:
|
60 |
|
61 | **app.js**
|
62 |
|
63 | ```js
|
64 | import "./style.scss";
|
65 | ```
|
66 |
|
67 | **style.scss**
|
68 |
|
69 | ```scss
|
70 | $body-color: red;
|
71 |
|
72 | body {
|
73 | color: $body-color;
|
74 | }
|
75 | ```
|
76 |
|
77 | **webpack.config.js**
|
78 |
|
79 | ```js
|
80 | module.exports = {
|
81 | module: {
|
82 | rules: [
|
83 | {
|
84 | test: /\.s[ac]ss$/i,
|
85 | use: [
|
86 | // Creates `style` nodes from JS strings
|
87 | "style-loader",
|
88 | // Translates CSS into CommonJS
|
89 | "css-loader",
|
90 | // Compiles Sass to CSS
|
91 | "sass-loader",
|
92 | ],
|
93 | },
|
94 | ],
|
95 | },
|
96 | };
|
97 | ```
|
98 |
|
99 | Finally run `webpack` via your preferred method.
|
100 |
|
101 | ### Resolving `import` at-rules
|
102 |
|
103 | Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
|
104 |
|
105 | The `sass-loader` uses Sass's custom importer feature to pass all queries to the Webpack resolving engine.
|
106 | Thus you can import your Sass modules from `node_modules`.
|
107 |
|
108 | ```scss
|
109 | @import "bootstrap";
|
110 | ```
|
111 |
|
112 | Using `~` is deprecated and can be removed from your code (**we recommend it**), but we still support it for historical reasons.
|
113 | Why can you remove it? The loader will first try to resolve `@import` as a relative path. If it cannot be resolved, then the loader will try to resolve `@import` inside [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules).
|
114 |
|
115 | Prepending module paths with a `~` tells webpack to search through [`node_modules`](https://webpack.js.org/configuration/resolve/#resolvemodules).
|
116 |
|
117 | ```scss
|
118 | @import "~bootstrap";
|
119 | ```
|
120 |
|
121 | It's important to prepend it with only `~`, because `~/` resolves to the home directory.
|
122 | Webpack needs to distinguish between `bootstrap` and `~bootstrap` because CSS and Sass files have no special syntax for importing relative files.
|
123 | Writing `@import "style.scss"` is the same as `@import "./style.scss";`
|
124 |
|
125 | ### Problems with `url(...)`
|
126 |
|
127 | Since Sass implementations don't provide [url rewriting](https://github.com/sass/libsass/issues/532), all linked assets must be relative to the output.
|
128 |
|
129 | - If you pass the generated CSS on to the `css-loader`, all urls must be relative to the entry-file (e.g. `main.scss`).
|
130 | - If you're just generating CSS without passing it to the `css-loader`, it must be relative to your web root.
|
131 |
|
132 | You will be disrupted by this first issue. It is natural to expect relative references to be resolved against the `.sass`/`.scss` file in which they are specified (like in regular `.css` files).
|
133 |
|
134 | Thankfully there are a two solutions to this problem:
|
135 |
|
136 | - Add the missing url rewriting using the [resolve-url-loader](https://github.com/bholloway/resolve-url-loader). Place it before `sass-loader` in the loader chain.
|
137 | - Library authors usually provide a variable to modify the asset path. [bootstrap-sass](https://github.com/twbs/bootstrap-sass) for example has an `$icon-font-path`.
|
138 |
|
139 | ## Options
|
140 |
|
141 | - **[`implementation`](#implementation)**
|
142 | - **[`sassOptions`](#sassoptions)**
|
143 | - **[`sourceMap`](#sourcemap)**
|
144 | - **[`additionalData`](#additionaldata)**
|
145 | - **[`webpackImporter`](#webpackimporter)**
|
146 | - **[`warnRuleAsWarning`](#warnruleaswarning)**
|
147 |
|
148 | ### `implementation`
|
149 |
|
150 | Type:
|
151 |
|
152 | ```ts
|
153 | type implementation = object | string;
|
154 | ```
|
155 |
|
156 | Default: `sass`
|
157 |
|
158 | The special `implementation` option determines which implementation of Sass to use.
|
159 |
|
160 | By default the loader resolve the implementation based on your dependencies.
|
161 | Just add required implementation to `package.json` (`sass` or `node-sass` package) and install dependencies.
|
162 |
|
163 | Example where the `sass-loader` loader uses the `sass` (`dart-sass`) implementation:
|
164 |
|
165 | **package.json**
|
166 |
|
167 | ```json
|
168 | {
|
169 | "devDependencies": {
|
170 | "sass-loader": "^7.2.0",
|
171 | "sass": "^1.22.10"
|
172 | }
|
173 | }
|
174 | ```
|
175 |
|
176 | Example where the `sass-loader` loader uses the `node-sass` implementation:
|
177 |
|
178 | **package.json**
|
179 |
|
180 | ```json
|
181 | {
|
182 | "devDependencies": {
|
183 | "sass-loader": "^7.2.0",
|
184 | "node-sass": "^5.0.0"
|
185 | }
|
186 | }
|
187 | ```
|
188 |
|
189 | Beware the situation when `node-sass` and `sass` were installed! By default the `sass-loader` prefers `sass`.
|
190 | In order to avoid this situation you can use the `implementation` option.
|
191 |
|
192 | The `implementation` options either accepts `sass` (`Dart Sass`) or `node-sass` as a module.
|
193 |
|
194 | #### `object`
|
195 |
|
196 | For example, to use Dart Sass, you'd pass:
|
197 |
|
198 | ```js
|
199 | module.exports = {
|
200 | module: {
|
201 | rules: [
|
202 | {
|
203 | test: /\.s[ac]ss$/i,
|
204 | use: [
|
205 | "style-loader",
|
206 | "css-loader",
|
207 | {
|
208 | loader: "sass-loader",
|
209 | options: {
|
210 | // Prefer `dart-sass`
|
211 | implementation: require("sass"),
|
212 | },
|
213 | },
|
214 | ],
|
215 | },
|
216 | ],
|
217 | },
|
218 | };
|
219 | ```
|
220 |
|
221 | #### `string`
|
222 |
|
223 | For example, to use Dart Sass, you'd pass:
|
224 |
|
225 | ```js
|
226 | module.exports = {
|
227 | module: {
|
228 | rules: [
|
229 | {
|
230 | test: /\.s[ac]ss$/i,
|
231 | use: [
|
232 | "style-loader",
|
233 | "css-loader",
|
234 | {
|
235 | loader: "sass-loader",
|
236 | options: {
|
237 | // Prefer `dart-sass`
|
238 | implementation: require.resolve("sass"),
|
239 | },
|
240 | },
|
241 | ],
|
242 | },
|
243 | ],
|
244 | },
|
245 | };
|
246 | ```
|
247 |
|
248 | Note that when using `sass` (`Dart Sass`), **synchronous compilation is twice as fast as asynchronous compilation** by default, due to the overhead of asynchronous callbacks.
|
249 | To avoid this overhead, you can use the [fibers](https://www.npmjs.com/package/fibers) package to call asynchronous importers from the synchronous code path.
|
250 |
|
251 | We automatically inject the [`fibers`](https://github.com/laverdet/node-fibers) package (setup `sassOptions.fiber`) for `Node.js` less v16.0.0 if is possible (i.e. you need install the [`fibers`](https://github.com/laverdet/node-fibers) package).
|
252 |
|
253 | > **Warning**
|
254 | >
|
255 | > Fibers is not compatible with `Node.js` v16.0.0 or later. Unfortunately, v8 commit [dacc2fee0f](https://github.com/v8/v8/commit/dacc2fee0f815823782a7e432c79c2a7767a4765) is a breaking change and workarounds are non-trivial. ([see introduction to readme](https://github.com/laverdet/node-fibers)).
|
256 |
|
257 | **package.json**
|
258 |
|
259 | ```json
|
260 | {
|
261 | "devDependencies": {
|
262 | "sass-loader": "^7.2.0",
|
263 | "sass": "^1.22.10",
|
264 | "fibers": "^4.0.1"
|
265 | }
|
266 | }
|
267 | ```
|
268 |
|
269 | You can disable automatically injecting the [`fibers`](https://github.com/laverdet/node-fibers) package by passing a `false` value for the `sassOptions.fiber` option.
|
270 |
|
271 | **webpack.config.js**
|
272 |
|
273 | ```js
|
274 | module.exports = {
|
275 | module: {
|
276 | rules: [
|
277 | {
|
278 | test: /\.s[ac]ss$/i,
|
279 | use: [
|
280 | "style-loader",
|
281 | "css-loader",
|
282 | {
|
283 | loader: "sass-loader",
|
284 | options: {
|
285 | implementation: require("sass"),
|
286 | sassOptions: {
|
287 | fiber: false,
|
288 | },
|
289 | },
|
290 | },
|
291 | ],
|
292 | },
|
293 | ],
|
294 | },
|
295 | };
|
296 | ```
|
297 |
|
298 | You can also pass the `fiber` value using this code:
|
299 |
|
300 | **webpack.config.js**
|
301 |
|
302 | ```js
|
303 | module.exports = {
|
304 | module: {
|
305 | rules: [
|
306 | {
|
307 | test: /\.s[ac]ss$/i,
|
308 | use: [
|
309 | "style-loader",
|
310 | "css-loader",
|
311 | {
|
312 | loader: "sass-loader",
|
313 | options: {
|
314 | implementation: require("sass"),
|
315 | sassOptions: {
|
316 | fiber: require("fibers"),
|
317 | },
|
318 | },
|
319 | },
|
320 | ],
|
321 | },
|
322 | ],
|
323 | },
|
324 | };
|
325 | ```
|
326 |
|
327 | ### `sassOptions`
|
328 |
|
329 | Type:
|
330 |
|
331 | ```ts
|
332 | type sassOptions =
|
333 | | import("sass").LegacyOptions<"async">
|
334 | | ((
|
335 | content: string | Buffer,
|
336 | loaderContext: LoaderContext,
|
337 | meta: any
|
338 | ) => import("sass").LegacyOptions<"async">);
|
339 | ```
|
340 |
|
341 | Default: defaults values for Sass implementation
|
342 |
|
343 | Options for [Dart Sass](http://sass-lang.com/dart-sass) or [Node Sass](https://github.com/sass/node-sass) implementation.
|
344 |
|
345 | > **Note**
|
346 | >
|
347 | > The `charset` option has `true` value by default for `dart-sass`, we strongly discourage change value to `false`, because webpack doesn't support files other than `utf-8`.
|
348 |
|
349 | > **Note**
|
350 | >
|
351 | > The `indentedSyntax` option has `true` value for the `sass` extension.
|
352 |
|
353 | > **Note**
|
354 | >
|
355 | > Options such as `data` and `file` are unavailable and will be ignored.
|
356 |
|
357 | > ℹ We strongly discourage change `outFile`, `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because `sass-loader` automatically sets these options when the `sourceMap` option is `true`.
|
358 |
|
359 | > **Note**
|
360 | >
|
361 | > Access to the [loader context](https://webpack.js.org/api/loaders/#the-loader-context) inside the custom importer can be done using the `this.webpackLoaderContext` property.
|
362 |
|
363 | There is a slight difference between the `sass` (`dart-sass`) and `node-sass` options.
|
364 |
|
365 | Please consult documentation before using them:
|
366 |
|
367 | - [Dart Sass documentation](https://sass-lang.com/documentation/js-api/interfaces/Options) for all available `sass` options.
|
368 | - [Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options.
|
369 |
|
370 | #### `object`
|
371 |
|
372 | Use an object for the Sass implementation setup.
|
373 |
|
374 | **webpack.config.js**
|
375 |
|
376 | ```js
|
377 | module.exports = {
|
378 | module: {
|
379 | rules: [
|
380 | {
|
381 | test: /\.s[ac]ss$/i,
|
382 | use: [
|
383 | "style-loader",
|
384 | "css-loader",
|
385 | {
|
386 | loader: "sass-loader",
|
387 | options: {
|
388 | sassOptions: {
|
389 | indentWidth: 4,
|
390 | includePaths: ["absolute/path/a", "absolute/path/b"],
|
391 | },
|
392 | },
|
393 | },
|
394 | ],
|
395 | },
|
396 | ],
|
397 | },
|
398 | };
|
399 | ```
|
400 |
|
401 | #### `function`
|
402 |
|
403 | Allows to setup the Sass implementation by setting different options based on the loader context.
|
404 |
|
405 | ```js
|
406 | module.exports = {
|
407 | module: {
|
408 | rules: [
|
409 | {
|
410 | test: /\.s[ac]ss$/i,
|
411 | use: [
|
412 | "style-loader",
|
413 | "css-loader",
|
414 | {
|
415 | loader: "sass-loader",
|
416 | options: {
|
417 | sassOptions: (loaderContext) => {
|
418 | // More information about available properties https://webpack.js.org/api/loaders/
|
419 | const { resourcePath, rootContext } = loaderContext;
|
420 | const relativePath = path.relative(rootContext, resourcePath);
|
421 |
|
422 | if (relativePath === "styles/foo.scss") {
|
423 | return {
|
424 | includePaths: ["absolute/path/c", "absolute/path/d"],
|
425 | };
|
426 | }
|
427 |
|
428 | return {
|
429 | includePaths: ["absolute/path/a", "absolute/path/b"],
|
430 | };
|
431 | },
|
432 | },
|
433 | },
|
434 | ],
|
435 | },
|
436 | ],
|
437 | },
|
438 | };
|
439 | ```
|
440 |
|
441 | ### `sourceMap`
|
442 |
|
443 | Type:
|
444 |
|
445 | ```ts
|
446 | type sourceMap = boolean;
|
447 | ```
|
448 |
|
449 | Default: depends on the `compiler.devtool` value
|
450 |
|
451 | Enables/Disables generation of source maps.
|
452 |
|
453 | By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option.
|
454 | All values enable source map generation except `eval` and `false` value.
|
455 |
|
456 | > ℹ If a `true` the `sourceMap`, `sourceMapRoot`, `sourceMapEmbed`, `sourceMapContents` and `omitSourceMapUrl` from `sassOptions` will be ignored.
|
457 |
|
458 | **webpack.config.js**
|
459 |
|
460 | ```js
|
461 | module.exports = {
|
462 | module: {
|
463 | rules: [
|
464 | {
|
465 | test: /\.s[ac]ss$/i,
|
466 | use: [
|
467 | "style-loader",
|
468 | {
|
469 | loader: "css-loader",
|
470 | options: {
|
471 | sourceMap: true,
|
472 | },
|
473 | },
|
474 | {
|
475 | loader: "sass-loader",
|
476 | options: {
|
477 | sourceMap: true,
|
478 | },
|
479 | },
|
480 | ],
|
481 | },
|
482 | ],
|
483 | },
|
484 | };
|
485 | ```
|
486 |
|
487 | > ℹ In some rare cases `node-sass` can output invalid source maps (it is a `node-sass` bug).
|
488 |
|
489 | > > In order to avoid this, you can try to update `node-sass` to latest version or you can try to set within `sassOptions` the `outputStyle` option to `compressed`.
|
490 |
|
491 | **webpack.config.js**
|
492 |
|
493 | ```js
|
494 | module.exports = {
|
495 | module: {
|
496 | rules: [
|
497 | {
|
498 | test: /\.s[ac]ss$/i,
|
499 | use: [
|
500 | "style-loader",
|
501 | "css-loader",
|
502 | {
|
503 | loader: "sass-loader",
|
504 | options: {
|
505 | sourceMap: true,
|
506 | sassOptions: {
|
507 | outputStyle: "compressed",
|
508 | },
|
509 | },
|
510 | },
|
511 | ],
|
512 | },
|
513 | ],
|
514 | },
|
515 | };
|
516 | ```
|
517 |
|
518 | ### `additionalData`
|
519 |
|
520 | Type:
|
521 |
|
522 | ```ts
|
523 | type additionalData =
|
524 | | string
|
525 | | ((content: string | Buffer, loaderContext: LoaderContext) => string);
|
526 | ```
|
527 |
|
528 | Default: `undefined`
|
529 |
|
530 | Prepends `Sass`/`SCSS` code before the actual entry file.
|
531 | In this case, the `sass-loader` will not override the `data` option but just **prepend** the entry's content.
|
532 |
|
533 | This is especially useful when some of your Sass variables depend on the environment:
|
534 |
|
535 | #### `string`
|
536 |
|
537 | ```js
|
538 | module.exports = {
|
539 | module: {
|
540 | rules: [
|
541 | {
|
542 | test: /\.s[ac]ss$/i,
|
543 | use: [
|
544 | "style-loader",
|
545 | "css-loader",
|
546 | {
|
547 | loader: "sass-loader",
|
548 | options: {
|
549 | additionalData: "$env: " + process.env.NODE_ENV + ";",
|
550 | },
|
551 | },
|
552 | ],
|
553 | },
|
554 | ],
|
555 | },
|
556 | };
|
557 | ```
|
558 |
|
559 | #### `function`
|
560 |
|
561 | ##### Sync
|
562 |
|
563 | ```js
|
564 | module.exports = {
|
565 | module: {
|
566 | rules: [
|
567 | {
|
568 | test: /\.s[ac]ss$/i,
|
569 | use: [
|
570 | "style-loader",
|
571 | "css-loader",
|
572 | {
|
573 | loader: "sass-loader",
|
574 | options: {
|
575 | additionalData: (content, loaderContext) => {
|
576 | // More information about available properties https://webpack.js.org/api/loaders/
|
577 | const { resourcePath, rootContext } = loaderContext;
|
578 | const relativePath = path.relative(rootContext, resourcePath);
|
579 |
|
580 | if (relativePath === "styles/foo.scss") {
|
581 | return "$value: 100px;" + content;
|
582 | }
|
583 |
|
584 | return "$value: 200px;" + content;
|
585 | },
|
586 | },
|
587 | },
|
588 | ],
|
589 | },
|
590 | ],
|
591 | },
|
592 | };
|
593 | ```
|
594 |
|
595 | ##### Async
|
596 |
|
597 | ```js
|
598 | module.exports = {
|
599 | module: {
|
600 | rules: [
|
601 | {
|
602 | test: /\.s[ac]ss$/i,
|
603 | use: [
|
604 | "style-loader",
|
605 | "css-loader",
|
606 | {
|
607 | loader: "sass-loader",
|
608 | options: {
|
609 | additionalData: async (content, loaderContext) => {
|
610 | // More information about available properties https://webpack.js.org/api/loaders/
|
611 | const { resourcePath, rootContext } = loaderContext;
|
612 | const relativePath = path.relative(rootContext, resourcePath);
|
613 |
|
614 | if (relativePath === "styles/foo.scss") {
|
615 | return "$value: 100px;" + content;
|
616 | }
|
617 |
|
618 | return "$value: 200px;" + content;
|
619 | },
|
620 | },
|
621 | },
|
622 | ],
|
623 | },
|
624 | ],
|
625 | },
|
626 | };
|
627 | ```
|
628 |
|
629 | ### `webpackImporter`
|
630 |
|
631 | Type:
|
632 |
|
633 | ```ts
|
634 | type webpackImporter = boolean;
|
635 | ```
|
636 |
|
637 | Default: `true`
|
638 |
|
639 | Enables/Disables the default Webpack importer.
|
640 |
|
641 | This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starting with `~` will not work.
|
642 | You can pass own `importer` to solve this (see [`importer docs`](https://github.com/sass/node-sass#importer--v200---experimental)).
|
643 |
|
644 | **webpack.config.js**
|
645 |
|
646 | ```js
|
647 | module.exports = {
|
648 | module: {
|
649 | rules: [
|
650 | {
|
651 | test: /\.s[ac]ss$/i,
|
652 | use: [
|
653 | "style-loader",
|
654 | "css-loader",
|
655 | {
|
656 | loader: "sass-loader",
|
657 | options: {
|
658 | webpackImporter: false,
|
659 | },
|
660 | },
|
661 | ],
|
662 | },
|
663 | ],
|
664 | },
|
665 | };
|
666 | ```
|
667 |
|
668 | ### `warnRuleAsWarning`
|
669 |
|
670 | Type:
|
671 |
|
672 | ```ts
|
673 | type warnRuleAsWarning = boolean;
|
674 | ```
|
675 |
|
676 | Default: `false`
|
677 |
|
678 | Treats the `@warn` rule as a webpack warning.
|
679 |
|
680 | > **Note**
|
681 | >
|
682 | > It will be `true` by default in the next major release.
|
683 |
|
684 | **style.scss**
|
685 |
|
686 | ```scss
|
687 | $known-prefixes: webkit, moz, ms, o;
|
688 |
|
689 | @mixin prefix($property, $value, $prefixes) {
|
690 | @each $prefix in $prefixes {
|
691 | @if not index($known-prefixes, $prefix) {
|
692 | @warn "Unknown prefix #{$prefix}.";
|
693 | }
|
694 |
|
695 | -#{$prefix}-#{$property}: $value;
|
696 | }
|
697 | #{$property}: $value;
|
698 | }
|
699 |
|
700 | .tilt {
|
701 | // Oops, we typo'd "webkit" as "wekbit"!
|
702 | @include prefix(transform, rotate(15deg), wekbit ms);
|
703 | }
|
704 | ```
|
705 |
|
706 | The presented code will throw webpack warning instead logging.
|
707 |
|
708 | To ignore unnecessary warnings you can use the [ignoreWarnings](https://webpack.js.org/configuration/other-options/#ignorewarnings) option.
|
709 |
|
710 | **webpack.config.js**
|
711 |
|
712 | ```js
|
713 | module.exports = {
|
714 | module: {
|
715 | rules: [
|
716 | {
|
717 | test: /\.s[ac]ss$/i,
|
718 | use: [
|
719 | "style-loader",
|
720 | "css-loader",
|
721 | {
|
722 | loader: "sass-loader",
|
723 | options: {
|
724 | warnRuleAsWarning: true,
|
725 | },
|
726 | },
|
727 | ],
|
728 | },
|
729 | ],
|
730 | },
|
731 | };
|
732 | ```
|
733 |
|
734 | ### `api`
|
735 |
|
736 | Type:
|
737 |
|
738 | ```ts
|
739 | type api = "legacy" | "modern";
|
740 | ```
|
741 |
|
742 | Default: `"legacy"`
|
743 |
|
744 | Allows you to switch between `legacy` and `modern` API. You can find more information [here](https://sass-lang.com/documentation/js-api).
|
745 |
|
746 | > **Warning**
|
747 | >
|
748 | > "modern" API is experimental, so some features may not work (known: built-in `importer` is not working and files with errors is not watching on initial run), you can follow this [here](https://github.com/webpack-contrib/sass-loader/issues/774).
|
749 |
|
750 | > **Warning**
|
751 | >
|
752 | > The sass options are different for `modern` and `old` APIs. Please look at [docs](https://sass-lang.com/documentation/js-api) how to migrate on new options.
|
753 |
|
754 | **webpack.config.js**
|
755 |
|
756 | ```js
|
757 | module.exports = {
|
758 | module: {
|
759 | rules: [
|
760 | {
|
761 | test: /\.s[ac]ss$/i,
|
762 | use: [
|
763 | "style-loader",
|
764 | "css-loader",
|
765 | {
|
766 | loader: "sass-loader",
|
767 | options: {
|
768 | api: "modern",
|
769 | sassOptions: {
|
770 | // Your sass options
|
771 | },
|
772 | },
|
773 | },
|
774 | ],
|
775 | },
|
776 | ],
|
777 | },
|
778 | };
|
779 | ```
|
780 |
|
781 | ## How to enable `@debug` output
|
782 |
|
783 | Defaults, the output of `@debug` messages is disabled.
|
784 | To enable it, add to **webpack.config.js** following:
|
785 |
|
786 | ```js
|
787 | module.exports = {
|
788 | stats: {
|
789 | loggingDebug: ["sass-loader"],
|
790 | },
|
791 | // ...
|
792 | };
|
793 | ```
|
794 |
|
795 | ## Examples
|
796 |
|
797 | ### Extracts CSS into separate files
|
798 |
|
799 | 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.
|
800 |
|
801 | There are two possibilities to extract a style sheet from the bundle:
|
802 |
|
803 | - [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin)
|
804 | - [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
|
805 |
|
806 | **webpack.config.js**
|
807 |
|
808 | ```js
|
809 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
810 |
|
811 | module.exports = {
|
812 | module: {
|
813 | rules: [
|
814 | {
|
815 | test: /\.s[ac]ss$/i,
|
816 | use: [
|
817 | // fallback to style-loader in development
|
818 | process.env.NODE_ENV !== "production"
|
819 | ? "style-loader"
|
820 | : MiniCssExtractPlugin.loader,
|
821 | "css-loader",
|
822 | "sass-loader",
|
823 | ],
|
824 | },
|
825 | ],
|
826 | },
|
827 | plugins: [
|
828 | new MiniCssExtractPlugin({
|
829 | // Options similar to the same options in webpackOptions.output
|
830 | // both options are optional
|
831 | filename: "[name].css",
|
832 | chunkFilename: "[id].css",
|
833 | }),
|
834 | ],
|
835 | };
|
836 | ```
|
837 |
|
838 | ### Source maps
|
839 |
|
840 | Enables/Disables generation of source maps.
|
841 |
|
842 | To enable CSS source maps, you'll need to pass the `sourceMap` option to the `sass-loader` _and_ the css-loader.
|
843 |
|
844 | **webpack.config.js**
|
845 |
|
846 | ```javascript
|
847 | module.exports = {
|
848 | devtool: "source-map", // any "source-map"-like devtool is possible
|
849 | module: {
|
850 | rules: [
|
851 | {
|
852 | test: /\.s[ac]ss$/i,
|
853 | use: [
|
854 | "style-loader",
|
855 | {
|
856 | loader: "css-loader",
|
857 | options: {
|
858 | sourceMap: true,
|
859 | },
|
860 | },
|
861 | {
|
862 | loader: "sass-loader",
|
863 | options: {
|
864 | sourceMap: true,
|
865 | },
|
866 | },
|
867 | ],
|
868 | },
|
869 | ],
|
870 | },
|
871 | };
|
872 | ```
|
873 |
|
874 | If you want to edit the original Sass files inside Chrome, [there's a good blog post](https://medium.com/@toolmantim/getting-started-with-css-sourcemaps-and-in-browser-sass-editing-b4daab987fb0). Checkout [test/sourceMap](https://github.com/webpack-contrib/sass-loader/tree/master/test) for a running example.
|
875 |
|
876 | ## Contributing
|
877 |
|
878 | Please take a moment to read our contributing guidelines if you haven't yet done so.
|
879 |
|
880 | [CONTRIBUTING](./.github/CONTRIBUTING.md)
|
881 |
|
882 | ## License
|
883 |
|
884 | [MIT](./LICENSE)
|
885 |
|
886 | [npm]: https://img.shields.io/npm/v/sass-loader.svg
|
887 | [npm-url]: https://npmjs.com/package/sass-loader
|
888 | [node]: https://img.shields.io/node/v/sass-loader.svg
|
889 | [node-url]: https://nodejs.org
|
890 | [tests]: https://github.com/webpack-contrib/sass-loader/workflows/sass-loader/badge.svg
|
891 | [tests-url]: https://github.com/webpack-contrib/sass-loader/actions
|
892 | [cover]: https://codecov.io/gh/webpack-contrib/sass-loader/branch/master/graph/badge.svg
|
893 | [cover-url]: https://codecov.io/gh/webpack-contrib/sass-loader
|
894 | [chat]: https://badges.gitter.im/webpack/webpack.svg
|
895 | [chat-url]: https://gitter.im/webpack/webpack
|
896 | [size]: https://packagephobia.now.sh/badge?p=sass-loader
|
897 | [size-url]: https://packagephobia.now.sh/result?p=sass-loader
|