css-loader 6.7.1 → 6.7.3

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/dist/utils.js CHANGED
@@ -27,43 +27,33 @@ exports.shouldUseModulesPlugins = shouldUseModulesPlugins;
27
27
  exports.shouldUseURLPlugin = shouldUseURLPlugin;
28
28
  exports.sort = sort;
29
29
  exports.stringifyRequest = stringifyRequest;
30
-
31
30
  var _url = require("url");
32
-
33
31
  var _path = _interopRequireDefault(require("path"));
34
-
35
32
  var _postcssModulesValues = _interopRequireDefault(require("postcss-modules-values"));
36
-
37
33
  var _postcssModulesLocalByDefault = _interopRequireDefault(require("postcss-modules-local-by-default"));
38
-
39
34
  var _postcssModulesExtractImports = _interopRequireDefault(require("postcss-modules-extract-imports"));
40
-
41
35
  var _postcssModulesScope = _interopRequireDefault(require("postcss-modules-scope"));
42
-
43
36
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
44
-
45
37
  /*
46
38
  MIT License http://www.opensource.org/licenses/mit-license.php
47
39
  Author Tobias Koppers @sokra
48
40
  */
41
+
49
42
  const WEBPACK_IGNORE_COMMENT_REGEXP = /webpackIgnore:(\s+)?(true|false)/;
50
43
  exports.WEBPACK_IGNORE_COMMENT_REGEXP = WEBPACK_IGNORE_COMMENT_REGEXP;
51
44
  const matchRelativePath = /^\.\.?[/\\]/;
52
-
53
45
  function isAbsolutePath(str) {
54
46
  return _path.default.posix.isAbsolute(str) || _path.default.win32.isAbsolute(str);
55
47
  }
56
-
57
48
  function isRelativePath(str) {
58
49
  return matchRelativePath.test(str);
59
- } // TODO simplify for the next major release
60
-
50
+ }
61
51
 
52
+ // TODO simplify for the next major release
62
53
  function stringifyRequest(loaderContext, request) {
63
54
  if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") {
64
55
  return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
65
56
  }
66
-
67
57
  const splitted = request.split("!");
68
58
  const {
69
59
  context
@@ -73,34 +63,28 @@ function stringifyRequest(loaderContext, request) {
73
63
  const splittedPart = part.match(/^(.*?)(\?.*)/);
74
64
  const query = splittedPart ? splittedPart[2] : "";
75
65
  let singlePath = splittedPart ? splittedPart[1] : part;
76
-
77
66
  if (isAbsolutePath(singlePath) && context) {
78
67
  singlePath = _path.default.relative(context, singlePath);
79
-
80
68
  if (isAbsolutePath(singlePath)) {
81
69
  // If singlePath still matches an absolute path, singlePath was on a different drive than context.
82
70
  // In this case, we leave the path platform-specific without replacing any separators.
83
71
  // @see https://github.com/webpack/loader-utils/pull/14
84
72
  return singlePath + query;
85
73
  }
86
-
87
74
  if (isRelativePath(singlePath) === false) {
88
75
  // Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
89
76
  singlePath = `./${singlePath}`;
90
77
  }
91
78
  }
92
-
93
79
  return singlePath.replace(/\\/g, "/") + query;
94
80
  }).join("!"));
95
- } // We can't use path.win32.isAbsolute because it also matches paths starting with a forward slash
96
-
81
+ }
97
82
 
83
+ // We can't use path.win32.isAbsolute because it also matches paths starting with a forward slash
98
84
  const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
99
85
  const IS_MODULE_REQUEST = /^[^?]*~/;
100
-
101
86
  function urlToRequest(url, root) {
102
87
  let request;
103
-
104
88
  if (IS_NATIVE_WIN32_PATH.test(url)) {
105
89
  // absolute windows path, keep it
106
90
  request = url;
@@ -112,29 +96,25 @@ function urlToRequest(url, root) {
112
96
  } else {
113
97
  // every other url is threaded like a relative url
114
98
  request = `./${url}`;
115
- } // A `~` makes the url an module
116
-
99
+ }
117
100
 
101
+ // A `~` makes the url an module
118
102
  if (IS_MODULE_REQUEST.test(request)) {
119
103
  request = request.replace(IS_MODULE_REQUEST, "");
120
104
  }
121
-
122
105
  return request;
123
- } // eslint-disable-next-line no-useless-escape
124
-
106
+ }
125
107
 
