UNPKG

18.1 kBMarkdownView Raw
1<div align="center">
2 <img height="100"
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[![deps][deps]][deps-url]
13[![tests][tests]][tests-url]
14[![coverage][cover]][cover-url]
15[![chat][chat]][chat-url]
16[![size][size]][size-url]
17
18# sass-loader
19
20Loads a Sass/SCSS file and compiles it to CSS.
21
22## Getting Started
23
24To begin, you'll need to install `sass-loader`:
25
26```console
27npm install sass-loader sass webpack --save-dev
28```
29
30`sass-loader` requires you to install either [Dart Sass](https://github.com/sass/dart-sass) or [Node Sass](https://github.com/sass/node-sass) on your own (more documentation can be found below).
31
32This allows you to control the versions of all your dependencies, and to choose which Sass implementation to use.
33
34> ℹ️ We recommend using [Dart Sass](https://github.com/sass/dart-sass).
35
36> ⚠ [Node Sass](https://github.com/sass/node-sass) does not work with [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) feature.
37
38Chain 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.
39
40Then add the loader to your Webpack configuration. For example:
41
42**app.js**
43
44```js
45import './style.scss';
46```
47
48**style.scss**
49
50```scss
51$body-color: red;
52
53body {
54 color: $body-color;
55}
56```
57
58**webpack.config.js**
59
60```js
61module.exports = {
62 module: {
63 rules: [
64 {
65 test: /\.s[ac]ss$/i,
66 use: [
67 // Creates `style` nodes from JS strings
68 'style-loader',
69 // Translates CSS into CommonJS
70 'css-loader',
71 // Compiles Sass to CSS
72 'sass-loader',
73 ],
74 },
75 ],
76 },
77};
78```
79
80Finally run `webpack` via your preferred method.
81
82### Resolving `import` at-rules
83
84Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
85
86The `sass-loader` uses Sass's custom importer feature to pass all queries to the Webpack resolving engine. Thus you can import your Sass modules from `node_modules`. Just prepend them with a `~` to tell Webpack that this is not a relative import:
87
88```scss
89@import '~bootstrap';
90```
91
92It's important to only prepend it with `~`, because `~/` resolves to the home directory.
93Webpack needs to distinguish between `bootstrap` and `~bootstrap` because CSS and Sass files have no special syntax for importing relative files.
94Writing `@import "style.scss"` is the same as `@import "./style.scss";`
95
96### Problems with `url(...)`
97
98Since Sass implementations don't provide [url rewriting](https://github.com/sass/libsass/issues/532), all linked assets must be relative to the output.
99
100- If you pass the generated CSS on to the `css-loader`, all urls must be relative to the entry-file (e.g. `main.scss`).
101- If you're just generating CSS without passing it to the `css-loader`, it must be relative to your web root.
102
103You 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).
104
105Thankfully there are a two solutions to this problem:
106
107- 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.
108- 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`.
109
110## Options
111
112| Name | Type | Default | Description |
113| :---------------------------------------: | :------------------: | :-------------------------------------: | :---------------------------------------------------------------- |
114| **[`implementation`](#implementation)** | `{Object}` | `sass` | Setup Sass implementation to use. |
115| **[`sassOptions`](#sassoptions)** | `{Object\|Function}` | defaults values for Sass implementation | Options for Sass. |
116| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
117| **[`additionalData`](#additionaldata)** | `{String\|Function}` | `undefined` | Prepends/Appends `Sass`/`SCSS` code before the actual entry file. |
118| **[`webpackImporter`](#webpackimporter)** | `{Boolean}` | `true` | Enables/Disables the default Webpack importer. |
119
120### `implementation`
121
122Type: `Object`
123Default: `sass`
124
125The special `implementation` option determines which implementation of Sass to use.
126
127By default the loader resolve the implementation based on your dependencies.
128Just add required implementation to `package.json` (`sass` or `node-sass` package) and install dependencies.
129
130Example where the `sass-loader` loader uses the `sass` (`dart-sass`) implementation:
131
132**package.json**
133
134```json
135{
136 "devDependencies": {
137 "sass-loader": "^7.2.0",
138 "sass": "^1.22.10"
139 }
140}
141```
142
143Example where the `sass-loader` loader uses the `node-sass` implementation:
144
145**package.json**
146
147```json
148{
149 "devDependencies": {
150 "sass-loader": "^7.2.0",
151 "node-sass": "^4.0.0"
152 }
153}
154```
155
156Beware the situation when `node-sass` and `sass` were installed! By default the `sass-loader` prefers `sass`.
157In order to avoid this situation you can use the `implementation` option.
158
159The `implementation` options either accepts `sass` (`Dart Sass`) or `node-sass` as a module.
160
161For example, to use Dart Sass, you'd pass:
162
163```js
164module.exports = {
165 module: {
166 rules: [
167 {
168 test: /\.s[ac]ss$/i,
169 use: [
170 'style-loader',
171 'css-loader',
172 {
173 loader: 'sass-loader',
174 options: {
175 // Prefer `dart-sass`
176 implementation: require('sass'),
177 },
178 },
179 ],
180 },
181 ],
182 },
183};
184```
185
186Note that when using `sass` (`Dart Sass`), **synchronous compilation is twice as fast as asynchronous compilation** by default, due to the overhead of asynchronous callbacks.
187To avoid this overhead, you can use the [fibers](https://www.npmjs.com/package/fibers) package to call asynchronous importers from the synchronous code path.
188
189We automatically inject the [`fibers`](https://github.com/laverdet/node-fibers) package (setup `sassOptions.fiber`) if is possible (i.e. you need install the [`fibers`](https://github.com/laverdet/node-fibers) package).
190
191**package.json**
192
193```json
194{
195 "devDependencies": {
196 "sass-loader": "^7.2.0",
197 "sass": "^1.22.10",
198 "fibers": "^4.0.1"
199 }
200}
201```
202
203You can disable automatically injecting the [`fibers`](https://github.com/laverdet/node-fibers) package by passing a `false` value for the `sassOptions.fiber` option.
204
205**webpack.config.js**
206
207```js
208module.exports = {
209 module: {
210 rules: [
211 {
212 test: /\.s[ac]ss$/i,
213 use: [
214 'style-loader',
215 'css-loader',
216 {
217 loader: 'sass-loader',
218 options: {
219 implementation: require('sass'),
220 sassOptions: {
221 fiber: false,
222 },
223 },
224 },
225 ],
226 },
227 ],
228 },
229};
230```
231
232You can also pass the `fiber` value using this code:
233
234**webpack.config.js**
235
236```js
237module.exports = {
238 module: {
239 rules: [
240 {
241 test: /\.s[ac]ss$/i,
242 use: [
243 'style-loader',
244 'css-loader',
245 {
246 loader: 'sass-loader',
247 options: {
248 implementation: require('sass'),
249 sassOptions: {
250 fiber: require('fibers'),
251 },
252 },
253 },
254 ],
255 },
256 ],
257 },
258};
259```
260
261### `sassOptions`
262
263Type: `Object|Function`
264Default: defaults values for Sass implementation
265
266Options for [Dart Sass](http://sass-lang.com/dart-sass) or [Node Sass](https://github.com/sass/node-sass) implementation.
267
268> ℹ️ The `indentedSyntax` option has `true` value for the `sass` extension.
269
270> ℹ️ Options such as `data` and `file` are unavailable and will be ignored.
271
272> ℹ We recommend not to set the `outFile`, `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because `sass-loader` automatically sets these options when the `sourceMap` option is `true`.
273
274> ℹ️ 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.
275
276There is a slight difference between the `sass` (`dart-sass`) and `node-sass` options.
277
278Please consult documentation before using them:
279
280- [Dart Sass documentation](https://github.com/sass/dart-sass#javascript-api) for all available `sass` options.
281- [Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options.
282
283#### `Object`
284
285Use and object for the Sass implementation setup.
286
287**webpack.config.js**
288
289```js
290module.exports = {
291 module: {
292 rules: [
293 {
294 test: /\.s[ac]ss$/i,
295 use: [
296 'style-loader',
297 'css-loader',
298 {
299 loader: 'sass-loader',
300 options: {
301 sassOptions: {
302 indentWidth: 4,
303 includePaths: ['absolute/path/a', 'absolute/path/b'],
304 },
305 },
306 },
307 ],
308 },
309 ],
310 },
311};
312```
313
314#### `Function`
315
316Allows to setup the Sass implementation by setting different options based on the loader context.
317
318```js
319module.exports = {
320 module: {
321 rules: [
322 {
323 test: /\.s[ac]ss$/i,
324 use: [
325 'style-loader',
326 'css-loader',
327 {
328 loader: 'sass-loader',
329 options: {
330 sassOptions: (loaderContext) => {
331 // More information about available properties https://webpack.js.org/api/loaders/
332 const { resourcePath, rootContext } = loaderContext;
333 const relativePath = path.relative(rootContext, resourcePath);
334
335 if (relativePath === 'styles/foo.scss') {
336 return {
337 includePaths: ['absolute/path/c', 'absolute/path/d'],
338 };
339 }
340
341 return {
342 includePaths: ['absolute/path/a', 'absolute/path/b'],
343 };
344 },
345 },
346 },
347 ],
348 },
349 ],
350 },
351};
352```
353
354### `sourceMap`
355
356Type: `Boolean`
357Default: depends on the `compiler.devtool` value
358
359Enables/Disables generation of source maps.
360
361By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option.
362All values enable source map generation except `eval` and `false` value.
363
364> ℹ If a `true` the `sourceMap`, `sourceMapRoot`, `sourceMapEmbed`, `sourceMapContents` and `omitSourceMapUrl` from `sassOptions` will be ignored.
365
366**webpack.config.js**
367
368```js
369module.exports = {
370 module: {
371 rules: [
372 {
373 test: /\.s[ac]ss$/i,
374 use: [
375 'style-loader',
376 {
377 loader: 'css-loader',
378 options: {
379 sourceMap: true,
380 },
381 },
382 {
383 loader: 'sass-loader',
384 options: {
385 sourceMap: true,
386 },
387 },
388 ],
389 },
390 ],
391 },
392};
393```
394
395> ℹ In some rare cases `node-sass` can output invalid source maps (it is a `node-sass` bug).
396
397> > 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`.
398
399**webpack.config.js**
400
401```js
402module.exports = {
403 module: {
404 rules: [
405 {
406 test: /\.s[ac]ss$/i,
407 use: [
408 'style-loader',
409 'css-loader',
410 {
411 loader: 'sass-loader',
412 options: {
413 sourceMap: true,
414 sassOptions: {
415 outputStyle: 'compressed',
416 },
417 },
418 },
419 ],
420 },
421 ],
422 },
423};
424```
425
426### `additionalData`
427
428Type: `String|Function`
429Default: `undefined`
430
431Prepends `Sass`/`SCSS` code before the actual entry file.
432In this case, the `sass-loader` will not override the `data` option but just **prepend** the entry's content.
433
434This is especially useful when some of your Sass variables depend on the environment:
435
436#### `String`
437
438```js
439module.exports = {
440 module: {
441 rules: [
442 {
443 test: /\.s[ac]ss$/i,
444 use: [
445 'style-loader',
446 'css-loader',
447 {
448 loader: 'sass-loader',
449 options: {
450 additionalData: '$env: ' + process.env.NODE_ENV + ';',
451 },
452 },
453 ],
454 },
455 ],
456 },
457};
458```
459
460#### `Function`
461
462```js
463module.exports = {
464 module: {
465 rules: [
466 {
467 test: /\.s[ac]ss$/i,
468 use: [
469 'style-loader',
470 'css-loader',
471 {
472 loader: 'sass-loader',
473 options: {
474 additionalData: (content, loaderContext) => {
475 // More information about available properties https://webpack.js.org/api/loaders/
476 const { resourcePath, rootContext } = loaderContext;
477 const relativePath = path.relative(rootContext, resourcePath);
478
479 if (relativePath === 'styles/foo.scss') {
480 return '$value: 100px;' + content;
481 }
482
483 return '$value: 200px;' + content;
484 },
485 },
486 },
487 ],
488 },
489 ],
490 },
491};
492```
493
494### `webpackImporter`
495
496Type: `Boolean`
497Default: `true`
498
499Enables/Disables the default Webpack importer.
500
501This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starting with `~` will not work.
502You can pass own `importer` to solve this (see [`importer docs`](https://github.com/sass/node-sass#importer--v200---experimental)).
503
504**webpack.config.js**
505
506```js
507module.exports = {
508 module: {
509 rules: [
510 {
511 test: /\.s[ac]ss$/i,
512 use: [
513 'style-loader',
514 'css-loader',
515 {
516 loader: 'sass-loader',
517 options: {
518 webpackImporter: false,
519 },
520 },
521 ],
522 },
523 ],
524 },
525};
526```
527
528## Examples
529
530### Extracts CSS into separate files
531
532For production builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
533
534There are two possibilities to extract a style sheet from the bundle:
535
536- [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) (use this, when using webpack 4 configuration. Works in all use-cases)
537- [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
538
539**webpack.config.js**
540
541```js
542const MiniCssExtractPlugin = require('mini-css-extract-plugin');
543
544module.exports = {
545 module: {
546 rules: [
547 {
548 test: /\.s[ac]ss$/i,
549 use: [
550 // fallback to style-loader in development
551 process.env.NODE_ENV !== 'production'
552 ? 'style-loader'
553 : MiniCssExtractPlugin.loader,
554 'css-loader',
555 'sass-loader',
556 ],
557 },
558 ],
559 },
560 plugins: [
561 new MiniCssExtractPlugin({
562 // Options similar to the same options in webpackOptions.output
563 // both options are optional
564 filename: '[name].css',
565 chunkFilename: '[id].css',
566 }),
567 ],
568};
569```
570
571### Source maps
572
573Enables/Disables generation of source maps.
574
575To enable CSS source maps, you'll need to pass the `sourceMap` option to the `sass-loader` _and_ the css-loader.
576
577**webpack.config.js**
578
579```javascript
580module.exports = {
581 devtool: 'source-map', // any "source-map"-like devtool is possible
582 module: {
583 rules: [
584 {
585 test: /\.s[ac]ss$/i,
586 use: [
587 'style-loader',
588 {
589 loader: 'css-loader',
590 options: {
591 sourceMap: true,
592 },
593 },
594 {
595 loader: 'sass-loader',
596 options: {
597 sourceMap: true,
598 },
599 },
600 ],
601 },
602 ],
603 },
604};
605```
606
607If 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.
608
609## Contributing
610
611Please take a moment to read our contributing guidelines if you haven't yet done so.
612
613[CONTRIBUTING](./.github/CONTRIBUTING.md)
614
615## License
616
617[MIT](./LICENSE)
618
619[npm]: https://img.shields.io/npm/v/sass-loader.svg
620[npm-url]: https://npmjs.com/package/sass-loader
621[node]: https://img.shields.io/node/v/sass-loader.svg
622[node-url]: https://nodejs.org
623[deps]: https://david-dm.org/webpack-contrib/sass-loader.svg
624[deps-url]: https://david-dm.org/webpack-contrib/sass-loader
625[tests]: https://github.com/webpack-contrib/sass-loader/workflows/sass-loader/badge.svg
626[tests-url]: https://github.com/webpack-contrib/sass-loader/actions
627[cover]: https://codecov.io/gh/webpack-contrib/sass-loader/branch/master/graph/badge.svg
628[cover-url]: https://codecov.io/gh/webpack-contrib/sass-loader
629[chat]: https://badges.gitter.im/webpack/webpack.svg
630[chat-url]: https://gitter.im/webpack/webpack
631[size]: https://packagephobia.now.sh/badge?p=sass-loader
632[size-url]: https://packagephobia.now.sh/result?p=sass-loader