sass-loader 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +62 -5
- package/lib/formatSassError.js +47 -41
- package/lib/importsToResolve.js +46 -44
- package/lib/loader.js +172 -90
- package/lib/normalizeOptions.js +71 -52
- package/lib/proxyCustomImporters.js +16 -12
- package/lib/webpackImporter.js +41 -35
- package/package.json +46 -21
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
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.
|
|
4
4
|
|
|
5
|
+
<a name="7.2.0"></a>
|
|
6
|
+
# [7.2.0](https://github.com/webpack-contrib/sass-loader/compare/v7.1.0...v7.2.0) (2019-08-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* better handle stdin in sources ([#681](https://github.com/webpack-contrib/sass-loader/issues/681)) ([e279f2a](https://github.com/webpack-contrib/sass-loader/commit/e279f2a))
|
|
12
|
+
* prefer `sass`/`scss`/`css` extensions ([#711](https://github.com/webpack-contrib/sass-loader/issues/711)) ([6fc9d4e](https://github.com/webpack-contrib/sass-loader/commit/6fc9d4e))
|
|
13
|
+
* relax node engine ([#708](https://github.com/webpack-contrib/sass-loader/issues/708)) ([2a51502](https://github.com/webpack-contrib/sass-loader/commit/2a51502))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* 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))
|
|
19
|
+
* support `data` as `Function` ([#648](https://github.com/webpack-contrib/sass-loader/issues/648)) ([aa64e1b](https://github.com/webpack-contrib/sass-loader/commit/aa64e1b))
|
|
20
|
+
* 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))
|
|
21
|
+
* support auto resolving `dart-sass` ([ff90dd6](https://github.com/webpack-contrib/sass-loader/commit/ff90dd6))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
5
25
|
<a name="7.1.0"></a>
|
|
6
26
|
# [7.1.0](https://github.com/webpack-contrib/sass-loader/compare/v7.0.3...v7.1.0) (2018-08-01)
|
|
7
27
|
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<p>Loads a Sass/SCSS file and compiles it to CSS.</p>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
Use the [css-loader](https://github.com/webpack-contrib/css-loader) or the [raw-loader](https://github.com/webpack-contrib/raw-loader) to turn it into a JS module and the [
|
|
21
|
+
Use the [css-loader](https://github.com/webpack-contrib/css-loader) or the [raw-loader](https://github.com/webpack-contrib/raw-loader) to turn it into a JS module and the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract it into a separate file.
|
|
22
22
|
Looking for the webpack 1 loader? Check out the [archive/webpack-1 branch](https://github.com/webpack-contrib/sass-loader/tree/archive/webpack-1).
|
|
23
23
|
|
|
24
24
|
<h2 align="center">Install</h2>
|
|
@@ -29,7 +29,7 @@ npm install sass-loader node-sass webpack --save-dev
|
|
|
29
29
|
|
|
30
30
|
The sass-loader requires [webpack](https://github.com/webpack) as a
|
|
31
31
|
[`peerDependency`](https://docs.npmjs.com/files/package.json#peerdependencies)
|
|
32
|
-
and it requires you to install either [Node Sass]
|
|
32
|
+
and it requires you to install either [Node Sass](https://github.com/sass/node-sass) or [Dart Sass](https://github.com/sass/dart-sass) on your
|
|
33
33
|
own. This allows you to control the versions of all your dependencies, and to
|
|
34
34
|
choose which Sass implementation to use.
|
|
35
35
|
|
|
@@ -87,6 +87,40 @@ module.exports = {
|
|
|
87
87
|
|
|
88
88
|
See [the Node Sass documentation](https://github.com/sass/node-sass/blob/master/README.md#options) for all available Sass options.
|
|
89
89
|
|
|
90
|
+
By default the loader resolve the implementation based on your dependencies.
|
|
91
|
+
Just add required implementation to `package.json`
|
|
92
|
+
(`node-sass` or `sass` package) and install dependencies.
|
|
93
|
+
|
|
94
|
+
Example where the `sass-loader` loader uses the `sass` (`dart-sass`) implementation:
|
|
95
|
+
|
|
96
|
+
**package.json**
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"sass-loader": "*",
|
|
102
|
+
"sass": "*"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Example where the `sass-loader` loader uses the `node-sass` implementation:
|
|
108
|
+
|
|
109
|
+
**package.json**
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"devDependencies": {
|
|
114
|
+
"sass-loader": "*",
|
|
115
|
+
"node-sass": "*"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Beware the situation
|
|
121
|
+
when `node-sass` and `sass` was installed, by default the `sass-loader`
|
|
122
|
+
prefers `node-sass`, to avoid this situation use the `implementation` option.
|
|
123
|
+
|
|
90
124
|
The special `implementation` option determines which implementation of Sass to
|
|
91
125
|
use. It takes either a [Node Sass][] or a [Dart Sass][] module. For example, to
|
|
92
126
|
use Dart Sass, you'd pass:
|
|
@@ -136,7 +170,7 @@ module.exports = {
|
|
|
136
170
|
|
|
137
171
|
### In production
|
|
138
172
|
|
|
139
|
-
Usually, it's recommended to extract the style sheets into a dedicated file in production using the [
|
|
173
|
+
Usually, it's recommended to extract the style sheets into a dedicated file in production using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin). This way your styles are not dependent on JavaScript:
|
|
140
174
|
|
|
141
175
|
```js
|
|
142
176
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
@@ -196,7 +230,7 @@ Bundling CSS with webpack has some nice advantages like referencing images and f
|
|
|
196
230
|
There are two possibilities to extract a style sheet from the bundle:
|
|
197
231
|
|
|
198
232
|
- [extract-loader](https://github.com/peerigon/extract-loader) (simpler, but specialized on the css-loader's output)
|
|
199
|
-
- [
|
|
233
|
+
- [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)
|
|
200
234
|
|
|
201
235
|
### Source maps
|
|
202
236
|
|
|
@@ -210,7 +244,9 @@ module.exports = {
|
|
|
210
244
|
rules: [{
|
|
211
245
|
test: /\.scss$/,
|
|
212
246
|
use: [{
|
|
213
|
-
loader: "style-loader"
|
|
247
|
+
loader: "style-loader", options: {
|
|
248
|
+
sourceMap: true
|
|
249
|
+
}
|
|
214
250
|
}, {
|
|
215
251
|
loader: "css-loader", options: {
|
|
216
252
|
sourceMap: true
|
|
@@ -240,6 +276,27 @@ If you want to prepend Sass code before the actual entry file, you can set the `
|
|
|
240
276
|
}
|
|
241
277
|
```
|
|
242
278
|
|
|
279
|
+
The `data` option supports `Function` notation:
|
|
280
|
+
|
|
281
|
+
```javascript
|
|
282
|
+
{
|
|
283
|
+
loader: "sass-loader",
|
|
284
|
+
options: {
|
|
285
|
+
data: (loaderContext) => {
|
|
286
|
+
// More information about avalaible options https://webpack.js.org/api/loaders/
|
|
287
|
+
const { resourcePath, rootContext } = loaderContext;
|
|
288
|
+
const relativePath = path.relative(rootContext,resourcePath);
|
|
289
|
+
|
|
290
|
+
if (relativePath === "styles/foo.scss") {
|
|
291
|
+
return "$value: 100px;"
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return "$value: 200px;"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
243
300
|
**Please note:** 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.
|
|
244
301
|
|
|
245
302
|
<h2 align="center">Maintainers</h2>
|
package/lib/formatSassError.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
const path = require(
|
|
4
|
-
const os = require(
|
|
5
|
-
const fs = require(
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const fs = require('fs');
|
|
6
6
|
|
|
7
7
|
// A typical sass error looks like this
|
|
8
|
-
const SassError = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
8
|
+
// const SassError = {
|
|
9
|
+
// message: "invalid property name",
|
|
10
|
+
// column: 14,
|
|
11
|
+
// line: 1,
|
|
12
|
+
// file: "stdin",
|
|
13
|
+
// status: 1
|
|
14
|
+
// };
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Enhances the sass error with additional information about what actually went wrong.
|
|
@@ -20,31 +20,37 @@ const SassError = { // eslint-disable-line no-unused-vars
|
|
|
20
20
|
* @param {string} resourcePath
|
|
21
21
|
*/
|
|
22
22
|
function formatSassError(err, resourcePath) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
// Instruct webpack to hide the JS stack from the console
|
|
24
|
+
// Usually you're only interested in the SASS stack in this case.
|
|
25
|
+
// eslint-disable-next-line no-param-reassign
|
|
26
|
+
err.hideStack = true;
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
// The file property is missing in rare cases.
|
|
29
|
+
// No improvement in the error is possible.
|
|
30
|
+
if (!err.file) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
let msg = err.message;
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
err.file = path.normalize(err.file);
|
|
36
|
+
if (err.file === 'stdin') {
|
|
37
|
+
// eslint-disable-next-line no-param-reassign
|
|
38
|
+
err.file = resourcePath;
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// node-sass returns UNIX-style paths
|
|
42
|
+
// eslint-disable-next-line no-param-reassign
|
|
43
|
+
err.file = path.normalize(err.file);
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// The 'Current dir' hint of node-sass does not help us, we're providing
|
|
46
|
+
// additional information by reading the err.file property
|
|
47
|
+
msg = msg.replace(/\s*Current dir:\s*/, '');
|
|
48
|
+
|
|
49
|
+
// eslint-disable-next-line no-param-reassign
|
|
50
|
+
err.message = `${getFileExcerptIfPossible(err) +
|
|
51
|
+
msg.charAt(0).toUpperCase() +
|
|
52
|
+
msg.slice(1) +
|
|
53
|
+
os.EOL} in ${err.file} (line ${err.line}, column ${err.column})`;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
/**
|
|
@@ -57,17 +63,17 @@ function formatSassError(err, resourcePath) {
|
|
|
57
63
|
* @returns {string}
|
|
58
64
|
*/
|
|
59
65
|
function getFileExcerptIfPossible(err) {
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
try {
|
|
67
|
+
const content = fs.readFileSync(err.file, 'utf8');
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
return `${os.EOL +
|
|
70
|
+
content.split(os.EOL)[err.line - 1] +
|
|
71
|
+
os.EOL +
|
|
72
|
+
new Array(err.column - 1).join(' ')}^${os.EOL} `;
|
|
73
|
+
} catch (ignoreErr) {
|
|
74
|
+
// If anything goes wrong here, we don't want any errors to be reported to the user
|
|
75
|
+
return '';
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
module.exports = formatSassError;
|
package/lib/importsToResolve.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
const path = require(
|
|
4
|
-
const utils = require("loader-utils");
|
|
3
|
+
const path = require('path');
|
|
5
4
|
|
|
6
|
-
const
|
|
5
|
+
const utils = require('loader-utils');
|
|
6
|
+
|
|
7
|
+
const matchModuleImport = /^~([^/]+|@[^/]+[/][^/]+)$/;
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* When libsass tries to resolve an import, it uses a special algorithm.
|
|
@@ -15,46 +16,47 @@ const matchModuleImport = /^~([^\/]+|@[^\/]+[\/][^\/]+)$/;
|
|
|
15
16
|
* @returns {Array<string>}
|
|
16
17
|
*/
|
|
17
18
|
function importsToResolve(url) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
19
|
+
const request = utils.urlToRequest(url);
|
|
20
|
+
// Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
|
|
21
|
+
// @see https://github.com/webpack-contrib/sass-loader/issues/167
|
|
22
|
+
const ext = path.extname(request);
|
|
23
|
+
|
|
24
|
+
if (matchModuleImport.test(url)) {
|
|
25
|
+
return [request, url];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// libsass' import algorithm works like this:
|
|
29
|
+
|
|
30
|
+
// In case there is a file extension...
|
|
31
|
+
// - If the file is a CSS-file, do not include it all, but just link it via @import url().
|
|
32
|
+
// - The exact file name must match (no auto-resolving of '_'-modules).
|
|
33
|
+
if (ext === '.css') {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
if (ext === '.scss' || ext === '.sass') {
|
|
37
|
+
return [request, url];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// In case there is no file extension...
|
|
41
|
+
// - Prefer modules starting with '_'.
|
|
42
|
+
// - File extension precedence: .scss, .sass, .css.
|
|
43
|
+
const basename = path.basename(request);
|
|
44
|
+
|
|
45
|
+
if (basename.charAt(0) === '_') {
|
|
46
|
+
return [`${request}.scss`, `${request}.sass`, `${request}.css`, url];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const dirname = path.dirname(request);
|
|
50
|
+
|
|
51
|
+
return [
|
|
52
|
+
`${dirname}/_${basename}.scss`,
|
|
53
|
+
`${dirname}/_${basename}.sass`,
|
|
54
|
+
`${dirname}/_${basename}.css`,
|
|
55
|
+
`${request}.scss`,
|
|
56
|
+
`${request}.sass`,
|
|
57
|
+
`${request}.css`,
|
|
58
|
+
url,
|
|
59
|
+
];
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
module.exports = importsToResolve;
|
package/lib/loader.js
CHANGED
|
@@ -1,80 +1,135 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
const path = require(
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const async = require('neo-async');
|
|
6
|
+
const pify = require('pify');
|
|
7
|
+
const semver = require('semver');
|
|
8
|
+
|
|
9
|
+
const formatSassError = require('./formatSassError');
|
|
10
|
+
const webpackImporter = require('./webpackImporter');
|
|
11
|
+
const normalizeOptions = require('./normalizeOptions');
|
|
10
12
|
|
|
11
13
|
let nodeSassJobQueue = null;
|
|
12
14
|
|
|
15
|
+
// Very hacky check
|
|
16
|
+
function hasGetResolve(loaderContext) {
|
|
17
|
+
return (
|
|
18
|
+
loaderContext.getResolve &&
|
|
19
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
20
|
+
loaderContext._compiler &&
|
|
21
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
22
|
+
loaderContext._compiler.resolverFactory &&
|
|
23
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
24
|
+
loaderContext._compiler.resolverFactory._create &&
|
|
25
|
+
/cachedCleverMerge/.test(
|
|
26
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
27
|
+
loaderContext._compiler.resolverFactory._create.toString()
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
13
32
|
/**
|
|
14
|
-
* The sass-loader makes node-sass available to webpack modules.
|
|
33
|
+
* The sass-loader makes node-sass and dart-sass available to webpack modules.
|
|
15
34
|
*
|
|
16
35
|
* @this {LoaderContext}
|
|
17
36
|
* @param {string} content
|
|
18
37
|
*/
|
|
19
38
|
function sassLoader(content) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
39
|
+
const callback = this.async();
|
|
40
|
+
const isSync = typeof callback !== 'function';
|
|
41
|
+
const self = this;
|
|
42
|
+
const { resourcePath } = this;
|
|
43
|
+
|
|
44
|
+
function addNormalizedDependency(file) {
|
|
45
|
+
// node-sass returns POSIX paths
|
|
46
|
+
self.dependency(path.normalize(file));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (isSync) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
'Synchronous compilation is not supported anymore. See https://github.com/webpack-contrib/sass-loader/issues/333'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let resolve = pify(this.resolve);
|
|
56
|
+
|
|
57
|
+
// Supported since v4.36.0
|
|
58
|
+
if (hasGetResolve(self)) {
|
|
59
|
+
resolve = this.getResolve({
|
|
60
|
+
mainFields: ['sass', 'style', '...'],
|
|
61
|
+
extensions: ['.scss', '.sass', '.css', '...'],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const options = normalizeOptions(
|
|
66
|
+
this,
|
|
67
|
+
content,
|
|
68
|
+
webpackImporter(resourcePath, resolve, addNormalizedDependency)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Skip empty files, otherwise it will stop webpack, see issue #21
|
|
72
|
+
if (options.data.trim() === '') {
|
|
73
|
+
callback(null, '');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const render = getRenderFuncFromSassImpl(
|
|
78
|
+
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
|
|
79
|
+
options.implementation || getDefaultSassImpl()
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
render(options, (err, result) => {
|
|
83
|
+
if (err) {
|
|
84
|
+
formatSassError(err, this.resourcePath);
|
|
85
|
+
|
|
86
|
+
if (err.file) {
|
|
87
|
+
this.dependency(err.file);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
callback(err);
|
|
91
|
+
return;
|
|
28
92
|
}
|
|
29
93
|
|
|
30
|
-
if (
|
|
31
|
-
|
|
94
|
+
if (result.map && result.map !== '{}') {
|
|
95
|
+
// eslint-disable-next-line no-param-reassign
|
|
96
|
+
result.map = JSON.parse(result.map);
|
|
97
|
+
// result.map.file is an optional property that provides the output filename.
|
|
98
|
+
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
|
|
99
|
+
// eslint-disable-next-line no-param-reassign
|
|
100
|
+
delete result.map.file;
|
|
101
|
+
// One of the sources is 'stdin' according to dart-sass/node-sass because we've used the data input.
|
|
102
|
+
// Now let's override that value with the correct relative path.
|
|
103
|
+
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in normalizeOptions,
|
|
104
|
+
// we know that this path is relative to process.cwd(). This is how node-sass works.
|
|
105
|
+
// eslint-disable-next-line no-param-reassign
|
|
106
|
+
const stdinIndex = result.map.sources.findIndex(
|
|
107
|
+
(source) => source.indexOf('stdin') !== -1
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
if (stdinIndex !== -1) {
|
|
111
|
+
// eslint-disable-next-line no-param-reassign
|
|
112
|
+
result.map.sources[stdinIndex] = path.relative(
|
|
113
|
+
process.cwd(),
|
|
114
|
+
resourcePath
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
|
|
118
|
+
// This fixes an error on windows where the source-map module cannot resolve the source maps.
|
|
119
|
+
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
|
|
120
|
+
// eslint-disable-next-line no-param-reassign
|
|
121
|
+
result.map.sourceRoot = path.normalize(result.map.sourceRoot);
|
|
122
|
+
// eslint-disable-next-line no-param-reassign
|
|
123
|
+
result.map.sources = result.map.sources.map(path.normalize);
|
|
124
|
+
} else {
|
|
125
|
+
// eslint-disable-next-line no-param-reassign
|
|
126
|
+
result.map = null;
|
|
32
127
|
}
|
|
33
128
|
|
|
34
|
-
|
|
35
|
-
resourcePath,
|
|
36
|
-
pify(this.resolve.bind(this)),
|
|
37
|
-
addNormalizedDependency
|
|
38
|
-
));
|
|
129
|
+
result.stats.includedFiles.forEach(addNormalizedDependency);
|
|
39
130
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
callback(null, "");
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const render = getRenderFuncFromSassImpl(options.implementation || require("node-sass"));
|
|
47
|
-
|
|
48
|
-
render(options, (err, result) => {
|
|
49
|
-
if (err) {
|
|
50
|
-
formatSassError(err, this.resourcePath);
|
|
51
|
-
err.file && this.dependency(err.file);
|
|
52
|
-
callback(err);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (result.map && result.map !== "{}") {
|
|
57
|
-
result.map = JSON.parse(result.map);
|
|
58
|
-
// result.map.file is an optional property that provides the output filename.
|
|
59
|
-
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
|
|
60
|
-
delete result.map.file;
|
|
61
|
-
// The first source is 'stdin' according to node-sass because we've used the data input.
|
|
62
|
-
// Now let's override that value with the correct relative path.
|
|
63
|
-
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in normalizeOptions,
|
|
64
|
-
// we know that this path is relative to process.cwd(). This is how node-sass works.
|
|
65
|
-
result.map.sources[0] = path.relative(process.cwd(), resourcePath);
|
|
66
|
-
// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
|
|
67
|
-
// This fixes an error on windows where the source-map module cannot resolve the source maps.
|
|
68
|
-
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
|
|
69
|
-
result.map.sourceRoot = path.normalize(result.map.sourceRoot);
|
|
70
|
-
result.map.sources = result.map.sources.map(path.normalize);
|
|
71
|
-
} else {
|
|
72
|
-
result.map = null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
result.stats.includedFiles.forEach(addNormalizedDependency);
|
|
76
|
-
callback(null, result.css.toString(), result.map);
|
|
77
|
-
});
|
|
131
|
+
callback(null, result.css.toString(), result.map);
|
|
132
|
+
});
|
|
78
133
|
}
|
|
79
134
|
|
|
80
135
|
/**
|
|
@@ -84,41 +139,68 @@ function sassLoader(content) {
|
|
|
84
139
|
* @returns {Function}
|
|
85
140
|
*/
|
|
86
141
|
function getRenderFuncFromSassImpl(module) {
|
|
87
|
-
|
|
88
|
-
|
|
142
|
+
const { info } = module;
|
|
143
|
+
const components = info.split('\t');
|
|
144
|
+
|
|
145
|
+
if (components.length < 2) {
|
|
146
|
+
throw new Error(`Unknown Sass implementation "${info}".`);
|
|
147
|
+
}
|
|
89
148
|
|
|
90
|
-
|
|
91
|
-
|
|
149
|
+
const [implementation, version] = components;
|
|
150
|
+
|
|
151
|
+
if (!semver.valid(version)) {
|
|
152
|
+
throw new Error(`Invalid Sass version "${version}".`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (implementation === 'dart-sass') {
|
|
156
|
+
if (!semver.satisfies(version, '^1.3.0')) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Dart Sass version ${version} is incompatible with ^1.3.0.`
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return module.render.bind(module);
|
|
163
|
+
} else if (implementation === 'node-sass') {
|
|
164
|
+
if (!semver.satisfies(version, '^4.0.0')) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Node Sass version ${version} is incompatible with ^4.0.0.`
|
|
167
|
+
);
|
|
92
168
|
}
|
|
93
169
|
|
|
94
|
-
|
|
95
|
-
|
|
170
|
+
// There is an issue with node-sass when async custom importers are used
|
|
171
|
+
// See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
|
|
172
|
+
// We need to use a job queue to make sure that one thread is always available to the UV lib
|
|
173
|
+
if (nodeSassJobQueue === null) {
|
|
174
|
+
const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
|
|
96
175
|
|
|
97
|
-
|
|
98
|
-
|
|
176
|
+
nodeSassJobQueue = async.queue(
|
|
177
|
+
module.render.bind(module),
|
|
178
|
+
threadPoolSize - 1
|
|
179
|
+
);
|
|
99
180
|
}
|
|
100
181
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return nodeSassJobQueue.push.bind(nodeSassJobQueue);
|
|
182
|
+
return nodeSassJobQueue.push.bind(nodeSassJobQueue);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
throw new Error(`Unknown Sass implementation "${implementation}".`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function getDefaultSassImpl() {
|
|
189
|
+
let sassImplPkg = 'node-sass';
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
require.resolve('node-sass');
|
|
193
|
+
} catch (error) {
|
|
194
|
+
try {
|
|
195
|
+
require.resolve('sass');
|
|
196
|
+
sassImplPkg = 'sass';
|
|
197
|
+
} catch (ignoreError) {
|
|
198
|
+
sassImplPkg = 'node-sass';
|
|
120
199
|
}
|
|
121
|
-
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// eslint-disable-next-line import/no-dynamic-require, global-require
|
|
203
|
+
return require(sassImplPkg);
|
|
122
204
|
}
|
|
123
205
|
|
|
124
206
|
module.exports = sassLoader;
|
package/lib/normalizeOptions.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
const os = require(
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const utils = require('loader-utils');
|
|
7
|
+
const cloneDeep = require('clone-deep');
|
|
8
|
+
|
|
9
|
+
const proxyCustomImporters = require('./proxyCustomImporters');
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Derives the sass options from the loader context and normalizes its values with sane defaults.
|
|
@@ -18,61 +20,78 @@ const proxyCustomImporters = require("./proxyCustomImporters");
|
|
|
18
20
|
* @returns {Object}
|
|
19
21
|
*/
|
|
20
22
|
function normalizeOptions(loaderContext, content, webpackImporter) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
const options = cloneDeep(utils.getOptions(loaderContext)) || {};
|
|
24
|
+
const { resourcePath } = loaderContext;
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
// allow opt.functions to be configured WRT loaderContext
|
|
27
|
+
if (typeof options.functions === 'function') {
|
|
28
|
+
options.functions = options.functions(loaderContext);
|
|
29
|
+
}
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
if (!options.outputStyle && loaderContext.minimize) {
|
|
28
|
-
options.outputStyle = "compressed";
|
|
29
|
-
}
|
|
31
|
+
let { data } = options;
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
|
|
37
|
-
// In case it is a string, options.sourceMap should be a path where the source map is written.
|
|
38
|
-
// But since we're using the data option, the source map will not actually be written, but
|
|
39
|
-
// all paths in sourceMap.sources will be relative to that path.
|
|
40
|
-
// Pretty complicated... :(
|
|
41
|
-
options.sourceMap = path.join(process.cwd(), "/sass.map");
|
|
42
|
-
if ("sourceMapRoot" in options === false) {
|
|
43
|
-
options.sourceMapRoot = process.cwd();
|
|
44
|
-
}
|
|
45
|
-
if ("omitSourceMapUrl" in options === false) {
|
|
46
|
-
// The source map url doesn't make sense because we don't know the output path
|
|
47
|
-
// The css-loader will handle that for us
|
|
48
|
-
options.omitSourceMapUrl = true;
|
|
49
|
-
}
|
|
50
|
-
if ("sourceMapContents" in options === false) {
|
|
51
|
-
// If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
|
|
52
|
-
// when exported by webpack-extract-text-plugin.
|
|
53
|
-
options.sourceMapContents = true;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
33
|
+
if (typeof options.data === 'function') {
|
|
34
|
+
data = options.data(loaderContext);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
options.data = data ? data + os.EOL + content : content;
|
|
56
38
|
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
// opt.outputStyle
|
|
40
|
+
if (!options.outputStyle && loaderContext.minimize) {
|
|
41
|
+
options.outputStyle = 'compressed';
|
|
42
|
+
}
|
|
59
43
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
44
|
+
// opt.sourceMap
|
|
45
|
+
// Not using the `this.sourceMap` flag because css source maps are different
|
|
46
|
+
// @see https://github.com/webpack/css-loader/pull/40
|
|
47
|
+
if (options.sourceMap) {
|
|
48
|
+
// Deliberately overriding the sourceMap option here.
|
|
49
|
+
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
|
|
50
|
+
// In case it is a string, options.sourceMap should be a path where the source map is written.
|
|
51
|
+
// But since we're using the data option, the source map will not actually be written, but
|
|
52
|
+
// all paths in sourceMap.sources will be relative to that path.
|
|
53
|
+
// Pretty complicated... :(
|
|
54
|
+
options.sourceMap = path.join(process.cwd(), '/sass.map');
|
|
55
|
+
if ('sourceMapRoot' in options === false) {
|
|
56
|
+
options.sourceMapRoot = process.cwd();
|
|
65
57
|
}
|
|
58
|
+
if ('omitSourceMapUrl' in options === false) {
|
|
59
|
+
// The source map url doesn't make sense because we don't know the output path
|
|
60
|
+
// The css-loader will handle that for us
|
|
61
|
+
options.omitSourceMapUrl = true;
|
|
62
|
+
}
|
|
63
|
+
if ('sourceMapContents' in options === false) {
|
|
64
|
+
// If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
|
|
65
|
+
// when exported by webpack-extract-text-plugin.
|
|
66
|
+
options.sourceMapContents = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// indentedSyntax is a boolean flag.
|
|
71
|
+
const ext = path.extname(resourcePath);
|
|
72
|
+
|
|
73
|
+
// If we are compiling sass and indentedSyntax isn't set, automatically set it.
|
|
74
|
+
if (
|
|
75
|
+
ext &&
|
|
76
|
+
ext.toLowerCase() === '.sass' &&
|
|
77
|
+
'indentedSyntax' in options === false
|
|
78
|
+
) {
|
|
79
|
+
options.indentedSyntax = true;
|
|
80
|
+
} else {
|
|
81
|
+
options.indentedSyntax = Boolean(options.indentedSyntax);
|
|
82
|
+
}
|
|
66
83
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
options.importer
|
|
84
|
+
// Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
|
|
85
|
+
options.importer = options.importer
|
|
86
|
+
? proxyCustomImporters(options.importer, resourcePath)
|
|
87
|
+
: [];
|
|
88
|
+
options.importer.push(webpackImporter);
|
|
70
89
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
90
|
+
// `node-sass` uses `includePaths` to resolve `@import` paths. Append the currently processed file.
|
|
91
|
+
options.includePaths = options.includePaths || [];
|
|
92
|
+
options.includePaths.push(path.dirname(resourcePath));
|
|
74
93
|
|
|
75
|
-
|
|
94
|
+
return options;
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
module.exports = normalizeOptions;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates new custom importers that use the given `resourcePath` if libsass calls the custom importer with `prev`
|
|
@@ -10,20 +10,24 @@
|
|
|
10
10
|
*
|
|
11
11
|
* We have to fix this behavior in order to provide a consistent experience to the webpack user.
|
|
12
12
|
*
|
|
13
|
-
* @param {
|
|
13
|
+
* @param {Function|Array<Function>} importer
|
|
14
14
|
* @param {string} resourcePath
|
|
15
|
-
* @returns {Array<
|
|
15
|
+
* @returns {Array<Function>}
|
|
16
16
|
*/
|
|
17
17
|
function proxyCustomImporters(importer, resourcePath) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
return [].concat(importer).map(
|
|
19
|
+
// eslint-disable-next-line no-shadow
|
|
20
|
+
(importer) =>
|
|
21
|
+
function customImporter() {
|
|
22
|
+
return importer.apply(
|
|
23
|
+
this,
|
|
24
|
+
// eslint-disable-next-line prefer-rest-params
|
|
25
|
+
Array.from(arguments).map((arg, i) =>
|
|
26
|
+
i === 1 && arg === 'stdin' ? resourcePath : arg
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
module.exports = proxyCustomImporters;
|
package/lib/webpackImporter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @name PromisedResolve
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
* @param {Function<Error, string>} done
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
const path = require(
|
|
20
|
-
|
|
21
|
-
const importsToResolve = require(
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
const importsToResolve = require('./importsToResolve');
|
|
22
22
|
|
|
23
23
|
const matchCss = /\.css$/;
|
|
24
24
|
|
|
@@ -34,39 +34,45 @@ const matchCss = /\.css$/;
|
|
|
34
34
|
* @returns {Importer}
|
|
35
35
|
*/
|
|
36
36
|
function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
function dirContextFrom(fileContext) {
|
|
38
|
+
return path.dirname(
|
|
39
|
+
// The first file is 'stdin' when we're using the data option
|
|
40
|
+
fileContext === 'stdin' ? resourcePath : fileContext
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
// eslint-disable-next-line no-shadow
|
|
45
|
+
function startResolving(dir, importsToResolve) {
|
|
46
|
+
return importsToResolve.length === 0
|
|
47
|
+
? Promise.reject()
|
|
48
|
+
: resolve(dir, importsToResolve[0]).then(
|
|
49
|
+
(resolvedFile) => {
|
|
50
|
+
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
|
|
51
|
+
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
|
|
52
|
+
addNormalizedDependency(resolvedFile);
|
|
53
|
+
return {
|
|
54
|
+
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
|
|
55
|
+
file: resolvedFile.replace(matchCss, ''),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
() => {
|
|
59
|
+
const [, ...tailResult] = importsToResolve;
|
|
60
|
+
|
|
61
|
+
return startResolving(dir, tailResult);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
return (url, prev, done) => {
|
|
67
|
+
startResolving(dirContextFrom(prev), importsToResolve(url))
|
|
68
|
+
// Catch all resolving errors, return the original file and pass responsibility back to other custom importers
|
|
69
|
+
.catch(() => {
|
|
70
|
+
return {
|
|
71
|
+
file: url,
|
|
72
|
+
};
|
|
73
|
+
})
|
|
74
|
+
.then(done);
|
|
75
|
+
};
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
module.exports = webpackImporter;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sass-loader",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"description": "Sass loader for webpack",
|
|
5
5
|
"author": "J. Tangelder",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,13 +12,14 @@
|
|
|
12
12
|
"appveyor:test": "npm test",
|
|
13
13
|
"create-spec": "node test/tools/runCreateSpec.js",
|
|
14
14
|
"lint": "eslint lib test",
|
|
15
|
-
"test": "nyc
|
|
15
|
+
"test": "nyc mocha -R spec -t 10000",
|
|
16
16
|
"test-bootstrap-sass": "webpack-dev-server --config test/bootstrapSass/webpack.config.js --content-base ./test/bootstrapSass",
|
|
17
17
|
"test-source-map": "webpack-dev-server --config test/sourceMap/webpack.config.js --content-base ./test/sourceMap --inline",
|
|
18
18
|
"test-watch": "webpack --config test/watch/webpack.config.js",
|
|
19
19
|
"test-extract-text": "webpack --config test/extractText/webpack.config.js",
|
|
20
20
|
"test-hmr": "webpack-dev-server --config test/hmr/webpack.config.js --content-base ./test/hmr --hot --inline",
|
|
21
|
-
"travis:lint": "
|
|
21
|
+
"travis:lint:commits": "commitlint --from=${TRAVIS_BRANCH} --to=${TRAVIS_COMMIT}",
|
|
22
|
+
"travis:lint": "npm run lint && npm run travis:lint:commits",
|
|
22
23
|
"travis:test": "npm run test",
|
|
23
24
|
"travis:coverage": "npm run test",
|
|
24
25
|
"pretest": "npm run create-spec",
|
|
@@ -26,35 +27,43 @@
|
|
|
26
27
|
"release": "standard-version"
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"clone-deep": "^
|
|
30
|
+
"clone-deep": "^4.0.1",
|
|
30
31
|
"loader-utils": "^1.0.1",
|
|
31
|
-
"lodash.tail": "^4.1.1",
|
|
32
32
|
"neo-async": "^2.5.0",
|
|
33
|
-
"pify": "^
|
|
33
|
+
"pify": "^4.0.1",
|
|
34
34
|
"semver": "^5.5.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@commitlint/cli": "^7.2.1",
|
|
38
|
+
"@commitlint/config-conventional": "^7.1.2",
|
|
39
|
+
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
|
|
37
40
|
"bootstrap-sass": "^3.3.5",
|
|
38
|
-
"css-loader": "^0.
|
|
39
|
-
"eslint": "^
|
|
40
|
-
"eslint-
|
|
41
|
-
"eslint-plugin-jsdoc": "^
|
|
42
|
-
"
|
|
43
|
-
"
|
|
41
|
+
"css-loader": "^2.0.0",
|
|
42
|
+
"eslint": "^5.10.0",
|
|
43
|
+
"eslint-plugin-import": "^2.14.0",
|
|
44
|
+
"eslint-plugin-jsdoc": "^4.4.3",
|
|
45
|
+
"eslint-plugin-prettier": "^3.0.0",
|
|
46
|
+
"file-loader": "^3.0.1",
|
|
47
|
+
"husky": "^1.2.0",
|
|
48
|
+
"lint-staged": "^8.1.0",
|
|
49
|
+
"mocha": "^6.0.2",
|
|
44
50
|
"mock-require": "^3.0.1",
|
|
45
51
|
"node-sass": "^4.5.0",
|
|
46
|
-
"nyc": "^
|
|
47
|
-
"raw-loader": "^0.
|
|
52
|
+
"nyc": "^13.1.0",
|
|
53
|
+
"raw-loader": "^1.0.0",
|
|
54
|
+
"prettier": "^1.15.2",
|
|
48
55
|
"sass": "^1.3.0",
|
|
49
|
-
"should": "^
|
|
50
|
-
"standard-version": "^
|
|
51
|
-
"style-loader": "^0.
|
|
56
|
+
"should": "^13.2.3",
|
|
57
|
+
"standard-version": "^5.0.2",
|
|
58
|
+
"style-loader": "^0.23.1",
|
|
52
59
|
"webpack": "^4.5.0",
|
|
53
|
-
"webpack-
|
|
54
|
-
"webpack-
|
|
60
|
+
"webpack-cli": "^3.1.0",
|
|
61
|
+
"webpack-dev-server": "^3.1.4",
|
|
62
|
+
"webpack-merge": "^4.0.0",
|
|
63
|
+
"chokidar": "^2.1.6"
|
|
55
64
|
},
|
|
56
65
|
"engines": {
|
|
57
|
-
"node": ">= 6.9.0
|
|
66
|
+
"node": ">= 6.9.0"
|
|
58
67
|
},
|
|
59
68
|
"peerDependencies": {
|
|
60
69
|
"webpack": "^3.0.0 || ^4.0.0"
|
|
@@ -67,5 +76,21 @@
|
|
|
67
76
|
],
|
|
68
77
|
"repository": "https://github.com/webpack-contrib/sass-loader.git",
|
|
69
78
|
"bugs": "https://github.com/webpack-contrib/sass-loader/issues",
|
|
70
|
-
"homepage": "https://github.com/webpack-contrib/sass-loader"
|
|
79
|
+
"homepage": "https://github.com/webpack-contrib/sass-loader",
|
|
80
|
+
"husky": {
|
|
81
|
+
"hooks": {
|
|
82
|
+
"pre-commit": "lint-staged"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"lint-staged": {
|
|
86
|
+
"*.js": [
|
|
87
|
+
"eslint --fix",
|
|
88
|
+
"git add"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"commitlint": {
|
|
92
|
+
"extends": [
|
|
93
|
+
"@commitlint/config-conventional"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
71
96
|
}
|