108
+ // eslint-disable-next-line no-useless-escape
126
109
  const regexSingleEscape = /[ -,.\/:-@[\]\^`{-~]/;
127
110
  const regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;
128
-
129
111
  const preserveCamelCase = string => {
130
112
  let result = string;
131
113
  let isLastCharLower = false;
132
114
  let isLastCharUpper = false;
133
115
  let isLastLastCharUpper = false;
134
-
135
116
  for (let i = 0; i < result.length; i++) {
136
117
  const character = result[i];
137
-
138
118
  if (isLastCharLower && /[\p{Lu}]/u.test(character)) {
139
119
  result = `${result.slice(0, i)}-${result.slice(i)}`;
140
120
  isLastCharLower = false;
@@ -152,39 +132,31 @@ const preserveCamelCase = string => {
152
132
  isLastCharUpper = character.toUpperCase() === character && character.toLowerCase() !== character;
153
133
  }
154
134
  }
155
-
156
135
  return result;
157
136
  };
158
-
159
137
  function camelCase(input) {
160
138
  let result = input.trim();
161
-
162
139
  if (result.length === 0) {
163
140
  return "";
164
141
  }
165
-
166
142
  if (result.length === 1) {
167
143
  return result.toLowerCase();
168
144
  }
169
-
170
145
  const hasUpperCase = result !== result.toLowerCase();
171
-
172
146
  if (hasUpperCase) {
173
147
  result = preserveCamelCase(result);
174
148
  }
175
-
176
149
  return result.replace(/^[_.\- ]+/, "").toLowerCase().replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toUpperCase()).replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toUpperCase());
177
150
  }
178
-
179
151
  function escape(string) {
180
152
  let output = "";
181
153
  let counter = 0;
182
-
183
154
  while (counter < string.length) {
184
155
  // eslint-disable-next-line no-plusplus
185
156
  const character = string.charAt(counter++);
186
- let value; // eslint-disable-next-line no-control-regex
157
+ let value;
187
158
 
159
+ // eslint-disable-next-line no-control-regex
188
160
  if (/[\t\n\f\r\x0B]/.test(character)) {
189
161
  const codePoint = character.charCodeAt();
190
162
  value = `\\${codePoint.toString(16).toUpperCase()} `;
@@ -193,131 +165,117 @@ function escape(string) {
193
165
  } else {
194
166
  value = character;
195
167
  }
196
-
197
168
  output += value;
198
169
  }
199
-
200
170
  const firstChar = string.charAt(0);
201
-
202
171
  if (/^-[-\d]/.test(output)) {
203
172
  output = `\\-${output.slice(1)}`;
204
173
  } else if (/\d/.test(firstChar)) {
205
174
  output = `\\3${firstChar} ${output.slice(1)}`;
206
- } // Remove spaces after `\HEX` escapes that are not followed by a hex digit,
175
+ }
176
+
177
+ // Remove spaces after `\HEX` escapes that are not followed by a hex digit,
207
178
  // since they’re redundant. Note that this is only possible if the escape
208
179
  // sequence isn’t preceded by an odd number of backslashes.
209
-
210
-
211
180
  output = output.replace(regexExcessiveSpaces, ($0, $1, $2) => {
212
181
  if ($1 && $1.length % 2) {
213
182
  // It’s not safe to remove the space, so don’t.
214
183
  return $0;
215
- } // Strip the space.
216
-
184
+ }
217
185
 
186
+ // Strip the space.
218
187
  return ($1 || "") + $2;
219
188
  });
220
189
  return output;
221
190
  }
222
-
223
191
  function gobbleHex(str) {
224
192
  const lower = str.toLowerCase();
225
193
  let hex = "";
226
- let spaceTerminated = false; // eslint-disable-next-line no-undefined
194
+ let spaceTerminated = false;
227
195
 
196
+ // eslint-disable-next-line no-undefined
228
197
  for (let i = 0; i < 6 && lower[i] !== undefined; i++) {
229
- const code = lower.charCodeAt(i); // check to see if we are dealing with a valid hex char [a-f|0-9]
230
-
231
- const valid = code >= 97 && code <= 102 || code >= 48 && code <= 57; // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point
232
-
198
+ const code = lower.charCodeAt(i);
199
+ // check to see if we are dealing with a valid hex char [a-f|0-9]
200
+ const valid = code >= 97 && code <= 102 || code >= 48 && code <= 57;
201
+ // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point
233
202
  spaceTerminated = code === 32;
234
-
235
203
  if (!valid) {
236
204
  break;
237
205
  }
238
-
239
206
  hex += lower[i];
240
207
  }
241
-
242
208
  if (hex.length === 0) {
243
209
  // eslint-disable-next-line no-undefined
244
210
  return undefined;
245
211
  }
246
-
247
212
  const codePoint = parseInt(hex, 16);
248
- const isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff; // Add special case for
213
+ const isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff;
214
+ // Add special case for
249
215
  // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point"
250
216
  // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point
251
-
252
217
  if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10ffff) {
253
218
  return ["\uFFFD", hex.length + (spaceTerminated ? 1 : 0)];
254
219
  }
255
-
256
220
  return [String.fromCodePoint(codePoint), hex.length + (spaceTerminated ? 1 : 0)];
257
221
  }
258
-
259
222
  const CONTAINS_ESCAPE = /\\/;
260
-
261
223
  function unescape(str) {
262
224
  const needToProcess = CONTAINS_ESCAPE.test(str);
263
-
264
225
  if (!needToProcess) {
265
226
  return str;
266
227
  }
267
-
268
228
  let ret = "";
269
-
270
229
  for (let i = 0; i < str.length; i++) {
271
230
  if (str[i] === "\\") {
272
- const gobbled = gobbleHex(str.slice(i + 1, i + 7)); // eslint-disable-next-line no-undefined
231
+ const gobbled = gobbleHex(str.slice(i + 1, i + 7));
273
232
 
233
+ // eslint-disable-next-line no-undefined
274
234
  if (gobbled !== undefined) {
275
235
  ret += gobbled[0];
276
- i += gobbled[1]; // eslint-disable-next-line no-continue
236
+ i += gobbled[1];
277
237
 
238
+ // eslint-disable-next-line no-continue
278
239
  continue;
279
- } // Retain a pair of \\ if double escaped `\\\\`
280
- // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e
281
-
240
+ }
282
241
 
242
+ // Retain a pair of \\ if double escaped `\\\\`
243
+ // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e
283
244
  if (str[i + 1] === "\\") {
284
245
  ret += "\\";
285
- i += 1; // eslint-disable-next-line no-continue
246
+ i += 1;
286
247
 
248
+ // eslint-disable-next-line no-continue
287
249
  continue;
288
- } // if \\ is at the end of the string retain it
289
- // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb
290
-
250
+ }
291
251
 
252
+ // if \\ is at the end of the string retain it
253
+ // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb
292
254
  if (str.length === i + 1) {
293
255
  ret += str[i];
294
- } // eslint-disable-next-line no-continue
295
-
256
+ }
296
257
 
258
+ // eslint-disable-next-line no-continue
297
259
  continue;
298
260
  }
299
-
300
261
  ret += str[i];
301
262
  }
302
-
303
263
  return ret;
304
264
  }
305
-
306
265
  function normalizePath(file) {
307
266
  return _path.default.sep === "\\" ? file.replace(/\\/g, "/") : file;
308
- } // eslint-disable-next-line no-control-regex
309
-
310
-
311
- const filenameReservedRegex = /[<>:"/\\|?*]/g; // eslint-disable-next-line no-control-regex
267
+ }
312
268
 
269
+ // eslint-disable-next-line no-control-regex
270
+ const filenameReservedRegex = /[<>:"/\\|?*]/g;
271
+ // eslint-disable-next-line no-control-regex
313
272
  const reControlChars = /[\u0000-\u001f\u0080-\u009f]/g;
314
-
315
273
  function escapeLocalIdent(localident) {
316
274
  // TODO simplify in the next major release
317
- return escape(localident // For `[hash]` placeholder
275
+ return escape(localident
276
+ // For `[hash]` placeholder
318
277
  .replace(/^((-?[0-9])|--)/, "_$1").replace(filenameReservedRegex, "-").replace(reControlChars, "-").replace(/\./g, "-"));
319
278
  }
320
-
321
279
  function defaultGetLocalIdent(loaderContext, localIdentName, localName, options) {
322
280
  const {
323
281
  context,
@@ -327,8 +285,16 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
327
285
  const {
328
286
  resourcePath
329
287
  } = loaderContext;
330
- const relativeResourcePath = normalizePath(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
288
+ let relativeResourcePath = normalizePath(_path.default.relative(context, resourcePath));
331
289
 
290
+ // eslint-disable-next-line no-underscore-dangle
291
+ if (loaderContext._module && loaderContext._module.matchResource) {
292
+ relativeResourcePath = `${normalizePath(
293
+ // eslint-disable-next-line no-underscore-dangle
294
+ _path.default.relative(context, loaderContext._module.matchResource))}`;
295
+ }
296
+
297
+ // eslint-disable-next-line no-param-reassign
332
298
  options.content = hashStrategy === "minimal-subset" && /\[local\]/.test(localIdentName) ? relativeResourcePath : `${relativeResourcePath}\x00${localName}`;
333
299
  let {
334
300
  hashFunction,
@@ -336,45 +302,44 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
336
302
  hashDigestLength
337
303
  } = options;
338
304
  const matches = localIdentName.match(/\[(?:([^:\]]+):)?(?:(hash|contenthash|fullhash))(?::([a-z]+\d*))?(?::(\d+))?\]/i);
339
-
340
305
  if (matches) {
341
306
  const hashName = matches[2] || hashFunction;
342
307
  hashFunction = matches[1] || hashFunction;
343
308
  hashDigest = matches[3] || hashDigest;
344
- hashDigestLength = matches[4] || hashDigestLength; // `hash` and `contenthash` are same in `loader-utils` context
309
+ hashDigestLength = matches[4] || hashDigestLength;
310
+
311
+ // `hash` and `contenthash` are same in `loader-utils` context
345
312
  // let's keep `hash` for backward compatibility
346
- // eslint-disable-next-line no-param-reassign
347
313
 
314
+ // eslint-disable-next-line no-param-reassign
348
315
  localIdentName = localIdentName.replace(/\[(?:([^:\]]+):)?(?:hash|contenthash|fullhash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi, () => hashName === "fullhash" ? "[fullhash]" : "[contenthash]");
349
316
  }
350
-
351
317
  let localIdentHash = "";
352
-
353
318
  for (let tier = 0; localIdentHash.length < hashDigestLength; tier++) {
354
319
  // TODO remove this in the next major release
355
- const hash = loaderContext.utils && typeof loaderContext.utils.createHash === "function" ? loaderContext.utils.createHash(hashFunction) : // eslint-disable-next-line no-underscore-dangle
320
+ const hash = loaderContext.utils && typeof loaderContext.utils.createHash === "function" ? loaderContext.utils.createHash(hashFunction) :
321
+ // eslint-disable-next-line no-underscore-dangle
356
322
  loaderContext._compiler.webpack.util.createHash(hashFunction);
357
-
358
323
  if (hashSalt) {
359
324
  hash.update(hashSalt);
360
325
  }
361
-
362
326
  const tierSalt = Buffer.allocUnsafe(4);
363
327
  tierSalt.writeUInt32LE(tier);
364
- hash.update(tierSalt); // TODO: bug in webpack with unicode characters with strings
365
-
328
+ hash.update(tierSalt);
329
+ // TODO: bug in webpack with unicode characters with strings
366
330
  hash.update(Buffer.from(options.content, "utf8"));
367
- localIdentHash = (localIdentHash + hash.digest(hashDigest) // Remove all leading digits
368
- ).replace(/^\d+/, "") // Replace all slashes with underscores (same as in base64url)
369
- .replace(/\//g, "_") // Remove everything that is not an alphanumeric or underscore
331
+ localIdentHash = (localIdentHash + hash.digest(hashDigest)
332
+ // Remove all leading digits
333
+ ).replace(/^\d+/, "")
334
+ // Replace all slashes with underscores (same as in base64url)
335
+ .replace(/\//g, "_")
336
+ // Remove everything that is not an alphanumeric or underscore
370
337
  .replace(/[^A-Za-z0-9_]+/g, "").slice(0, hashDigestLength);
371
- } // TODO need improve on webpack side, we should allow to pass hash/contentHash without chunk property, also `data` for `getPath` should be looks good without chunk property
372
-
338
+ }
373
339
 
340
+ // TODO need improve on webpack side, we should allow to pass hash/contentHash without chunk property, also `data` for `getPath` should be looks good without chunk property
374
341
  const ext = _path.default.extname(resourcePath);
375
-
376
342
  const base = _path.default.basename(resourcePath);
377
-
378
343
  const name = base.slice(0, base.length - ext.length);
379
344
  const data = {
380
345
  filename: _path.default.relative(context, resourcePath),
@@ -384,131 +349,105 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
384
349
  hash: localIdentHash,
385
350
  contentHash: localIdentHash
386
351
  }
387
- }; // eslint-disable-next-line no-underscore-dangle
352
+ };
388
353
 
354
+ // eslint-disable-next-line no-underscore-dangle
389
355
  let result = loaderContext._compilation.getPath(localIdentName, data);
390
-
391
356
  if (/\[folder\]/gi.test(result)) {
392
357
  const dirname = _path.default.dirname(resourcePath);
393
-
394
358
  let directory = normalizePath(_path.default.relative(context, `${dirname + _path.default.sep}_`));
395
- directory = directory.substr(0, directory.length - 1);
359
+ directory = directory.substring(0, directory.length - 1);
396
360
  let folder = "";
397
-
398
361
  if (directory.length > 1) {
399
362
  folder = _path.default.basename(directory);
400
363
  }
401
-
402
364
  result = result.replace(/\[folder\]/gi, () => folder);
403
365
  }
404
-
405
366
  if (options.regExp) {
406
367
  const match = resourcePath.match(options.regExp);
407
-
408
368
  if (match) {
409
369
  match.forEach((matched, i) => {
410
370
  result = result.replace(new RegExp(`\\[${i}\\]`, "ig"), matched);
411
371
  });
412
372
  }
413
373
  }
414
-
415
374
  return result;
416
375
  }
417
-
418
376
  function fixedEncodeURIComponent(str) {
419
377
  return str.replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16)}`);
