All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
* support webpack@5 ([#794](https://github.com/webpack-contrib/sass-loader/issues/794)) ([6c59e37](https://github.com/webpack-contrib/sass-loader/commit/6c59e37e3f67668d7a3908444ddfc0176bc5601f))
* move all sass (`includePaths`, `importer`, `functions`, `outputStyle`) options to the `sassOptions` option. The `functions` option can't be used as `Function`, you should use `sassOption` as `Function` to achieve this.
* the `data` option was renamed to the `prependData` option
* default value of the `sourceMap` option depends on the `devtool` value (`eval`/`false` values don't enable source map generation)
### Features
* automatically use the `fibers` package if it is possible ([#744](https://github.com/webpack-contrib/sass-loader/issues/744)) ([96184e1](https://github.com/webpack-contrib/sass-loader/commit/96184e1))
* source map generation depends on the `devtool` option ([#743](https://github.com/webpack-contrib/sass-loader/issues/743)) ([fcea88e](https://github.com/webpack-contrib/sass-loader/commit/fcea88e))
* minimum `node` version in `package.json` ([#733](https://github.com/webpack-contrib/sass-loader/issues/733)) ([1175920](https://github.com/webpack-contrib/sass-loader/commit/1175920))
* use "compressed" output when mode is "production" ([#723](https://github.com/webpack-contrib/sass-loader/issues/723)) ([b2af379](https://github.com/webpack-contrib/sass-loader/commit/b2af379))
* allow passing `functions` option as function ([#651](https://github.com/webpack-contrib/sass-loader/issues/651)) ([6c9654d](https://github.com/webpack-contrib/sass-loader/commit/6c9654d))
* support `data` as `Function` ([#648](https://github.com/webpack-contrib/sass-loader/issues/648)) ([aa64e1b](https://github.com/webpack-contrib/sass-loader/commit/aa64e1b))
* support `sass` and `style` fields in `package.json` ([#647](https://github.com/webpack-contrib/sass-loader/issues/647)) ([a8709c9](https://github.com/webpack-contrib/sass-loader/commit/a8709c9))
* support auto resolving `dart-sass` ([ff90dd6](https://github.com/webpack-contrib/sass-loader/commit/ff90dd6))
* Make this package implementation-agnostic (#573) ([bed9fb5](https://github.com/webpack-contrib/sass-loader/commit/bed9fb5)), closes [#435](https://github.com/webpack-contrib/sass-loader/issues/435)
* Bare imports not working sometimes (#579) ([c348281](https://github.com/webpack-contrib/sass-loader/commit/c348281)), closes [#566](https://github.com/webpack-contrib/sass-loader/issues/566)
* Errors being swallowed when trying to load node-sass (#576) ([6dfb274](https://github.com/webpack-contrib/sass-loader/commit/6dfb274)), closes [#563](https://github.com/webpack-contrib/sass-loader/issues/563)
* Report error to user for problems loading node-sass (#562) ([2529c07](https://github.com/webpack-contrib/sass-loader/commit/2529c07))
* Refactor resolving and simplify webpack config aliases (#479) ([e0fde1a](https://github.com/webpack-contrib/sass-loader/commit/e0fde1a))
* Remove `node-sass` from `peerDependencies` (#533) ([6439cef](https://github.com/webpack-contrib/sass-loader/commit/6439cef))
### BREAKING CHANGES
* Drop official node 4 support
* This slightly changes the resolving algorithm. Should not break in normal usage, but might break in complex configurations.
* The sass-loader throws an error at runtime now and refuses to compile if the peer dependency is wrong. This could break applications where npm's peer dependency warning was just ignored.
* Remove official node-sass@3 and webpack@1 support. [5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5](https://github.com/webpack-contrib/sass-loader/commit/5a6bcb96d8bd7a7a11c33252ba739ffe09ca38c5)
* Fix custom importers receiving `'stdin'` as second argument instead of the actual `resourcePath`[#267](https://github.com/webpack-contrib/sass-loader/pull/267)
* Fix a problem where modules with a `.` in their names were not resolved [#167](https://github.com/webpack-contrib/sass-loader/issues/167)
### Features
* Add possibility to also define all options in your `webpack.config.js`[#152](https://github.com/webpack-contrib/sass-loader/pull/152)[#170](https://github.com/webpack-contrib/sass-loader/pull/170)
* Fix crash when Sass reported an error without `file`[#158](https://github.com/webpack-contrib/sass-loader/pull/158)
### BREAKING CHANGES
* Add `node-sass@^3.3.3` and `webpack@^1.12.2` as peer-dependency [#165](https://github.com/webpack-contrib/sass-loader/pull/165)[#166](https://github.com/webpack-contrib/sass-loader/pull/166) [#169](https://github.com/webpack-contrib/sass-loader/pull/169)
* The new algorithm is aligned to libsass' way of resolving files. This yields to different results if two files with the same path and filename but with different extensions are present. Though this change should be no problem for most users, we must flag it as breaking change. [#135](https://github.com/webpack-contrib/sass-loader/issues/135)[#138](https://github.com/webpack-contrib/sass-loader/issues/138)
* Moved `node-sass^3.0.0-alpha.0` to `peerDependencies`[#28](https://github.com/webpack-contrib/sass-loader/issues/28)
* Using webpack's module resolver as custom importer [#39](https://github.com/webpack-contrib/sass-loader/issues/31)
* Add synchronous compilation support for usage with [enhanced-require](https://github.com/webpack/enhanced-require)[#39](https://github.com/webpack-contrib/sass-loader/pull/39)
`sass-loader` requires you to install either [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](https://github.com/sass/dart-sass) on your own (more documentation can be found below).
This allows you to control the versions of all your dependencies, and to choose which Sass implementation to use.
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.
Then add the loader to your Webpack configuration. For example:
**app.js**
```js
import'./style.scss';
```
**style.scss**
```scss
$body-color:red;
body{
color:$body-color;
}
```
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
};
```
Finally run `webpack` via your preferred method.
### Resolving `import` at-rules
Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
The `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:
```scss
@import'~bootstrap';
```
It's important to only prepend it with `~`, because `~/` resolves to the home directory.
Webpack needs to distinguish between `bootstrap` and `~bootstrap` because CSS and Sass files have no special syntax for importing relative files.
Writing `@import "style.scss"` is the same as `@import "./style.scss";`
### Problems with `url(...)`
Since Sass implementations don't provide [url rewriting](https://github.com/sass/libsass/issues/532), all linked assets must be relative to the output.
- If you pass the generated CSS on to the `css-loader`, all urls must be relative to the entry-file (e.g. `main.scss`).
- If you're just generating CSS without passing it to the `css-loader`, it must be relative to your web root.
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).
Thankfully there are a two solutions to this problem:
- 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.
- 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`.
## Options
### `implementation`
The special `implementation` option determines which implementation of Sass to use.
By default the loader resolve the implementation based on your dependencies.
Just add required implementation to `package.json` (`node-sass` or `sass` package) and install dependencies.
Example where the `sass-loader` loader uses the `sass` (`dart-sass`) implementation:
**package.json**
```json
{
"devDependencies":{
"sass-loader":"^7.2.0",
"sass":"^1.22.10"
}
}
```
Example where the `sass-loader` loader uses the `node-sass` implementation:
**package.json**
```json
{
"devDependencies":{
"sass-loader":"^7.2.0",
"node-sass":"^4.0.0"
}
}
```
Beware the situation when `node-sass` and `sass` were installed! By default the `sass-loader` prefers `node-sass`. In order to avoid this situation you can use the `implementation` option.
The `implementation` options either accepts `node-sass` or `sass` (`Dart Sass`) as a module.
For example, to use Dart Sass, you'd pass:
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
// Prefer `dart-sass`
implementation:require('sass'),
},
},
],
},
],
},
};
```
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.
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.
We 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).
**package.json**
```json
{
"devDependencies":{
"sass-loader":"^7.2.0",
"sass":"^1.22.10",
"fibers":"^4.0.1"
}
}
```
You can disable automatically injecting the [`fibers`](https://github.com/laverdet/node-fibers) package by passing a `false` value for the `sassOptions.fiber` option.
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
implementation:require('sass'),
sassOptions:{
fiber:false,
},
},
},
],
},
],
},
};
```
You can also pass the `fiber` value using this code:
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
implementation:require('sass'),
sassOptions:{
fiber:require('fibers'),
},
},
},
],
},
],
},
};
```
### `sassOptions`
Type: `Object|Function`
Options for [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](http://sass-lang.com/dart-sass) implementation.
> ℹ️ The `indentedSyntax` option has `true` value for the `sass` extension.
> ℹ️ Options such as `file` and `outFile` are unavailable.
> ℹ We recommend not to use the `sourceMapContents`, `sourceMapEmbed`, `sourceMapRoot` options because `sass-loader` automatically sets these options.
There is a slight difference between the `node-sass` and `sass` (`Dart Sass`) options.
Please consult documentation before using them:
-[Node Sass documentation](https://github.com/sass/node-sass/#options) for all available `node-sass` options.
-[Dart Sass documentation](https://github.com/sass/dart-sass#javascript-api) for all available `sass` options.
Prepends `Sass`/`SCSS` code before the actual entry file.
In this case, the `sass-loader` will not override the `data` option but just append the entry's content.
This is especially useful when some of your Sass variables depend on the environment:
> ℹ Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this, like multiple Sass entry files.
#### `String`
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
prependData:'$env: '+process.env.NODE_ENV+';',
},
},
],
},
],
},
};
```
#### `Function`
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
prependData:(loaderContext)=>{
// More information about available properties https://webpack.js.org/api/loaders/
By default generation of source maps depends on the [`devtool`](https://webpack.js.org/configuration/devtool/) option. All values enable source map generation except `eval` and `false` value.
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
{
loader:'css-loader',
options:{
sourceMap:true,
},
},
{
loader:'sass-loader',
options:{
sourceMap:true,
},
},
],
},
],
},
};
```
> ℹ In some rare cases `node-sass` can output invalid source maps (it is a `node-sass` bug).
> 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`.
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
sourceMap:true,
sassOptions:{
outputStyle:'compressed',
},
},
],
},
],
},
};
```
### `webpackImporter`
Type: `Boolean`
Default: `true`
Enables/Disables the default Webpack importer.
This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starting with `~` will not work. You can pass own `importer` to solve this (see [`importer docs`](https://github.com/sass/node-sass#importer--v200---experimental)).
**webpack.config.js**
```js
module.exports={
module:{
rules:[
{
test:/\.s[ac]ss$/i,
use:[
'style-loader',
'css-loader',
{
loader:'sass-loader',
options:{
webpackImporter:false,
},
},
],
},
],
},
};
```
## Examples
### Extracts CSS into separate files
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.
There are two possibilities to extract a style sheet from the bundle:
-[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)
-[extract-loader](https://github.com/peerigon/extract-loader)(simpler, but specialized on the css-loader's output)
// Options similar to the same options in webpackOptions.output
// both options are optional
filename:'[name].css',
chunkFilename:'[id].css',
}),
],
};
```
### Source maps
Enables/Disables generation of source maps.
To enable CSS source maps, you'll need to pass the `sourceMap` option to the `sass-loader` _and_ the css-loader.
**webpack.config.js**
```javascript
module.exports={
devtool:'source-map',// any "source-map"-like devtool is possible
module:{
rules:[
{
test:/\.scss$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
sourceMap:true,
},
},
{
loader:'sass-loader',
options:{
sourceMap:true,
},
},
],
},
],
},
};
```
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.
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
this.message=`${this.name}: ${this.originalSassError.formatted.replace(/^Error: /,'').replace(/(\s*)stdin(\s*)/,`$1${resourcePath}$2`)}`;// Instruct webpack to hide the JS stack from the console.
// Usually you're only interested in the SASS stack in this case.
* When libsass tries to resolve an import, it uses a special algorithm.
* Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
* returns an array of import paths to try. The last entry in the array is always the original url
* to enable straight-forward webpack.config aliases.
*
* @param {string} url
* @returns {Array<string>}
*/
functionimportsToResolve(url){
constrequest=_loaderUtils.default.urlToRequest(url);// Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
constext=_path.default.extname(request).toLowerCase();// In case there is module request, send this to webpack resolver
if(matchModuleImport.test(url)){
return[request,url];
}// Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
// To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any @imports with the following characteristics to plain CSS imports:
// - imports where the URL ends with .css.
// - imports where the URL begins http:// or https://.
// - imports where the URL is written as a url().
// - imports that have media queries.
//
// The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
if(ext==='.css'){
return[];
}
constdirname=_path.default.dirname(request);
constbasename=_path.default.basename(request);// In case there is file extension:
//
// 1. Try to resolve `_` file.
// 2. Try to resolve file without `_`.
// 3. Send a original url to webpack resolver, maybe it is alias.
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
addNormalizedDependency(resolvedFile);
return{
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
file:resolvedFile.replace(matchCss,'')
};
},()=>{
const[,...tailResult]=importsToResolve;
returnstartResolving(dir,tailResult);
});
}
return(url,prev,done)=>{
startResolving(dirContextFrom(prev),(0,_importsToResolve.default)(url))// Catch all resolving errors, return the original file and pass responsibility back to other custom importers
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
* smart not case ([#101](https://github.com/webpack/schema-utils/issues/101)) ([698d8b0](https://github.com/webpack/schema-utils/commit/698d8b05462d86aadb217e25a45c7b953a79a52e))
### Bug Fixes
* move @types/json-schema from devDependencies to dependencies ([#97](https://github.com/webpack/schema-utils/issues/97)) ([#98](https://github.com/webpack/schema-utils/issues/98)) ([945e67d](https://github.com/webpack/schema-utils/commit/945e67db5e19baf7ec7df72813b0739dd56f950d))
* prefer the `baseDataPath` option from arguments ([#86](https://github.com/webpack/schema-utils/issues/86)) ([e236859](https://github.com/webpack/schema-utils/commit/e236859e85b28e35e1294f86fc1ff596a5031cea))
* support configuration via title ([#81](https://github.com/webpack/schema-utils/issues/81)) ([afddc10](https://github.com/webpack/schema-utils/commit/afddc109f6891cd37a9f1835d50862d119a072bf))
* rework format for maxLength, minLength ([#67](https://github.com/webpack/schema-utils/issues/67)) ([0d12259](https://github.com/webpack/schema-utils/commit/0d12259))
* support all cases with one number in range ([#64](https://github.com/webpack/schema-utils/issues/64)) ([7fc8069](https://github.com/webpack/schema-utils/commit/7fc8069))
* typescript definition and export naming ([#69](https://github.com/webpack/schema-utils/issues/69)) ([a435b79](https://github.com/webpack/schema-utils/commit/a435b79))
### Features
* "smart" numbers range ([62fb107](https://github.com/webpack/schema-utils/commit/62fb107))
***src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
***validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
***ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
***validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
***ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
constmessage=shouldBeAbsolute?`The provided value ${JSON.stringify(data)} is not an absolute path!`:`A relative path is expected. However, the provided value ${JSON.stringify(data)} is an absolute path!`;
returnerrorMessage(message,schema,data);
}
/**
*
* @param {Ajv} ajv
* @returns {Ajv}
*/
functionaddAbsolutePathKeyword(ajv){
ajv.addKeyword('absolutePath',{
errors:true,
type:'string',
compile(schema,parentSchema){
/** @type {ValidateFunction} */
constcallback=data=>{
letpasses=true;
constisExclamationMarkPresent=data.includes('!');
if(isExclamationMarkPresent){
callback.errors=[errorMessage(`The provided value ${JSON.stringify(data)} contains exclamation mark (!) which is not allowed because it's reserved for loader syntax.`,parentSchema,data)];