sass-loader 7.1.0 → 8.0.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 +67 -1
- package/LICENSE +16 -14
- package/README.md +486 -192
- package/dist/SassError.js +33 -0
- package/dist/cjs.js +5 -0
- package/dist/getDefaultSassImplementation.js +28 -0
- package/dist/getRenderFunctionFromSassImplementation.js +39 -0
- package/dist/getSassImplementation.js +56 -0
- package/dist/getSassOptions.js +116 -0
- package/dist/importsToResolve.js +88 -0
- package/dist/index.js +114 -0
- package/dist/options.json +41 -0
- package/{lib → dist}/proxyCustomImporters.js +14 -12
- package/dist/webpackImporter.js +75 -0
- package/package.json +88 -54
- package/lib/formatSassError.js +0 -73
- package/lib/importsToResolve.js +0 -60
- package/lib/loader.js +0 -124
- package/lib/normalizeOptions.js +0 -78
- package/lib/webpackImporter.js +0 -72
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
class SassError extends Error {
|
|
9
|
+
constructor(sassError, resourcePath) {
|
|
10
|
+
super();
|
|
11
|
+
this.name = 'SassError';
|
|
12
|
+
this.originalSassError = sassError;
|
|
13
|
+
this.loc = {
|
|
14
|
+
line: sassError.line,
|
|
15
|
+
column: sassError.column
|
|
16
|
+
}; // Keep original error if `sassError.formatted` is unavailable
|
|
17
|
+
|
|
18
|
+
this.message = `${this.name}: ${this.originalSassError.message}`;
|
|
19
|
+
|
|
20
|
+
if (this.originalSassError.formatted) {
|
|
21
|
+
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.
|
|
22
|
+
// Usually you're only interested in the SASS stack in this case.
|
|
23
|
+
// eslint-disable-next-line no-param-reassign
|
|
24
|
+
|
|
25
|
+
this.hideStack = true;
|
|
26
|
+
Error.captureStackTrace(this, this.constructor);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var _default = SassError;
|
|
33
|
+
exports.default = _default;
|
package/dist/cjs.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
function getDefaultSassImplementation() {
|
|
9
|
+
let sassImplPkg = 'node-sass';
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
require.resolve('node-sass');
|
|
13
|
+
} catch (error) {
|
|
14
|
+
try {
|
|
15
|
+
require.resolve('sass');
|
|
16
|
+
|
|
17
|
+
sassImplPkg = 'sass';
|
|
18
|
+
} catch (ignoreError) {
|
|
19
|
+
sassImplPkg = 'node-sass';
|
|
20
|
+
}
|
|
21
|
+
} // eslint-disable-next-line import/no-dynamic-require, global-require
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
return require(sassImplPkg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var _default = getDefaultSassImplementation;
|
|
28
|
+
exports.default = _default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _neoAsync = _interopRequireDefault(require("neo-async"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
|
|
12
|
+
let nodeSassJobQueue = null;
|
|
13
|
+
/**
|
|
14
|
+
* Verifies that the implementation and version of Sass is supported by this loader.
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} implementation
|
|
17
|
+
* @returns {Function}
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
function getRenderFunctionFromSassImplementation(implementation) {
|
|
21
|
+
const isDartSass = implementation.info.includes('dart-sass');
|
|
22
|
+
|
|
23
|
+
if (isDartSass) {
|
|
24
|
+
return implementation.render.bind(implementation);
|
|
25
|
+
} // There is an issue with node-sass when async custom importers are used
|
|
26
|
+
// See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
|
|
27
|
+
// We need to use a job queue to make sure that one thread is always available to the UV lib
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if (nodeSassJobQueue === null) {
|
|
31
|
+
const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
|
|
32
|
+
nodeSassJobQueue = _neoAsync.default.queue(implementation.render.bind(implementation), threadPoolSize - 1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return nodeSassJobQueue.push.bind(nodeSassJobQueue);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var _default = getRenderFunctionFromSassImplementation;
|
|
39
|
+
exports.default = _default;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _semver = _interopRequireDefault(require("semver"));
|
|
9
|
+
|
|
10
|
+
var _getDefaultSassImplementation = _interopRequireDefault(require("./getDefaultSassImplementation"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
function getSassImplementation(implementation) {
|
|
15
|
+
let resolvedImplementation = implementation;
|
|
16
|
+
|
|
17
|
+
if (!resolvedImplementation) {
|
|
18
|
+
// eslint-disable-next-line no-param-reassign
|
|
19
|
+
resolvedImplementation = (0, _getDefaultSassImplementation.default)();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
info
|
|
24
|
+
} = resolvedImplementation;
|
|
25
|
+
|
|
26
|
+
if (!info) {
|
|
27
|
+
throw new Error('Unknown Sass implementation.');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const infoParts = info.split('\t');
|
|
31
|
+
|
|
32
|
+
if (infoParts.length < 2) {
|
|
33
|
+
throw new Error(`Unknown Sass implementation "${info}".`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const [implementationName, version] = infoParts;
|
|
37
|
+
|
|
38
|
+
if (implementationName === 'dart-sass') {
|
|
39
|
+
if (!_semver.default.satisfies(version, '^1.3.0')) {
|
|
40
|
+
throw new Error(`Dart Sass version ${version} is incompatible with ^1.3.0.`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return resolvedImplementation;
|
|
44
|
+
} else if (implementationName === 'node-sass') {
|
|
45
|
+
if (!_semver.default.satisfies(version, '^4.0.0')) {
|
|
46
|
+
throw new Error(`Node Sass version ${version} is incompatible with ^4.0.0.`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return resolvedImplementation;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
throw new Error(`Unknown Sass implementation "${implementationName}".`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
var _default = getSassImplementation;
|
|
56
|
+
exports.default = _default;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _os = _interopRequireDefault(require("os"));
|
|
9
|
+
|
|
10
|
+
var _path = _interopRequireDefault(require("path"));
|
|
11
|
+
|
|
12
|
+
var _cloneDeep = _interopRequireDefault(require("clone-deep"));
|
|
13
|
+
|
|
14
|
+
var _proxyCustomImporters = _interopRequireDefault(require("./proxyCustomImporters"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
function isProductionLikeMode(loaderContext) {
|
|
19
|
+
return loaderContext.mode === 'production' || !loaderContext.mode || loaderContext.minimize;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Derives the sass options from the loader context and normalizes its values with sane defaults.
|
|
23
|
+
*
|
|
24
|
+
* @param {object} loaderContext
|
|
25
|
+
* @param {object} loaderOptions
|
|
26
|
+
* @param {string} content
|
|
27
|
+
* @param {object} implementation
|
|
28
|
+
* @returns {Object}
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
function getSassOptions(loaderContext, loaderOptions, content, implementation) {
|
|
33
|
+
const options = (0, _cloneDeep.default)(loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === 'function' ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {});
|
|
34
|
+
const isDartSass = implementation.info.includes('dart-sass');
|
|
35
|
+
|
|
36
|
+
if (isDartSass) {
|
|
37
|
+
const shouldTryToResolveFibers = !options.fiber && options.fiber !== false;
|
|
38
|
+
|
|
39
|
+
if (shouldTryToResolveFibers) {
|
|
40
|
+
let fibers;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
fibers = require.resolve('fibers');
|
|
44
|
+
} catch (_error) {// Nothing
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (fibers) {
|
|
48
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
49
|
+
options.fiber = require(fibers);
|
|
50
|
+
}
|
|
51
|
+
} else if (options.fiber === false) {
|
|
52
|
+
// Don't pass the `fiber` option for `sass` (`Dart Sass`)
|
|
53
|
+
delete options.fiber;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
// Don't pass the `fiber` option for `node-sass`
|
|
57
|
+
delete options.fiber;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
options.data = loaderOptions.prependData ? typeof loaderOptions.prependData === 'function' ? loaderOptions.prependData(loaderContext) + _os.default.EOL + content : loaderOptions.prependData + _os.default.EOL + content : content; // opt.outputStyle
|
|
61
|
+
|
|
62
|
+
if (!options.outputStyle && isProductionLikeMode(loaderContext)) {
|
|
63
|
+
options.outputStyle = 'compressed';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const useSourceMap = typeof loaderOptions.sourceMap === 'boolean' ? loaderOptions.sourceMap : loaderContext.sourceMap; // opt.sourceMap
|
|
67
|
+
// Not using the `this.sourceMap` flag because css source maps are different
|
|
68
|
+
// @see https://github.com/webpack/css-loader/pull/40
|
|
69
|
+
|
|
70
|
+
if (useSourceMap) {
|
|
71
|
+
// Deliberately overriding the sourceMap option here.
|
|
72
|
+
// node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
|
|
73
|
+
// In case it is a string, options.sourceMap should be a path where the source map is written.
|
|
74
|
+
// But since we're using the data option, the source map will not actually be written, but
|
|
75
|
+
// all paths in sourceMap.sources will be relative to that path.
|
|
76
|
+
// Pretty complicated... :(
|
|
77
|
+
options.sourceMap = _path.default.join(process.cwd(), '/sass.map');
|
|
78
|
+
|
|
79
|
+
if ('sourceMapRoot' in options === false) {
|
|
80
|
+
options.sourceMapRoot = process.cwd();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ('omitSourceMapUrl' in options === false) {
|
|
84
|
+
// The source map url doesn't make sense because we don't know the output path
|
|
85
|
+
// The css-loader will handle that for us
|
|
86
|
+
options.omitSourceMapUrl = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if ('sourceMapContents' in options === false) {
|
|
90
|
+
// If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
|
|
91
|
+
// when exported by webpack-extract-text-plugin.
|
|
92
|
+
options.sourceMapContents = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const {
|
|
97
|
+
resourcePath
|
|
98
|
+
} = loaderContext;
|
|
99
|
+
|
|
100
|
+
const ext = _path.default.extname(resourcePath); // If we are compiling sass and indentedSyntax isn't set, automatically set it.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if (ext && ext.toLowerCase() === '.sass' && 'indentedSyntax' in options === false) {
|
|
104
|
+
options.indentedSyntax = true;
|
|
105
|
+
} else {
|
|
106
|
+
options.indentedSyntax = Boolean(options.indentedSyntax);
|
|
107
|
+
} // Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
options.importer = options.importer ? (0, _proxyCustomImporters.default)(options.importer, resourcePath) : [];
|
|
111
|
+
options.includePaths = (options.includePaths || []).concat(_path.default.dirname(resourcePath));
|
|
112
|
+
return options;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var _default = getSassOptions;
|
|
116
|
+
exports.default = _default;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
|
|
10
|
+
var _loaderUtils = _interopRequireDefault(require("loader-utils"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
// Examples:
|
|
15
|
+
// - ~package
|
|
16
|
+
// - ~package/
|
|
17
|
+
// - ~@org
|
|
18
|
+
// - ~@org/
|
|
19
|
+
// - ~@org/package
|
|
20
|
+
// - ~@org/package/
|
|
21
|
+
const matchModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
|
|
22
|
+
/**
|
|
23
|
+
* When libsass tries to resolve an import, it uses a special algorithm.
|
|
24
|
+
* Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
|
|
25
|
+
* returns an array of import paths to try. The last entry in the array is always the original url
|
|
26
|
+
* to enable straight-forward webpack.config aliases.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} url
|
|
29
|
+
* @returns {Array<string>}
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
function importsToResolve(url) {
|
|
33
|
+
const request = _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.
|
|
34
|
+
// @see https://github.com/webpack-contrib/sass-loader/issues/167
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
const ext = _path.default.extname(request).toLowerCase(); // In case there is module request, send this to webpack resolver
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if (matchModuleImport.test(url)) {
|
|
41
|
+
return [request, url];
|
|
42
|
+
} // 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.
|
|
43
|
+
// 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:
|
|
44
|
+
// - imports where the URL ends with .css.
|
|
45
|
+
// - imports where the URL begins http:// or https://.
|
|
46
|
+
// - imports where the URL is written as a url().
|
|
47
|
+
// - imports that have media queries.
|
|
48
|
+
//
|
|
49
|
+
// The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if (ext === '.css') {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const dirname = _path.default.dirname(request);
|
|
57
|
+
|
|
58
|
+
const basename = _path.default.basename(request); // In case there is file extension:
|
|
59
|
+
//
|
|
60
|
+
// 1. Try to resolve `_` file.
|
|
61
|
+
// 2. Try to resolve file without `_`.
|
|
62
|
+
// 3. Send a original url to webpack resolver, maybe it is alias.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if (['.scss', '.sass'].includes(ext)) {
|
|
66
|
+
return [`${dirname}/_${basename}`, `${dirname}/${basename}`, url];
|
|
67
|
+
} // In case there is no file extension and filename starts with `_`:
|
|
68
|
+
//
|
|
69
|
+
// 1. Try to resolve files with `scss`, `sass` and `css` extensions.
|
|
70
|
+
// 2. Try to resolve directory with `_index` or `index` filename.
|
|
71
|
+
// 3. Send the original url to webpack resolver, maybe it's alias.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if (basename.charAt(0) === '_') {
|
|
75
|
+
return [`${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
|
|
76
|
+
} // In case there is no file extension and filename doesn't start with `_`:
|
|
77
|
+
//
|
|
78
|
+
// 1. Try to resolve file starts with `_` and with extensions
|
|
79
|
+
// 2. Try to resolve file with extensions
|
|
80
|
+
// 3. Try to resolve directory with `_index` or `index` filename.
|
|
81
|
+
// 4. Send a original url to webpack resolver, maybe it is alias.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
return [`${dirname}/_${basename}.scss`, `${dirname}/_${basename}.sass`, `${dirname}/_${basename}.css`, `${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var _default = importsToResolve;
|
|
88
|
+
exports.default = _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
|
|
10
|
+
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
|
|
11
|
+
|
|
12
|
+
var _loaderUtils = require("loader-utils");
|
|
13
|
+
|
|
14
|
+
var _options = _interopRequireDefault(require("./options.json"));
|
|
15
|
+
|
|
16
|
+
var _getSassImplementation = _interopRequireDefault(require("./getSassImplementation"));
|
|
17
|
+
|
|
18
|
+
var _getSassOptions = _interopRequireDefault(require("./getSassOptions"));
|
|
19
|
+
|
|
20
|
+
var _webpackImporter = _interopRequireDefault(require("./webpackImporter"));
|
|
21
|
+
|
|
22
|
+
var _getRenderFunctionFromSassImplementation = _interopRequireDefault(require("./getRenderFunctionFromSassImplementation"));
|
|
23
|
+
|
|
24
|
+
var _SassError = _interopRequireDefault(require("./SassError"));
|
|
25
|
+
|
|
26
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The sass-loader makes node-sass and dart-sass available to webpack modules.
|
|
30
|
+
*
|
|
31
|
+
* @this {object}
|
|
32
|
+
* @param {string} content
|
|
33
|
+
*/
|
|
34
|
+
function loader(content) {
|
|
35
|
+
const options = (0, _loaderUtils.getOptions)(this) || {};
|
|
36
|
+
(0, _schemaUtils.default)(_options.default, options, {
|
|
37
|
+
name: 'Sass Loader',
|
|
38
|
+
baseDataPath: 'options'
|
|
39
|
+
});
|
|
40
|
+
const implementation = (0, _getSassImplementation.default)(options.implementation);
|
|
41
|
+
const callback = this.async();
|
|
42
|
+
|
|
43
|
+
const addNormalizedDependency = file => {
|
|
44
|
+
// node-sass returns POSIX paths
|
|
45
|
+
this.addDependency(_path.default.normalize(file));
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const sassOptions = (0, _getSassOptions.default)(this, options, content, implementation);
|
|
49
|
+
const shouldUseWebpackImporter = typeof options.webpackImporter === 'boolean' ? options.webpackImporter : true;
|
|
50
|
+
|
|
51
|
+
if (shouldUseWebpackImporter) {
|
|
52
|
+
const resolve = this.getResolve({
|
|
53
|
+
mainFields: ['sass', 'style', 'main', '...'],
|
|
54
|
+
mainFiles: ['_index', 'index', '...'],
|
|
55
|
+
extensions: ['.scss', '.sass', '.css', '...']
|
|
56
|
+
});
|
|
57
|
+
sassOptions.importer.push((0, _webpackImporter.default)(this.resourcePath, resolve, addNormalizedDependency));
|
|
58
|
+
} // Skip empty files, otherwise it will stop webpack, see issue #21
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if (sassOptions.data.trim() === '') {
|
|
62
|
+
callback(null, '');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const render = (0, _getRenderFunctionFromSassImplementation.default)(implementation);
|
|
67
|
+
render(sassOptions, (error, result) => {
|
|
68
|
+
if (error) {
|
|
69
|
+
if (error.file) {
|
|
70
|
+
addNormalizedDependency(error.file);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
callback(new _SassError.default(error, this.resourcePath));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (result.map && result.map !== '{}') {
|
|
78
|
+
// eslint-disable-next-line no-param-reassign
|
|
79
|
+
result.map = JSON.parse(result.map); // result.map.file is an optional property that provides the output filename.
|
|
80
|
+
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
|
|
81
|
+
// eslint-disable-next-line no-param-reassign
|
|
82
|
+
|
|
83
|
+
delete result.map.file; // One of the sources is 'stdin' according to dart-sass/node-sass because we've used the data input.
|
|
84
|
+
// Now let's override that value with the correct relative path.
|
|
85
|
+
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in getSassOptions,
|
|
86
|
+
// we know that this path is relative to process.cwd(). This is how node-sass works.
|
|
87
|
+
// eslint-disable-next-line no-param-reassign
|
|
88
|
+
|
|
89
|
+
const stdinIndex = result.map.sources.findIndex(source => source.indexOf('stdin') !== -1);
|
|
90
|
+
|
|
91
|
+
if (stdinIndex !== -1) {
|
|
92
|
+
// eslint-disable-next-line no-param-reassign
|
|
93
|
+
result.map.sources[stdinIndex] = _path.default.relative(process.cwd(), this.resourcePath);
|
|
94
|
+
} // node-sass returns POSIX paths, that's why we need to transform them back to native paths.
|
|
95
|
+
// This fixes an error on windows where the source-map module cannot resolve the source maps.
|
|
96
|
+
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
|
|
97
|
+
// eslint-disable-next-line no-param-reassign
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
result.map.sourceRoot = _path.default.normalize(result.map.sourceRoot); // eslint-disable-next-line no-param-reassign
|
|
101
|
+
|
|
102
|
+
result.map.sources = result.map.sources.map(_path.default.normalize);
|
|
103
|
+
} else {
|
|
104
|
+
// eslint-disable-next-line no-param-reassign
|
|
105
|
+
result.map = null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
result.stats.includedFiles.forEach(addNormalizedDependency);
|
|
109
|
+
callback(null, result.css.toString(), result.map);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var _default = loader;
|
|
114
|
+
exports.default = _default;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "object",
|
|
3
|
+
"properties": {
|
|
4
|
+
"implementation": {
|
|
5
|
+
"description": "The implementation of the sass to be used (https://github.com/webpack-contrib/sass-loader#implementation).",
|
|
6
|
+
"type": "object"
|
|
7
|
+
},
|
|
8
|
+
"sassOptions": {
|
|
9
|
+
"description": "Options for `node-sass` or `sass` (`Dart Sass`) implementation. (https://github.com/webpack-contrib/sass-loader#implementation).",
|
|
10
|
+
"anyOf": [
|
|
11
|
+
{
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"instanceof": "Function"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"prependData": {
|
|
21
|
+
"description": "Prepends `Sass`/`SCSS` code before the actual entry file (https://github.com/webpack-contrib/sass-loader#prependdata).",
|
|
22
|
+
"anyOf": [
|
|
23
|
+
{
|
|
24
|
+
"type": "string"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"instanceof": "Function"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"sourceMap": {
|
|
32
|
+
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/sass-loader#sourcemap).",
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"webpackImporter": {
|
|
36
|
+
"description": "Enables/Disables default `webpack` importer (https://github.com/webpack-contrib/sass-loader#webpackimporter).",
|
|
37
|
+
"type": "boolean"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"additionalProperties": false
|
|
41
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
3
8
|
/**
|
|
4
9
|
* Creates new custom importers that use the given `resourcePath` if libsass calls the custom importer with `prev`
|
|
5
10
|
* being 'stdin'.
|
|
@@ -10,20 +15,17 @@
|
|
|
10
15
|
*
|
|
11
16
|
* We have to fix this behavior in order to provide a consistent experience to the webpack user.
|
|
12
17
|
*
|
|
13
|
-
* @param {
|
|
18
|
+
* @param {Function|Array<Function>} importer
|
|
14
19
|
* @param {string} resourcePath
|
|
15
|
-
* @returns {Array<
|
|
20
|
+
* @returns {Array<Function>}
|
|
16
21
|
*/
|
|
17
22
|
function proxyCustomImporters(importer, resourcePath) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.map((arg, i) => i === 1 && arg === "stdin" ? resourcePath : arg)
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
});
|
|
23
|
+
return [].concat(importer).map( // eslint-disable-next-line no-shadow
|
|
24
|
+
importer => function customImporter() {
|
|
25
|
+
return importer.apply(this, // eslint-disable-next-line prefer-rest-params
|
|
26
|
+
Array.from(arguments).map((arg, i) => i === 1 && arg === 'stdin' ? resourcePath : arg));
|
|
27
|
+
});
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
var _default = proxyCustomImporters;
|
|
31
|
+
exports.default = _default;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
|
|
10
|
+
var _importsToResolve = _interopRequireDefault(require("./importsToResolve"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @name PromisedResolve
|
|
16
|
+
* @type {Function}
|
|
17
|
+
* @param {string} dir
|
|
18
|
+
* @param {string} request
|
|
19
|
+
* @returns Promise
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @name Importer
|
|
24
|
+
* @type {Function}
|
|
25
|
+
* @param {string} url
|
|
26
|
+
* @param {string} prev
|
|
27
|
+
* @param {Function<Error, string>} done
|
|
28
|
+
*/
|
|
29
|
+
const matchCss = /\.css$/i;
|
|
30
|
+
/**
|
|
31
|
+
* Returns an importer that uses webpack's resolving algorithm.
|
|
32
|
+
*
|
|
33
|
+
* It's important that the returned function has the correct number of arguments
|
|
34
|
+
* (based on whether the call is sync or async) because otherwise node-sass doesn't exit.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} resourcePath
|
|
37
|
+
* @param {PromisedResolve} resolve
|
|
38
|
+
* @param {Function<string>} addNormalizedDependency
|
|
39
|
+
* @returns {Importer}
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
|
|
43
|
+
function dirContextFrom(fileContext) {
|
|
44
|
+
return _path.default.dirname( // The first file is 'stdin' when we're using the data option
|
|
45
|
+
fileContext === 'stdin' ? resourcePath : fileContext);
|
|
46
|
+
} // eslint-disable-next-line no-shadow
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
function startResolving(dir, importsToResolve) {
|
|
50
|
+
return importsToResolve.length === 0 ? Promise.reject() : resolve(dir, importsToResolve[0]).then(resolvedFile => {
|
|
51
|
+
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
|
|
52
|
+
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
|
|
53
|
+
addNormalizedDependency(resolvedFile);
|
|
54
|
+
return {
|
|
55
|
+
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
|
|
56
|
+
file: resolvedFile.replace(matchCss, '')
|
|
57
|
+
};
|
|
58
|
+
}, () => {
|
|
59
|
+
const [, ...tailResult] = importsToResolve;
|
|
60
|
+
return startResolving(dir, tailResult);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return (url, prev, done) => {
|
|
65
|
+
startResolving(dirContextFrom(prev), (0, _importsToResolve.default)(url)) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
|
|
66
|
+
.catch(() => {
|
|
67
|
+
return {
|
|
68
|
+
file: url
|
|
69
|
+
};
|
|
70
|
+
}).then(done);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var _default = webpackImporter;
|
|
75
|
+
exports.default = _default;
|