420
378
  }
421
-
422
379
  function isDataUrl(url) {
423
380
  if (/^data:/i.test(url)) {
424
381
  return true;
425
382
  }
426
-
427
383
  return false;
428
384
  }
429
-
430
385
  const NATIVE_WIN32_PATH = /^[A-Z]:[/\\]|^\\\\/i;
431
-
432
386
  function normalizeUrl(url, isStringValue) {
433
387
  let normalizedUrl = url.replace(/^( |\t\n|\r\n|\r|\f)*/g, "").replace(/( |\t\n|\r\n|\r|\f)*$/g, "");
434
-
435
388
  if (isStringValue && /\\(\n|\r\n|\r|\f)/.test(normalizedUrl)) {
436
389
  normalizedUrl = normalizedUrl.replace(/\\(\n|\r\n|\r|\f)/g, "");
437
390
  }
438
-
439
391
  if (NATIVE_WIN32_PATH.test(url)) {
440
392
  try {
441
393
  normalizedUrl = decodeURI(normalizedUrl);
442
- } catch (error) {// Ignore
394
+ } catch (error) {
395
+ // Ignore
443
396
  }
444
-
445
397
  return normalizedUrl;
446
398
  }
447
-
448
399
  normalizedUrl = unescape(normalizedUrl);
449
-
450
400
  if (isDataUrl(url)) {
451
401
  // Todo fixedEncodeURIComponent is workaround. Webpack resolver shouldn't handle "!" in dataURL
452
402
  return fixedEncodeURIComponent(normalizedUrl);
453
403
  }
454
-
455
404
  try {
456
405
  normalizedUrl = decodeURI(normalizedUrl);
457
- } catch (error) {// Ignore
406
+ } catch (error) {
407
+ // Ignore
458
408
  }
459
-
460
409
  return normalizedUrl;
461
410
  }
