Skip to content

Commit

Permalink
feat: added the warnRuleAsWarning option, allow to emit a warning o…
Browse files Browse the repository at this point in the history
…n the `@warn` rule (#992)
  • Loading branch information
alexander-akait committed Oct 27, 2021
1 parent bb7cef9 commit c652c79
Show file tree
Hide file tree
Showing 9 changed files with 457 additions and 16 deletions.
74 changes: 67 additions & 7 deletions README.md
Expand Up @@ -119,13 +119,14 @@ Thankfully there are a two solutions to this problem:

## Options

| Name | Type | Default | Description |
| :---------------------------------------: | :------------------: | :-------------------------------------: | :---------------------------------------------------------------- |
| **[`implementation`](#implementation)** | `{Object\|String}` | `sass` | Setup Sass implementation to use. |
| **[`sassOptions`](#sassoptions)** | `{Object\|Function}` | defaults values for Sass implementation | Options for Sass. |
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
| **[`additionalData`](#additionaldata)** | `{String\|Function}` | `undefined` | Prepends/Appends `Sass`/`SCSS` code before the actual entry file. |
| **[`webpackImporter`](#webpackimporter)** | `{Boolean}` | `true` | Enables/Disables the default Webpack importer. |
| Name | Type | Default | Description |
| :-------------------------------------------: | :------------------: | :-------------------------------------: | :---------------------------------------------------------------- |
| **[`implementation`](#implementation)** | `{Object\|String}` | `sass` | Setup Sass implementation to use. |
| **[`sassOptions`](#sassoptions)** | `{Object\|Function}` | defaults values for Sass implementation | Options for Sass. |
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
| **[`additionalData`](#additionaldata)** | `{String\|Function}` | `undefined` | Prepends/Appends `Sass`/`SCSS` code before the actual entry file. |
| **[`webpackImporter`](#webpackimporter)** | `{Boolean}` | `true` | Enables/Disables the default Webpack importer. |
| **[`warnRuleAsWarning`](#warnruleaswarning)** | `{Boolean}` | `false` | Treats the `@warn` rule as a webpack warning. |

### `implementation`

Expand Down Expand Up @@ -604,6 +605,65 @@ module.exports = {
};
```

### `warnRuleAsWarning`

Type: `Boolean`
Default: `false`

Treats the `@warn` rule as a webpack warning.

> ℹ️ It will be `true` by default in the next major release.
**style.scss**

```scss
$known-prefixes: webkit, moz, ms, o;

@mixin prefix($property, $value, $prefixes) {
@each $prefix in $prefixes {
@if not index($known-prefixes, $prefix) {
@warn "Unknown prefix #{$prefix}.";
}

-#{$prefix}-#{$property}: $value;
}
#{$property}: $value;
}

.tilt {
// Oops, we typo'd "webkit" as "wekbit"!
@include prefix(transform, rotate(15deg), wekbit ms);
}
```

The presented code will throw webpack warning instead logging.

To ignore unnecessary warnings you can use the [ignoreWarnings](https://webpack.js.org/configuration/other-options/#ignorewarnings) option.

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
warnRuleAsWarning: true,
},
},
],
},
],
},
};
```

## Examples

### Extracts CSS into separate files
Expand Down
1 change: 1 addition & 0 deletions src/SassError.js
Expand Up @@ -3,6 +3,7 @@ class SassError extends Error {
super();

this.name = "SassError";
// TODO remove me in the next major release
this.originalSassError = sassError;
this.loc = {
line: sassError.line,
Expand Down
17 changes: 17 additions & 0 deletions src/SassWarning.js
@@ -0,0 +1,17 @@
class SassWarning extends Error {
constructor(warning, options) {
super(warning);

this.name = "SassWarning";
this.hideStack = true;

if (options.span) {
this.loc = {
line: options.span.start.line,
column: options.span.start.column,
};
}
}
}

export default SassWarning;
5 changes: 5 additions & 0 deletions src/options.json
Expand Up @@ -48,6 +48,11 @@
"description": "Enables/Disables default `webpack` importer.",
"link": "https://github.com/webpack-contrib/sass-loader#webpackimporter",
"type": "boolean"
},
"warnRuleAsWarning": {
"description": "Treats the '@warn' rule as a webpack warning.",
"link": "https://github.com/webpack-contrib/sass-loader#warnruleaswarning",
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
13 changes: 12 additions & 1 deletion src/utils.js
Expand Up @@ -4,6 +4,8 @@ import path from "path";
import { klona } from "klona/full";
import async from "neo-async";

import SassWarning from "./SassWarning";

function getDefaultSassImplementation() {
let sassImplPkg = "sass";

Expand Down Expand Up @@ -229,6 +231,9 @@ async function getSassOptions(
}

if (!options.logger) {
// TODO set me to `true` by default in the next major release
const needEmitWarning = loaderOptions.warnRuleAsWarning === true;

const logger = loaderContext.getLogger("sass-loader");
const formatSpan = (span) =>
`${span.url || "-"}:${span.start.line}:${span.start.column}: `;
Expand Down Expand Up @@ -262,7 +267,13 @@ async function getSassOptions(
builtMessage += `\n\n${loggerOptions.stack}`;
}

logger.warn(builtMessage);
if (needEmitWarning) {
loaderContext.emitWarning(
new SassWarning(builtMessage, loggerOptions)
);
} else {
logger.warn(builtMessage);
}
},
};
}
Expand Down
23 changes: 15 additions & 8 deletions test/__snapshots__/validate-options.test.js.snap
Expand Up @@ -69,49 +69,56 @@ exports[`validate options should throw an error on the "sourceMap" option with "
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter? }"
object { implementation?, sassOptions?, additionalData?, sourceMap?, webpackImporter?, warnRuleAsWarning? }"
`;
exports[`validate options should throw an error on the "warnRuleAsWarning" option with "string" value 1`] = `
"Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options.warnRuleAsWarning should be a boolean.
-> Treats the '@warn' rule as a webpack warning.
-> Read more at https://github.com/webpack-contrib/sass-loader#warnruleaswarning"
`;
exports[`validate options should throw an error on the "webpackImporter" option with "string" value 1`] = `
Expand Down

0 comments on commit c652c79

Please sign in to comment.