sass-loader 13.3.0 → 13.3.2

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/README.md CHANGED
@@ -98,6 +98,10 @@ module.exports = {
98
98
 
99
99
  Finally run `webpack` via your preferred method.
100
100
 
101
+ ### The `outputStyle` (old API) and `style` (new API) options in `production` mode
102
+
103
+ For `production` mode, the `outputStyle` (old API) and `style` (new API) options default to `compressed` unless otherwise specified in `sassOptions`.
104
+
101
105
  ### Resolving `import` at-rules
102
106
 
103
107
  Webpack provides an [advanced mechanism to resolve files](https://webpack.js.org/concepts/module-resolution/).
package/dist/index.js CHANGED
@@ -8,7 +8,6 @@ var _url = _interopRequireDefault(require("url"));
8
8
  var _path = _interopRequireDefault(require("path"));
9
9
  var _options = _interopRequireDefault(require("./options.json"));
10
10
  var _utils = require("./utils");
11
- var _SassError = _interopRequireDefault(require("./SassError"));
12
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
12
  /**
14
13
  * The sass-loader makes node-sass and dart-sass available to webpack modules.
@@ -19,9 +18,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
18
  async function loader(content) {
20
19
  const options = this.getOptions(_options.default);
21
20
  const callback = this.async();
22
- const implementation = (0, _utils.getSassImplementation)(this, options.implementation);
23
- if (!implementation) {
24
- callback();
21
+ let implementation;
22
+ try {
23
+ implementation = (0, _utils.getSassImplementation)(this, options.implementation);
24
+ } catch (error) {
25
+ callback(error);
25
26
  return;
26
27
  }
27
28
  const useSourceMap = typeof options.sourceMap === "boolean" ? options.sourceMap : this.sourceMap;
@@ -38,7 +39,13 @@ async function loader(content) {
38
39
  sassOptions.importers.push((0, _utils.getModernWebpackImporter)(this, implementation));
39
40
  }
40
41
  }
41
- const compile = (0, _utils.getCompileFn)(implementation, options);
42
+ let compile;
43
+ try {
44
+ compile = (0, _utils.getCompileFn)(implementation, options);
45
+ } catch (error) {
46
+ callback(error);
47
+ return;
48
+ }
42
49
  let result;
43
50
  try {
44
51
  result = await compile(sassOptions, options);
@@ -53,7 +60,7 @@ async function loader(content) {
53
60
  // `node-sass` returns POSIX paths
54
61
  this.addDependency(_path.default.normalize(error.file));
55
62
  }
56
- callback(new _SassError.default(error));
63
+ callback((0, _utils.errorFactory)(error));
57
64
  return;
58
65
  }
59
66
  let map =
package/dist/utils.js CHANGED
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.errorFactory = errorFactory;
6
7
  exports.getCompileFn = getCompileFn;
7
8
  exports.getModernWebpackImporter = getModernWebpackImporter;
8
9
  exports.getSassImplementation = getSassImplementation;
@@ -13,9 +14,6 @@ exports.isSupportedFibers = isSupportedFibers;
13
14
  exports.normalizeSourceMap = normalizeSourceMap;
14
15
  var _url = _interopRequireDefault(require("url"));
15
16
  var _path = _interopRequireDefault(require("path"));
16
- var _full = require("klona/full");
17
- var _neoAsync = _interopRequireDefault(require("neo-async"));
18
- var _SassWarning = _interopRequireDefault(require("./SassWarning"));
19
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
18
  function getDefaultSassImplementation() {
21
19
  let sassImplPkg = "sass";
@@ -45,35 +43,21 @@ function getDefaultSassImplementation() {
45
43
  function getSassImplementation(loaderContext, implementation) {
46
44
  let resolvedImplementation = implementation;
47
45
  if (!resolvedImplementation) {
48
- try {
49
- resolvedImplementation = getDefaultSassImplementation();
50
- } catch (error) {
51
- loaderContext.emitError(error);
52
- return;
53
- }
46
+ resolvedImplementation = getDefaultSassImplementation();
54
47
  }
55
48
  if (typeof resolvedImplementation === "string") {
56
- try {
57
- // eslint-disable-next-line import/no-dynamic-require, global-require
58
- resolvedImplementation = require(resolvedImplementation);
59
- } catch (error) {
60
- loaderContext.emitError(error);
61
-
62
- // eslint-disable-next-line consistent-return
63
- return;
64
- }
49
+ // eslint-disable-next-line import/no-dynamic-require, global-require
50
+ resolvedImplementation = require(resolvedImplementation);
65
51
  }
66
52
  const {
67
53
  info
68
54
  } = resolvedImplementation;
69
55
  if (!info) {
70
- loaderContext.emitError(new Error("Unknown Sass implementation."));
71
- return;
56
+ throw new Error("Unknown Sass implementation.");
72
57
  }
73
58
  const infoParts = info.split("\t");
74
59
  if (infoParts.length < 2) {
75
- loaderContext.emitError(new Error(`Unknown Sass implementation "${info}".`));
76
- return;
60
+ throw new Error(`Unknown Sass implementation "${info}".`);
77
61
  }
78
62
  const [implementationName] = infoParts;
79
63
  if (implementationName === "dart-sass") {
@@ -86,7 +70,7 @@ function getSassImplementation(loaderContext, implementation) {
86
70
  // eslint-disable-next-line consistent-return
87
71
  return resolvedImplementation;
88
72
  }
89
- loaderContext.emitError(new Error(`Unknown Sass implementation "${implementationName}".`));
73
+ throw new Error(`Unknown Sass implementation "${implementationName}".`);
90
74
  }
91
75
 
92
76
  /**
@@ -121,16 +105,17 @@ function isSupportedFibers() {
121
105
  * @returns {Object}
122
106
  */
123
107
  async function getSassOptions(loaderContext, loaderOptions, content, implementation, useSourceMap) {
124
- const options = (0, _full.klona)(loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === "function" ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {});
125
- const isDartSass = implementation.info.includes("dart-sass");
126
- const isModernAPI = loaderOptions.api === "modern";
127
- options.data = loaderOptions.additionalData ? typeof loaderOptions.additionalData === "function" ? await loaderOptions.additionalData(content, loaderContext) : `${loaderOptions.additionalData}\n${content}` : content;
128
- if (!options.logger) {
108
+ const options = loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === "function" ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {};
109
+ const sassOptions = {
110
+ ...options,
111
+ data: loaderOptions.additionalData ? typeof loaderOptions.additionalData === "function" ? await loaderOptions.additionalData(content, loaderContext) : `${loaderOptions.additionalData}\n${content}` : content
112
+ };
113
+ if (!sassOptions.logger) {
129
114
  const needEmitWarning = loaderOptions.warnRuleAsWarning !== false;
130
115
  const logger = loaderContext.getLogger("sass-loader");
131
116
  const formatSpan = span => `${span.url || "-"}:${span.start.line}:${span.start.column}: `;
132
117
  const formatDebugSpan = span => `[debug:${span.start.line}:${span.start.column}] `;
133
- options.logger = {
118
+ sassOptions.logger = {
134
119
  debug(message, loggerOptions) {
135
120
  let builtMessage = "";
136
121
  if (loggerOptions.span) {
@@ -152,43 +137,48 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
152
137
  builtMessage += `\n\n${loggerOptions.stack}`;
153
138
  }
154
139
  if (needEmitWarning) {
155
- loaderContext.emitWarning(new _SassWarning.default(builtMessage, loggerOptions));
140
+ const warning = new Error(builtMessage);
141
+ warning.name = "SassWarning";
142
+ warning.stack = null;
143
+ loaderContext.emitWarning(warning);
156
144
  } else {
157
145
  logger.warn(builtMessage);
158
146
  }
159
147
  }
160
148
  };
161
149
  }
150
+ const isModernAPI = loaderOptions.api === "modern";
162
151
  const {
163
152
  resourcePath
164
153
  } = loaderContext;
165
154
  if (isModernAPI) {
166
- options.url = _url.default.pathToFileURL(resourcePath);
155
+ sassOptions.url = _url.default.pathToFileURL(resourcePath);
167
156
 
168
157
  // opt.outputStyle
169
- if (!options.style && isProductionLikeMode(loaderContext)) {
170
- options.style = "compressed";
158
+ if (!sassOptions.style && isProductionLikeMode(loaderContext)) {
159
+ sassOptions.style = "compressed";
171
160
  }
172
161
  if (useSourceMap) {
173
- options.sourceMap = true;
162
+ sassOptions.sourceMap = true;
174
163
  }
175
164
 
176
165
  // If we are compiling sass and indentedSyntax isn't set, automatically set it.
177
- if (typeof options.syntax === "undefined") {
166
+ if (typeof sassOptions.syntax === "undefined") {
178
167
  const ext = _path.default.extname(resourcePath);
179
168
  if (ext && ext.toLowerCase() === ".scss") {
180
- options.syntax = "scss";
169
+ sassOptions.syntax = "scss";
181
170
  } else if (ext && ext.toLowerCase() === ".sass") {
182
- options.syntax = "indented";
171
+ sassOptions.syntax = "indented";
183
172
  } else if (ext && ext.toLowerCase() === ".css") {
184
- options.syntax = "css";
173
+ sassOptions.syntax = "css";
185
174
  }
186
175
  }
187
- options.importers = options.importers ? Array.isArray(options.importers) ? options.importers : [options.importers] : [];
176
+ sassOptions.importers = sassOptions.importers ? Array.isArray(sassOptions.importers) ? sassOptions.importers.slice() : [sassOptions.importers] : [];
188
177
  } else {
189
- options.file = resourcePath;
178
+ sassOptions.file = resourcePath;
179
+ const isDartSass = implementation.info.includes("dart-sass");
190
180
  if (isDartSass && isSupportedFibers()) {
191
- const shouldTryToResolveFibers = !options.fiber && options.fiber !== false;
181
+ const shouldTryToResolveFibers = !sassOptions.fiber && sassOptions.fiber !== false;
192
182
  if (shouldTryToResolveFibers) {
193
183
  let fibers;
194
184
  try {
@@ -198,20 +188,20 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
198
188
  }
199
189
  if (fibers) {
200
190
  // eslint-disable-next-line global-require, import/no-dynamic-require
201
- options.fiber = require(fibers);
191
+ sassOptions.fiber = require(fibers);
202
192
  }
203
- } else if (options.fiber === false) {
193
+ } else if (sassOptions.fiber === false) {
204
194
  // Don't pass the `fiber` option for `sass` (`Dart Sass`)
205
- delete options.fiber;
195
+ delete sassOptions.fiber;
206
196
  }
207
197
  } else {
208
198
  // Don't pass the `fiber` option for `node-sass`
209
- delete options.fiber;
199
+ delete sassOptions.fiber;
210
200
  }
211
201
 
212
202
  // opt.outputStyle
213
- if (!options.outputStyle && isProductionLikeMode(loaderContext)) {
214
- options.outputStyle = "compressed";
203
+ if (!sassOptions.outputStyle && isProductionLikeMode(loaderContext)) {
204
+ sassOptions.outputStyle = "compressed";
215
205
  }
216
206
  if (useSourceMap) {
217
207
  // Deliberately overriding the sourceMap option here.
@@ -220,31 +210,31 @@ async function getSassOptions(loaderContext, loaderOptions, content, implementat
220
210
  // But since we're using the data option, the source map will not actually be written, but
221
211
  // all paths in sourceMap.sources will be relative to that path.
222
212
  // Pretty complicated... :(
223
- options.sourceMap = true;
224
- options.outFile = _path.default.join(loaderContext.rootContext, "style.css.map");
225
- options.sourceMapContents = true;
226
- options.omitSourceMapUrl = true;
227
- options.sourceMapEmbed = false;
213
+ sassOptions.sourceMap = true;
214
+ sassOptions.outFile = _path.default.join(loaderContext.rootContext, "style.css.map");
215
+ sassOptions.sourceMapContents = true;
216
+ sassOptions.omitSourceMapUrl = true;
217
+ sassOptions.sourceMapEmbed = false;
228
218
  }
229
219
  const ext = _path.default.extname(resourcePath);
230
220
 
231
221
  // If we are compiling sass and indentedSyntax isn't set, automatically set it.
232
- if (ext && ext.toLowerCase() === ".sass" && typeof options.indentedSyntax === "undefined") {
233
- options.indentedSyntax = true;
222
+ if (ext && ext.toLowerCase() === ".sass" && typeof sassOptions.indentedSyntax === "undefined") {
223
+ sassOptions.indentedSyntax = true;
234
224
  } else {
235
- options.indentedSyntax = Boolean(options.indentedSyntax);
225
+ sassOptions.indentedSyntax = Boolean(sassOptions.indentedSyntax);
236
226
  }
237
227
 
238
228
  // Allow passing custom importers to `sass`/`node-sass`. Accepts `Function` or an array of `Function`s.
239
- options.importer = options.importer ? proxyCustomImporters(Array.isArray(options.importer) ? options.importer : [options.importer], loaderContext) : [];
240
- options.includePaths = [].concat(process.cwd()).concat(
229
+ sassOptions.importer = sassOptions.importer ? proxyCustomImporters(Array.isArray(sassOptions.importer) ? sassOptions.importer.slice() : [sassOptions.importer], loaderContext) : [];
230
+ sassOptions.includePaths = [].concat(process.cwd()).concat(
241
231
  // We use `includePaths` in context for resolver, so it should be always absolute
242
- (options.includePaths || []).map(includePath => _path.default.isAbsolute(includePath) ? includePath : _path.default.join(process.cwd(), includePath))).concat(process.env.SASS_PATH ? process.env.SASS_PATH.split(process.platform === "win32" ? ";" : ":") : []);
243
- if (typeof options.charset === "undefined") {
244
- options.charset = true;
232
+ (sassOptions.includePaths ? sassOptions.includePaths.slice() : []).map(includePath => _path.default.isAbsolute(includePath) ? includePath : _path.default.join(process.cwd(), includePath))).concat(process.env.SASS_PATH ? process.env.SASS_PATH.split(process.platform === "win32" ? ";" : ":") : []);
233
+ if (typeof sassOptions.charset === "undefined") {
234
+ sassOptions.charset = true;
245
235
  }
246
236
  }
247
- return options;
237
+ return sassOptions;
248
238
  }
249
239
  const MODULE_REQUEST_REGEX = /^[^?]*~/;
250
240
 
@@ -564,7 +554,10 @@ function getCompileFn(implementation, options) {
564
554
  // We need to use a job queue to make sure that one thread is always available to the UV lib
565
555
  if (nodeSassJobQueue === null) {
566
556
  const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
567
- nodeSassJobQueue = _neoAsync.default.queue(implementation.render.bind(implementation), threadPoolSize - 1);
557
+ // Only used for `node-sass`, so let's load it lazily
558
+ // eslint-disable-next-line global-require
559
+ const async = require("neo-async");
560
+ nodeSassJobQueue = async.queue(implementation.render.bind(implementation), threadPoolSize - 1);
568
561
  }
569
562
  return sassOptions => new Promise((resolve, reject) => {
570
563
  nodeSassJobQueue.push.bind(nodeSassJobQueue)(sassOptions, (error, result) => {
@@ -623,4 +616,20 @@ function normalizeSourceMap(map, rootContext) {
623
616
  return source;
624
617
  });
625
618
  return newMap;
619
+ }
620
+ function errorFactory(error) {
621
+ let message;
622
+ if (error.formatted) {
623
+ message = error.formatted.replace(/^Error: /, "");
624
+ } else {
625
+ // Keep original error if `sassError.formatted` is unavailable
626
+ ({
627
+ message
628
+ } = error);
629
+ }
630
+ const obj = new Error(message, {
631
+ cause: error
632
+ });
633
+ obj.stack = null;
634
+ return obj;
626
635
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sass-loader",
3
- "version": "13.3.0",
3
+ "version": "13.3.2",
4
4
  "description": "Sass loader for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/sass-loader",
@@ -63,7 +63,6 @@
63
63
  }
64
64
  },
65
65
  "dependencies": {
66
- "klona": "^2.0.6",
67
66
  "neo-async": "^2.6.2"
68
67
  },
69
68
  "devDependencies": {
package/dist/SassError.js DELETED
@@ -1,31 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- class SassError extends Error {
8
- constructor(sassError) {
9
- super();
10
- this.name = "SassError";
11
-
12
- // Instruct webpack to hide the JS stack from the console.
13
- // Usually you're only interested in the SASS error in this case.
14
- this.hideStack = true;
15
- Error.captureStackTrace(this, this.constructor);
16
- if (typeof sassError.line !== "undefined" || typeof sassError.column !== "undefined") {
17
- this.loc = {
18
- line: sassError.line,
19
- column: sassError.column
20
- };
21
- }
22
-
23
- // Keep original error if `sassError.formatted` is unavailable
24
- this.message = `${this.name}: ${typeof sassError.message !== "undefined" ? sassError.message : sassError}`;
25
- if (sassError.formatted) {
26
- this.message = `${this.name}: ${sassError.formatted.replace(/^Error: /, "")}`;
27
- }
28
- }
29
- }
30
- var _default = SassError;
31
- exports.default = _default;
@@ -1,21 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- class SassWarning extends Error {
8
- constructor(warning, options) {
9
- super(warning);
10
- this.name = "SassWarning";
11
- this.hideStack = true;
12
- if (options.span) {
13
- this.loc = {
14
- line: options.span.start.line,
15
- column: options.span.start.column
16
- };
17
- }
18
- }
19
- }
20
- var _default = SassWarning;
21
- exports.default = _default;