462
-
463
411
  function requestify(url, rootContext, needToResolveURL = true) {
464
412
  if (needToResolveURL) {
465
413
  if (/^file:/i.test(url)) {
466
414
  return (0, _url.fileURLToPath)(url);
467
415
  }
468
-
469
416
  return url.charAt(0) === "/" ? urlToRequest(url, rootContext) : urlToRequest(url);
470
417
  }
471
-
472
418
  if (url.charAt(0) === "/" || /^file:/i.test(url)) {
473
419
  return url;
474
- } // A `~` makes the url an module
475
-
420
+ }
476
421
 
422
+ // A `~` makes the url an module
477
423
  if (IS_MODULE_REQUEST.test(url)) {
478
424
  return url.replace(IS_MODULE_REQUEST, "");
479
425
  }
480
-
481
426
  return url;
482
427
  }
483
-
484
428
  function getFilter(filter, resourcePath) {
485
429
  return (...args) => {
486
430
  if (typeof filter === "function") {
487
431
  return filter(...args, resourcePath);
488
432
  }
489
-
490
433
  return true;
491
434
  };
492
435
  }
493
-
494
436
  function getValidLocalName(localName, exportLocalsConvention) {
495
437
  const result = exportLocalsConvention(localName);
496
438
  return Array.isArray(result) ? result[0] : result;
497
439
  }
498
-
499
440
  const IS_MODULES = /\.module(s)?\.\w+$/i;
500
441
  const IS_ICSS = /\.icss\.\w+$/i;
501
-
502
442
  function getModulesOptions(rawOptions, exportType, loaderContext) {
503
443
  if (typeof rawOptions.modules === "boolean" && rawOptions.modules === false) {
504
444
  return false;
505
445
  }
506
-
507
- const resourcePath = // eslint-disable-next-line no-underscore-dangle
446
+ const resourcePath =
447
+ // eslint-disable-next-line no-underscore-dangle
508
448
  loaderContext._module && loaderContext._module.matchResource || loaderContext.resourcePath;
509
449
  let auto;
510
450
  let rawModulesOptions;
511
-
512
451
  if (typeof rawOptions.modules === "undefined") {
513
452
  rawModulesOptions = {};
514
453
  auto = true;
@@ -523,9 +462,9 @@ function getModulesOptions(rawOptions, exportType, loaderContext) {
523
462
  ({
524
463
  auto
525
464
  } = rawModulesOptions);
526
- } // eslint-disable-next-line no-underscore-dangle
527
-
465
+ }
528
466
 
467
+ // eslint-disable-next-line no-underscore-dangle
529
468
  const {
530
469
  outputOptions
531
470
  } = loaderContext._compilation;
@@ -550,95 +489,76 @@ function getModulesOptions(rawOptions, exportType, loaderContext) {
550
489
  ...rawModulesOptions
551
490
  };
552
491
  let exportLocalsConventionType;
553
-
554
492
  if (typeof modulesOptions.exportLocalsConvention === "string") {
555
493
  exportLocalsConventionType = modulesOptions.exportLocalsConvention;
556
-
557
494
  modulesOptions.exportLocalsConvention = name => {
558
495
  switch (exportLocalsConventionType) {
559
496
  case "camelCase":
560
497
  {
561
498
  return [name, camelCase(name)];
562
499
  }
563
-
564
500
  case "camelCaseOnly":
565
501
  {
566
502
  return camelCase(name);
567
503
  }
568
-
569
504
  case "dashes":
570
505
  {
571
506
  return [name, dashesCamelCase(name)];
572
507
  }
573
-
574
508
  case "dashesOnly":
575
509
  {
576
510
  return dashesCamelCase(name);
577
511
  }
578
-
579
512
  case "asIs":
580
513
  default:
581
514
  return name;
582
515
  }
583
516
  };
584
517
  }
585
-
586
518
  if (typeof modulesOptions.auto === "boolean") {
587
519
  const isModules = modulesOptions.auto && IS_MODULES.test(resourcePath);
588
520
  let isIcss;
589
-
590
521
  if (!isModules) {
591
522
  isIcss = IS_ICSS.test(resourcePath);
592
-
593
523
  if (isIcss) {
594
524
  modulesOptions.mode = "icss";
595
525
  }
596
526
  }
597
-
598
527
  if (!isModules && !isIcss) {
599
528
  return false;
600
529
  }
601
530
  } else if (modulesOptions.auto instanceof RegExp) {
602
531
  const isModules = modulesOptions.auto.test(resourcePath);
603
-
604
532
  if (!isModules) {
605
533
  return false;
606
534
  }
607
535
  } else if (typeof modulesOptions.auto === "function") {
608
536
  const isModule = modulesOptions.auto(resourcePath);
609
-
610
537
  if (!isModule) {
611
538
  return false;
612
539
  }
613
540
  }
614
-
615
541
  if (typeof modulesOptions.mode === "function") {
616
542
  modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath);
617
543
  }
618
-
619
544
  if (needNamedExport) {
620
545
  if (rawOptions.esModule === false) {
621
546
  throw new Error("The 'exportType' option with the 'css-style-sheet' or 'string' value requires the 'esModules' option to be enabled");
622
547
  }
623
-
624
548
  if (modulesOptions.namedExport === false) {
625
549
  throw new Error("The 'exportType' option with the 'css-style-sheet' or 'string' value requires the 'modules.namedExport' option to be enabled");
626
550
  }
627
551
  }
628
-
629
552
  if (modulesOptions.namedExport === true) {
630
553
  if (rawOptions.esModule === false) {
631
554
  throw new Error("The 'modules.namedExport' option requires the 'esModules' option to be enabled");
632
555
  }
633
-
634
556
  if (typeof exportLocalsConventionType === "string" && exportLocalsConventionType !== "camelCaseOnly" && exportLocalsConventionType !== "dashesOnly") {
635
557
  throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly" or "dashesOnly"');
636
558
  }
637
559
  }
638
-
639
560
  return modulesOptions;
640
561
  }
641
-
642
562
  function normalizeOptions(rawOptions, loaderContext) {
643
563
  const exportType = typeof rawOptions.exportType === "undefined" ? "array" : rawOptions.exportType;
644
564
  const modulesOptions = getModulesOptions(rawOptions, exportType, loaderContext);
@@ -652,43 +572,33 @@ function normalizeOptions(rawOptions, loaderContext) {
652
572
  exportType
653
573
  };
654
574
  }
655
-
656
575
  function shouldUseImportPlugin(options) {
657
576
  if (options.modules.exportOnlyLocals) {
658
577
  return false;
659
578
  }
660
-
661
579
  if (typeof options.import === "boolean") {
662
580
  return options.import;
663
581
  }
664
-
665
582
  return true;
666
583
  }
667
-
668
584
  function shouldUseURLPlugin(options) {
669
585
  if (options.modules.exportOnlyLocals) {
670
586
  return false;
671
587
  }
672
-
673
588
  if (typeof options.url === "boolean") {
674
589
  return options.url;
675
590
  }
676
-
677
591
  return true;
678
592
  }
679
-
680
593
  function shouldUseModulesPlugins(options) {
681
594
  if (typeof options.modules === "boolean" && options.modules === false) {
682
595
  return false;
683
596
  }
684
-
685
597
  return options.modules.mode !== "icss";
686
598
  }
687
-
688
599
  function shouldUseIcssPlugin(options) {
689
600
  return Boolean(options.modules);
690
601
  }
691
-
692
602
  function getModulesPlugins(options, loaderContext) {
693
603
  const {
694
604
  mode,
@@ -703,14 +613,12 @@ function getModulesPlugins(options, loaderContext) {
703
613
  hashStrategy
704
614
  } = options.modules;
705
615
  let plugins = [];
706
-
707
616
  try {
708
617
  plugins = [_postcssModulesValues.default, (0, _postcssModulesLocalByDefault.default)({
709
618
  mode
710
619
  }), (0, _postcssModulesExtractImports.default)(), (0, _postcssModulesScope.default)({
711
620
  generateScopedName(exportName) {
712
621
  let localIdent;
713
-
714
622
  if (typeof getLocalIdent !== "undefined") {
715
623
  localIdent = getLocalIdent(loaderContext, localIdentName, unescape(exportName), {
716
624
  context: localIdentContext,
@@ -721,10 +629,10 @@ function getModulesPlugins(options, loaderContext) {
721
629
  hashStrategy,
722
630
  regExp: localIdentRegExp
723
631
  });
724
- } // A null/undefined value signals that we should invoke the default
725
- // getLocalIdent method.
726
-
632
+ }
727
633
 
634
+ // A null/undefined value signals that we should invoke the default
635
+ // getLocalIdent method.
728
636
  if (typeof localIdent === "undefined" || localIdent === null) {
729
637
  localIdent = defaultGetLocalIdent(loaderContext, localIdentName, unescape(exportName), {
730
638
  context: localIdentContext,
@@ -737,51 +645,41 @@ function getModulesPlugins(options, loaderContext) {
737
645
  });
738
646
  return escapeLocalIdent(localIdent).replace(/\\\[local\\]/gi, exportName);
739
647
  }
740
-
741
648
  return escapeLocalIdent(localIdent);
742
649
  },
743
-
744
650
  exportGlobals: options.modules.exportGlobals
745
651
  })];
746
652
  } catch (error) {
747
653
  loaderContext.emitError(error);
748
654
  }
749
-
750
655
  return plugins;
751
656
  }
752
-
753
657
  const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;
754
-
755
658
  function getURLType(source) {
756
659
  if (source[0] === "/") {
757
660
  if (source[1] === "/") {
758
661
  return "scheme-relative";
759
662
  }
760
-
761
663
  return "path-absolute";
762
664
  }
763
-
764
665
  if (IS_NATIVE_WIN32_PATH.test(source)) {
765
666
  return "path-absolute";
766
667
  }
767
-
768
668
  return ABSOLUTE_SCHEME.test(source) ? "absolute" : "path-relative";
769
669
  }
770
-
771
670
  function normalizeSourceMap(map, resourcePath) {
772
- let newMap = map; // Some loader emit source map as string
773
- // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
671
+ let newMap = map;
774
672
 
673
+ // Some loader emit source map as string
674
+ // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
775
675
  if (typeof newMap === "string") {
776
676
  newMap = JSON.parse(newMap);
777
677
  }
778
-
779
678
  delete newMap.file;
780
679
  const {
781
680
  sourceRoot
782
681
  } = newMap;
783
682
  delete newMap.sourceRoot;
784
-
785
683
  if (newMap.sources) {
786
684
  // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
787
685
  // We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
@@ -790,21 +688,18 @@ function normalizeSourceMap(map, resourcePath) {
790
688
  if (source.indexOf("<") === 0) {
791
689
  return source;
792
690
  }
691
+ const sourceType = getURLType(source);
793
692
 
794
- const sourceType = getURLType(source); // Do no touch `scheme-relative` and `absolute` URLs
795
-
693
+ // Do no touch `scheme-relative` and `absolute` URLs
796
694
  if (sourceType === "path-relative" || sourceType === "path-absolute") {
797
695
  const absoluteSource = sourceType === "path-relative" && sourceRoot ? _path.default.resolve(sourceRoot, normalizePath(source)) : normalizePath(source);
798
696
  return _path.default.relative(_path.default.dirname(resourcePath), absoluteSource);
799
697
  }
800
-
801
698
  return source;
802
699
  });
803
700
  }
804
-
805
701
  return newMap;
806
702
  }
807
-
808
703
  function getPreRequester({
809
704
  loaders,
810
705
  loaderIndex
@@ -814,21 +709,17 @@ function getPreRequester({
814
709
  if (cache[number]) {
815
710
  return cache[number];
816
711
  }
817
-
818
712
  if (number === false) {
819
713
  cache[number] = "";
820
714
  } else {
821
715
  const loadersRequest = loaders.slice(loaderIndex, loaderIndex + 1 + (typeof number !== "number" ? 0 : number)).map(x => x.request).join("!");
822
716
  cache[number] = `-!${loadersRequest}!`;
823
717
  }
824
-
825
718
  return cache[number];
826
719
  };
827
720
  }
828
-
829
721
  function getImportCode(imports, options) {
830
722
  let code = "";
831
-
832
723
  for (const item of imports) {
833
724
  const {
834
725
  importName,
@@ -836,7 +727,6 @@ function getImportCode(imports, options) {
836
727
  icss,
837
728
  type
838
729
  } = item;
839
-
840
730
  if (options.esModule) {
841
731
  if (icss && options.modules.namedExport) {
842
732
  code += `import ${options.modules.exportOnlyLocals ? "" : `${importName}, `}* as ${importName}_NAMED___ from ${url};\n`;
@@ -847,90 +737,70 @@ function getImportCode(imports, options) {
847
737
  code += `var ${importName} = require(${url});\n`;
848
738
  }
849
739
  }
850
-
851
740
  return code ? `// Imports\n${code}` : "";
852
741
  }
853
-
854
742
  function normalizeSourceMapForRuntime(map, loaderContext) {
855
743
  const resultMap = map ? map.toJSON() : null;
856
-
857
744
  if (resultMap) {
858
745
  delete resultMap.file;
859
- /* eslint-disable no-underscore-dangle */
860
746
 
747
+ /* eslint-disable no-underscore-dangle */
861
748
  if (loaderContext._compilation && loaderContext._compilation.options && loaderContext._compilation.options.devtool && loaderContext._compilation.options.devtool.includes("nosources")) {
862
749
  /* eslint-enable no-underscore-dangle */
750
+
863
751
  delete resultMap.sourcesContent;
864
752
  }
865
-
866
753
  resultMap.sourceRoot = "";
867
754
  resultMap.sources = resultMap.sources.map(source => {
868
755
  // Non-standard syntax from `postcss`
869
756
  if (source.indexOf("<") === 0) {
870
757
  return source;
871
758
  }
872
-
873
759
  const sourceType = getURLType(source);
874
-
875
760
  if (sourceType !== "path-relative") {
876
761
  return source;
877
762
  }
878
-
879
763
  const resourceDirname = _path.default.dirname(loaderContext.resourcePath);
880
-
881
764
  const absoluteSource = _path.default.resolve(resourceDirname, source);
882
-
883
765
  const contextifyPath = normalizePath(_path.default.relative(loaderContext.rootContext, absoluteSource));
884
766
  return `webpack://./${contextifyPath}`;
885
767
  });
886
768
  }
887
-
888
769
  return JSON.stringify(resultMap);
889
770
  }
890
-
891
771
  function printParams(media, dedupe, supports, layer) {
892
772
  let result = "";
893
-
894
773
  if (typeof layer !== "undefined") {
895
774
  result = `, ${JSON.stringify(layer)}`;
896
775
  }
897
-
898
776
  if (typeof supports !== "undefined") {
899
777
  result = `, ${JSON.stringify(supports)}${result}`;
900
778
  } else if (result.length > 0) {
901
779
  result = `, undefined${result}`;
902
780
  }
903
-
904
781
  if (dedupe) {
905
782
  result = `, true${result}`;
906
783
  } else if (result.length > 0) {
907
784
  result = `, false${result}`;
908
785
  }
909
-
910
786
  if (media) {
911
787
  result = `${JSON.stringify(media)}${result}`;
912
788
  } else if (result.length > 0) {
913
789
  result = `""${result}`;
914
790
  }
915
-
916
791
  return result;
917
792
  }
918
-
919
793
  function getModuleCode(result, api, replacements, options, loaderContext) {
920
794
  if (options.modules.exportOnlyLocals === true) {
921
795
  return "";
922
796
  }
923
-
924
797
  let sourceMapValue = "";
925
-
926
798
  if (options.sourceMap) {
927
799
  const sourceMap = result.map;
928
800
  sourceMapValue = `,${normalizeSourceMapForRuntime(sourceMap, loaderContext)}`;
929
801
  }
930
-
931
802
  let code = JSON.stringify(result.css);
932
803
  let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap ? "___CSS_LOADER_API_SOURCEMAP_IMPORT___" : "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___"});\n`;
933
-
934
804
  for (const item of api) {
935
805
  const {
936
806
  url,
@@ -939,7 +809,6 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
939
809
  media,
940
810
  dedupe
941
811
  } = item;
942
-
943
812
  if (url) {
944
813
  // eslint-disable-next-line no-undefined
945
814
  const printedParam = printParams(media, undefined, supports, layer);
@@ -949,14 +818,12 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
949
818
  beforeCode += `___CSS_LOADER_EXPORT___.i(${item.importName}${printedParam.length > 0 ? `, ${printedParam}` : ""});\n`;
950
819
  }
951
820
  }
952
-
953
821
  for (const item of replacements) {
954
822
  const {
955
823
  replacementName,
956
824
  importName,
957
825
  localName
958
826
  } = item;
959
-
960
827
  if (localName) {
961
828
  code = code.replace(new RegExp(replacementName, "g"), () => options.modules.namedExport ? `" + ${importName}_NAMED___[${JSON.stringify(getValidLocalName(localName, options.modules.exportLocalsConvention))}] + "` : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`);
962
829
  } else {
@@ -969,31 +836,26 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
969
836
  beforeCode += `var ${replacementName} = ___CSS_LOADER_GET_URL_IMPORT___(${importName}${preparedOptions});\n`;
970
837
  code = code.replace(new RegExp(replacementName, "g"), () => `" + ${replacementName} + "`);
971
838
  }
972
- } // Indexes description:
839
+ }
840
+
841
+ // Indexes description:
973
842
  // 0 - module id
974
843
  // 1 - CSS code
975
844
  // 2 - media
976
845
  // 3 - source map
977
846
  // 4 - supports
978
847
  // 5 - layer
979
-
980
-
981
848
  return `${beforeCode}// Module\n___CSS_LOADER_EXPORT___.push([module.id, ${code}, ""${sourceMapValue}]);\n`;
982
849
  }
983
-
984
850
  function dashesCamelCase(str) {
985
851
  return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
986
852
  }
987
-
988
853
  function getExportCode(exports, replacements, icssPluginUsed, options) {
989
854
  let code = "// Exports\n";
990
-
991
855
  if (icssPluginUsed) {
992
856
  let localsCode = "";
993
-
994
857
  const addExportToLocalsCode = (names, value) => {
995
858
  const normalizedNames = Array.isArray(names) ? new Set(names) : new Set([names]);
996
-
997
859
  for (const name of normalizedNames) {
998
860
  if (options.modules.namedExport) {
999
861
  localsCode += `export var ${name} = ${JSON.stringify(value)};\n`;
@@ -1001,25 +863,21 @@ function getExportCode(exports, replacements, icssPluginUsed, options) {
1001
863
  if (localsCode) {
1002
864
  localsCode += `,\n`;
1003
865
  }
1004
-
1005
866
  localsCode += `\t${JSON.stringify(name)}: ${JSON.stringify(value)}`;
1006
867
  }
1007
868
  }
1008
869
  };
1009
-
1010
870
  for (const {
1011
871
  name,
1012
872
  value
1013
873
  } of exports) {
1014
874
  addExportToLocalsCode(options.modules.exportLocalsConvention(name), value);
1015
875
  }
1016
-
1017
876
  for (const item of replacements) {
1018
877
  const {
1019
878
  replacementName,
1020
879
  localName
1021
880
  } = item;
1022
-
1023
881
  if (localName) {
1024
882
  const {
1025
883
  importName
@@ -1030,62 +888,48 @@ function getExportCode(exports, replacements, icssPluginUsed, options) {
1030
888
  } else if (options.modules.exportOnlyLocals) {
1031
889
  return `" + ${importName}[${JSON.stringify(localName)}] + "`;
1032
890
  }
1033
-
1034
891
  return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
1035
892
  });
1036
893
  } else {
1037
894
  localsCode = localsCode.replace(new RegExp(replacementName, "g"), () => `" + ${replacementName} + "`);
1038
895
  }
1039
896
  }
1040
-
1041
897
  if (options.modules.exportOnlyLocals) {
1042
898
  code += options.modules.namedExport ? localsCode : `${options.esModule ? "export default" : "module.exports ="} {\n${localsCode}\n};\n`;
1043
899
  return code;
1044
900
  }
1045
-
1046
901
  code += options.modules.namedExport ? localsCode : `___CSS_LOADER_EXPORT___.locals = {${localsCode ? `\n${localsCode}\n` : ""}};\n`;
1047
902
  }
1048
-
1049
903
  const isCSSStyleSheetExport = options.exportType === "css-style-sheet";
1050
-
1051
904
  if (isCSSStyleSheetExport) {
1052
905
  code += "var ___CSS_LOADER_STYLE_SHEET___ = new CSSStyleSheet();\n";
1053
906
  code += "___CSS_LOADER_STYLE_SHEET___.replaceSync(___CSS_LOADER_EXPORT___.toString());\n";
1054
907
  }
1055
-
1056
908
  let finalExport;
1057
-
1058
909
  switch (options.exportType) {
1059
910
  case "string":
1060
911
  finalExport = "___CSS_LOADER_EXPORT___.toString()";
1061
912
  break;
1062
-
1063
913
  case "css-style-sheet":
1064
914
  finalExport = "___CSS_LOADER_STYLE_SHEET___";
1065
915
  break;
1066
-
1067
916
  default:
1068
917
  case "array":
1069
918
  finalExport = "___CSS_LOADER_EXPORT___";
1070
919
  break;
1071
920
  }
1072
-
1073
921
  code += `${options.esModule ? "export default" : "module.exports ="} ${finalExport};\n`;
1074
922
  return code;
1075
923
  }
1076
-
1077
924
  async function resolveRequests(resolve, context, possibleRequests) {
1078
925
  return resolve(context, possibleRequests[0]).then(result => result).catch(error => {
1079
926
  const [, ...tailPossibleRequests] = possibleRequests;
1080
-
1081
927
  if (tailPossibleRequests.length === 0) {
1082
928
  throw error;
1083
929
  }
1084
-
1085
930
  return resolveRequests(resolve, context, tailPossibleRequests);
1086
931
  });
1087
932
  }
1088
-
1089
933
  function isURLRequestable(url, options = {}) {
1090
934
  // Protocol-relative URLs
1091
935
  if (/^\/\//.test(url)) {
@@ -1093,17 +937,17 @@ function isURLRequestable(url, options = {}) {
1093
937
  requestable: false,
1094
938
  needResolve: false
1095
939
  };
1096
- } // `#` URLs
1097
-
940
+ }
1098
941
 
942
+ // `#` URLs
1099
943
  if (/^#/.test(url)) {
1100
944
  return {
1101
945
  requestable: false,
1102
946
  needResolve: false
1103
947
  };
1104
- } // Data URI
1105
-
948
+ }
1106
949
 
950
+ // Data URI
1107
951
  if (isDataUrl(url) && options.isSupportDataURL) {
1108
952
  try {
1109
953
  decodeURIComponent(url);
@@ -1113,22 +957,21 @@ function isURLRequestable(url, options = {}) {
1113
957
  needResolve: false
1114
958
  };
1115
959
  }
1116
-
1117
960
  return {
1118
961
  requestable: true,
1119
962
  needResolve: false
1120
963
  };
1121
- } // `file:` protocol
1122
-
964
+ }
1123
965
 
966
+ // `file:` protocol
1124
967
  if (/^file:/i.test(url)) {
1125
968
  return {
1126
969
  requestable: true,
1127
970
  needResolve: true
1128
971
  };
1129
- } // Absolute URLs
1130
-
972
+ }
1131
973
 
974
+ // Absolute URLs
1132
975
  if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !NATIVE_WIN32_PATH.test(url)) {
1133
976
  if (options.isSupportAbsoluteURL && /^https?:/i.test(url)) {
1134
977
  return {
@@ -1136,23 +979,19 @@ function isURLRequestable(url, options = {}) {
1136
979
  needResolve: false
1137
980
  };
1138
981
  }
1139
-
1140
982
  return {
1141
983
  requestable: false,
1142
984
  needResolve: false
1143
985
  };
1144
986
  }
1145
-
1146
987
  return {
1147
988
  requestable: true,
1148
989
  needResolve: true
1149
990
  };
1150
991
  }
1151
-
1152
992
  function sort(a, b) {
1153
993
  return a.index - b.index;
1154
994
  }
1155
-
1156
995
  function combineRequests(preRequest, url) {
1157
996
  const idx = url.indexOf("!=!");
1158
997
  return idx !== -1 ? url.slice(0, idx + 3) + preRequest + url.slice(idx + 3) : preRequest + url;