css-loader 4.2.0 → 5.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/dist/utils.js CHANGED
@@ -28,8 +28,6 @@ var _path = _interopRequireDefault(require("path"));
28
28
 
29
29
  var _loaderUtils = require("loader-utils");
30
30
 
31
- var _normalizePath = _interopRequireDefault(require("normalize-path"));
32
-
33
31
  var _cssesc = _interopRequireDefault(require("cssesc"));
34
32
 
35
33
  var _postcssModulesValues = _interopRequireDefault(require("postcss-modules-values"));
@@ -66,6 +64,10 @@ function unescape(str) {
66
64
  String.fromCharCode(high >> 10 | 0xd800, high & 0x3ff | 0xdc00);
67
65
  /* eslint-enable line-comment-position */
68
66
  });
67
+ }
68
+
69
+ function normalizePath(file) {
70
+ return _path.default.sep === '\\' ? file.replace(/\\/g, '/') : file;
69
71
  } // eslint-disable-next-line no-control-regex
70
72
 
71
73
 
@@ -73,6 +75,13 @@ const filenameReservedRegex = /[<>:"/\\|?*]/g; // eslint-disable-next-line no-co
73
75
 
74
76
  const reControlChars = /[\u0000-\u001f\u0080-\u009f]/g;
75
77
 
78
+ function escapeLocalident(localident) {
79
+ return (0, _cssesc.default)(localident // For `[hash]` placeholder
80
+ .replace(/^((-?[0-9])|--)/, '_$1').replace(filenameReservedRegex, '-').replace(reControlChars, '-').replace(/\./g, '-'), {
81
+ isIdentifier: true
82
+ });
83
+ }
84
+
76
85
  function defaultGetLocalIdent(loaderContext, localIdentName, localName, options) {
77
86
  const {
78
87
  context,
@@ -81,22 +90,17 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
81
90
  const {
82
91
  resourcePath
83
92
  } = loaderContext;
84
- const request = (0, _normalizePath.default)(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
85
-
86
- options.content = `${hashPrefix + request}\x00${unescape(localName)}`; // Using `[path]` placeholder outputs `/` we need escape their
87
- // Also directories can contains invalid characters for css we need escape their too
93
+ const request = normalizePath(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
88
94
 
89
- return (0, _cssesc.default)((0, _loaderUtils.interpolateName)(loaderContext, localIdentName, options) // For `[hash]` placeholder
90
- .replace(/^((-?[0-9])|--)/, '_$1').replace(filenameReservedRegex, '-').replace(reControlChars, '-').replace(/\./g, '-'), {
91
- isIdentifier: true
92
- }).replace(/\\\[local\\]/gi, localName);
95
+ options.content = `${hashPrefix + request}\x00${localName}`;
96
+ return (0, _loaderUtils.interpolateName)(loaderContext, localIdentName, options);
93
97
  }
94
98
 
95
99
  function normalizeUrl(url, isStringValue) {
96
100
  let normalizedUrl = url;
97
101
 
98
- if (isStringValue && /\\[\n]/.test(normalizedUrl)) {
99
- normalizedUrl = normalizedUrl.replace(/\\[\n]/g, '');
102
+ if (isStringValue && /\\(\n|\r\n|\r|\f)/.test(normalizedUrl)) {
103
+ normalizedUrl = normalizedUrl.replace(/\\(\n|\r\n|\r|\f)/g, '');
100
104
  }
101
105
 
102
106
  if (matchNativeWin32Path.test(url)) {
@@ -124,17 +128,31 @@ function getFilter(filter, resourcePath) {
124
128
  };
125
129
  }
126
130
 
127
- const moduleRegExp = /\.module\.\w+$/i;
131
+ function getValidLocalName(localName, exportLocalsConvention) {
132
+ if (exportLocalsConvention === 'dashesOnly') {
133
+ return dashesCamelCase(localName);
134
+ }
135
+
136
+ return (0, _camelcase.default)(localName);
137
+ }
138
+
139
+ const moduleRegExp = /\.module(s)?\.\w+$/i;
140
+ const icssRegExp = /\.icss\.\w+$/i;
128
141
 
129
142
  function getModulesOptions(rawOptions, loaderContext) {
130
143
  const {
131
144
  resourcePath
132
145
  } = loaderContext;
146
+ let isIcss;
133
147
 
134
148
  if (typeof rawOptions.modules === 'undefined') {
135
149
  const isModules = moduleRegExp.test(resourcePath);
136
150
 
137
151
  if (!isModules) {
152
+ isIcss = icssRegExp.test(resourcePath);
153
+ }
154
+
155
+ if (!isModules && !isIcss) {
138
156
  return false;
139
157
  }
140
158
  } else if (typeof rawOptions.modules === 'boolean' && rawOptions.modules === false) {
@@ -142,7 +160,7 @@ function getModulesOptions(rawOptions, loaderContext) {
142
160
  }
143
161
 
144
162
  let modulesOptions = {
145
- compileType: rawOptions.icss ? 'icss' : 'module',
163
+ compileType: isIcss ? 'icss' : 'module',
146
164
  auto: true,
147
165
  mode: 'local',
148
166
  exportGlobals: false,
@@ -151,7 +169,8 @@ function getModulesOptions(rawOptions, loaderContext) {
151
169
  localIdentHashPrefix: '',
152
170
  // eslint-disable-next-line no-undefined
153
171
  localIdentRegExp: undefined,
154
- getLocalIdent: defaultGetLocalIdent,
172
+ // eslint-disable-next-line no-undefined
173
+ getLocalIdent: undefined,
155
174
  namedExport: false,
156
175
  exportLocalsConvention: 'asIs',
157
176
  exportOnlyLocals: false
@@ -200,28 +219,26 @@ function getModulesOptions(rawOptions, loaderContext) {
200
219
  throw new Error('The "modules.namedExport" option requires the "esModules" option to be enabled');
201
220
  }
202
221
 
203
- if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly') {
204
- throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly"');
222
+ if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly' && modulesOptions.exportLocalsConvention !== 'dashesOnly') {
223
+ throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly" or "dashesOnly"');
205
224
  }
206
225
  }
207
226
 
227
+ if (/\[emoji(?::(\d+))?\]/i.test(modulesOptions.localIdentName)) {
228
+ loaderContext.emitWarning('Emoji is deprecated and will be removed in next major release.');
229
+ }
230
+
208
231
  return modulesOptions;
209
232
  }
210
233
 
211
234
  function normalizeOptions(rawOptions, loaderContext) {
212
- if (rawOptions.icss) {
213
- loaderContext.emitWarning(new Error('The "icss" option is deprecated, use "modules.compileType: "icss"" instead'));
214
- }
215
-
216
235
  const modulesOptions = getModulesOptions(rawOptions, loaderContext);
217
236
  return {
218
237
  url: typeof rawOptions.url === 'undefined' ? true : rawOptions.url,
219
238
  import: typeof rawOptions.import === 'undefined' ? true : rawOptions.import,
220
239
  modules: modulesOptions,
221
- // TODO remove in the next major release
222
- icss: typeof rawOptions.icss === 'undefined' ? false : rawOptions.icss,
223
240
  sourceMap: typeof rawOptions.sourceMap === 'boolean' ? rawOptions.sourceMap : loaderContext.sourceMap,
224
- importLoaders: rawOptions.importLoaders,
241
+ importLoaders: typeof rawOptions.importLoaders === 'string' ? parseInt(rawOptions.importLoaders, 10) : rawOptions.importLoaders,
225
242
  esModule: typeof rawOptions.esModule === 'undefined' ? true : rawOptions.esModule
226
243
  };
227
244
  }
@@ -274,11 +291,28 @@ function getModulesPlugins(options, loaderContext) {
274
291
  mode
275
292
  }), (0, _postcssModulesExtractImports.default)(), (0, _postcssModulesScope.default)({
276
293
  generateScopedName(exportName) {
277
- return getLocalIdent(loaderContext, localIdentName, exportName, {
278
- context: localIdentContext,
279
- hashPrefix: localIdentHashPrefix,
280
- regExp: localIdentRegExp
281
- });
294
+ let localIdent;
295
+
296
+ if (typeof getLocalIdent !== 'undefined') {
297
+ localIdent = getLocalIdent(loaderContext, localIdentName, unescape(exportName), {
298
+ context: localIdentContext,
299
+ hashPrefix: localIdentHashPrefix,
300
+ regExp: localIdentRegExp
301
+ });
302
+ } // A null/undefined value signals that we should invoke the default
303
+ // getLocalIdent method.
304
+
305
+
306
+ if (typeof localIdent === 'undefined' || localIdent === null) {
307
+ localIdent = defaultGetLocalIdent(loaderContext, localIdentName, unescape(exportName), {
308
+ context: localIdentContext,
309
+ hashPrefix: localIdentHashPrefix,
310
+ regExp: localIdentRegExp
311
+ });
312
+ return escapeLocalident(localIdent).replace(/\\\[local\\]/gi, exportName);
313
+ }
314
+
315
+ return escapeLocalident(localIdent);
282
316
  },
283
317
 
284
318
  exportGlobals: options.modules.exportGlobals
@@ -290,26 +324,57 @@ function getModulesPlugins(options, loaderContext) {
290
324
  return plugins;
291
325
  }
292
326
 
293
- function normalizeSourceMap(map) {
327
+ const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;
328
+ const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i;
329
+
330
+ function getURLType(source) {
331
+ if (source[0] === '/') {
332
+ if (source[1] === '/') {
333
+ return 'scheme-relative';
334
+ }
335
+
336
+ return 'path-absolute';
337
+ }
338
+
339
+ if (IS_NATIVE_WIN32_PATH.test(source)) {
340
+ return 'path-absolute';
341
+ }
342
+
343
+ return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative';
344
+ }
345
+
346
+ function normalizeSourceMap(map, resourcePath) {
294
347
  let newMap = map; // Some loader emit source map as string
295
348
  // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
296
349
 
297
350
  if (typeof newMap === 'string') {
298
351
  newMap = JSON.parse(newMap);
299
- } // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
300
- // We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
301
-
302
-
303
- if (newMap.file) {
304
- newMap.file = (0, _normalizePath.default)(newMap.file);
305
352
  }
306
353
 
307
- if (newMap.sourceRoot) {
308
- newMap.sourceRoot = (0, _normalizePath.default)(newMap.sourceRoot);
309
- }
354
+ delete newMap.file;
355
+ const {
356
+ sourceRoot
357
+ } = newMap;
358
+ delete newMap.sourceRoot;
310
359
 
311
360
  if (newMap.sources) {
312
- newMap.sources = newMap.sources.map(source => (0, _normalizePath.default)(source));
361
+ // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
362
+ // We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
363
+ newMap.sources = newMap.sources.map(source => {
364
+ // Non-standard syntax from `postcss`
365
+ if (source.indexOf('<') === 0) {
366
+ return source;
367
+ }
368
+
369
+ const sourceType = getURLType(source); // Do no touch `scheme-relative` and `absolute` URLs
370
+
371
+ if (sourceType === 'path-relative' || sourceType === 'path-absolute') {
372
+ const absoluteSource = sourceType === 'path-relative' && sourceRoot ? _path.default.resolve(sourceRoot, normalizePath(source)) : normalizePath(source);
373
+ return _path.default.relative(_path.default.dirname(resourcePath), absoluteSource);
374
+ }
375
+
376
+ return source;
377
+ });
313
378
  }
314
379
 
315
380
  return newMap;
@@ -345,24 +410,59 @@ function getImportCode(imports, options) {
345
410
  url,
346
411
  icss
347
412
  } = item;
348
- code += options.esModule ? icss && options.modules.namedExport ? `import ${importName}, * as ${importName}_NAMED___ from ${url};\n` : `import ${importName} from ${url};\n` : `var ${importName} = require(${url});\n`;
413
+
414
+ if (options.esModule) {
415
+ if (icss && options.modules.namedExport) {
416
+ code += `import ${options.modules.exportOnlyLocals ? '' : `${importName}, `}* as ${importName}_NAMED___ from ${url};\n`;
417
+ } else {
418
+ code += `import ${importName} from ${url};\n`;
419
+ }
420
+ } else {
421
+ code += `var ${importName} = require(${url});\n`;
422
+ }
349
423
  }
350
424
 
351
425
  return code ? `// Imports\n${code}` : '';
352
426
  }
353
427
 
354
- function getModuleCode(result, api, replacements, options) {
428
+ function normalizeSourceMapForRuntime(map, loaderContext) {
429
+ const resultMap = map ? map.toJSON() : null;
430
+
431
+ if (resultMap) {
432
+ delete resultMap.file;
433
+ resultMap.sourceRoot = '';
434
+ resultMap.sources = resultMap.sources.map(source => {
435
+ // Non-standard syntax from `postcss`
436
+ if (source.indexOf('<') === 0) {
437
+ return source;
438
+ }
439
+
440
+ const sourceType = getURLType(source);
441
+
442
+ if (sourceType !== 'path-relative') {
443
+ return source;
444
+ }
445
+
446
+ const resourceDirname = _path.default.dirname(loaderContext.resourcePath);
447
+
448
+ const absoluteSource = _path.default.resolve(resourceDirname, source);
449
+
450
+ const contextifyPath = normalizePath(_path.default.relative(loaderContext.rootContext, absoluteSource));
451
+ return `webpack://${contextifyPath}`;
452
+ });
453
+ }
454
+
455
+ return JSON.stringify(resultMap);
456
+ }
457
+
458
+ function getModuleCode(result, api, replacements, options, loaderContext) {
355
459
  if (options.modules.exportOnlyLocals === true) {
356
- return 'var ___CSS_LOADER_EXPORT___ = {};\n';
460
+ return '';
357
461
  }
358
462
 
359
- const {
360
- css,
361
- map
362
- } = result;
363
- const sourceMapValue = options.sourceMap && map ? `,${map}` : '';
364
- let code = JSON.stringify(css);
365
- let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap});\n`;
463
+ const sourceMapValue = options.sourceMap ? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}` : '';
464
+ let code = JSON.stringify(result.css);
465
+ let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap ? '___CSS_LOADER_API_SOURCEMAP_IMPORT___' : 'function(i){return i[1]}'});\n`;
366
466
 
367
467
  for (const item of api) {
368
468
  const {
@@ -381,7 +481,7 @@ function getModuleCode(result, api, replacements, options) {
381
481
  } = item;
382
482
 
383
483
  if (localName) {
384
- code = code.replace(new RegExp(replacementName, 'g'), () => options.modules.namedExport ? `" + ${importName}_NAMED___[${JSON.stringify((0, _camelcase.default)(localName))}] + "` : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`);
484
+ code = code.replace(new RegExp(replacementName, 'g'), () => options.modules.namedExport ? `" + ${importName}_NAMED___[${JSON.stringify(getValidLocalName(localName, options.modules.exportLocalsConvention))}] + "` : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`);
385
485
  } else {
386
486
  const {
387
487
  hash,
@@ -402,12 +502,12 @@ function dashesCamelCase(str) {
402
502
  }
403
503
 
404
504
  function getExportCode(exports, replacements, options) {
405
- let code = '';
505
+ let code = '// Exports\n';
406
506
  let localsCode = '';
407
507
 
408
508
  const addExportToLocalsCode = (name, value) => {
409
509
  if (options.modules.namedExport) {
410
- localsCode += `export const ${(0, _camelcase.default)(name)} = ${JSON.stringify(value)};\n`;
510
+ localsCode += `export const ${name} = ${JSON.stringify(value)};\n`;
411
511
  } else {
412
512
  if (localsCode) {
413
513
  localsCode += `,\n`;
@@ -475,18 +575,31 @@ function getExportCode(exports, replacements, options) {
475
575
  const {
476
576
  importName
477
577
  } = item;
478
- localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () => options.modules.namedExport ? `" + ${importName}_NAMED___[${JSON.stringify((0, _camelcase.default)(localName))}] + "` : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`);
578
+ localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () => {
579
+ if (options.modules.namedExport) {
580
+ return `" + ${importName}_NAMED___[${JSON.stringify(getValidLocalName(localName, options.modules.exportLocalsConvention))}] + "`;
581
+ } else if (options.modules.exportOnlyLocals) {
582
+ return `" + ${importName}[${JSON.stringify(localName)}] + "`;
583
+ }
584
+
585
+ return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
586
+ });
479
587
  } else {
480
588
  localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () => `" + ${replacementName} + "`);
481
589
  }
482
590
  }
483
591
 
592
+ if (options.modules.exportOnlyLocals) {
593
+ code += options.modules.namedExport ? localsCode : `${options.esModule ? 'export default' : 'module.exports ='} {\n${localsCode}\n};\n`;
594
+ return code;
595
+ }
596
+
484
597
  if (localsCode) {
485
- code += options.modules.namedExport ? `${localsCode}` : `___CSS_LOADER_EXPORT___.locals = {\n${localsCode}\n};\n`;
598
+ code += options.modules.namedExport ? localsCode : `___CSS_LOADER_EXPORT___.locals = {\n${localsCode}\n};\n`;
486
599
  }
487
600
 
488
601
  code += `${options.esModule ? 'export default' : 'module.exports ='} ___CSS_LOADER_EXPORT___;\n`;
489
- return `// Exports\n${code}`;
602
+ return code;
490
603
  }
491
604
 
492
605
  async function resolveRequests(resolve, context, possibleRequests) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-loader",
3
- "version": "4.2.0",
3
+ "version": "5.0.0",
4
4
  "description": "css loader module for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/css-loader",
@@ -43,53 +43,56 @@
43
43
  "webpack": "^4.27.0 || ^5.0.0"
44
44
  },
45
45
  "dependencies": {
46
- "camelcase": "^6.0.0",
46
+ "camelcase": "^6.1.0",
47
47
  "cssesc": "^3.0.0",
48
- "icss-utils": "^4.1.1",
48
+ "icss-utils": "^5.0.0",
49
49
  "loader-utils": "^2.0.0",
50
- "normalize-path": "^3.0.0",
51
- "postcss": "^7.0.32",
52
- "postcss-modules-extract-imports": "^2.0.0",
53
- "postcss-modules-local-by-default": "^3.0.3",
54
- "postcss-modules-scope": "^2.2.0",
55
- "postcss-modules-values": "^3.0.0",
50
+ "postcss": "^8.1.1",
51
+ "postcss-modules-extract-imports": "^3.0.0",
52
+ "postcss-modules-local-by-default": "^4.0.0",
53
+ "postcss-modules-scope": "^3.0.0",
54
+ "postcss-modules-values": "^4.0.0",
56
55
  "postcss-value-parser": "^4.1.0",
57
- "schema-utils": "^2.7.0",
56
+ "schema-utils": "^3.0.0",
58
57
  "semver": "^7.3.2"
59
58
  },
60
59
  "devDependencies": {
61
- "@babel/cli": "^7.10.5",
62
- "@babel/core": "^7.10.5",
63
- "@babel/preset-env": "^7.10.4",
64
- "@commitlint/cli": "^9.1.2",
65
- "@commitlint/config-conventional": "^9.1.1",
60
+ "@babel/cli": "^7.11.6",
61
+ "@babel/core": "^7.11.6",
62
+ "@babel/preset-env": "^7.11.5",
63
+ "@commitlint/cli": "^11.0.0",
64
+ "@commitlint/config-conventional": "^11.0.0",
66
65
  "@webpack-contrib/defaults": "^6.3.0",
67
66
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
68
- "babel-jest": "^26.1.0",
67
+ "babel-jest": "^26.5.2",
69
68
  "cross-env": "^7.0.2",
70
- "del": "^5.1.0",
69
+ "del": "^6.0.0",
71
70
  "del-cli": "^3.0.1",
72
- "es-check": "^5.1.0",
73
- "eslint": "^7.5.0",
74
- "eslint-config-prettier": "^6.11.0",
75
- "eslint-plugin-import": "^2.22.0",
76
- "file-loader": "^6.0.0",
77
- "husky": "^4.2.5",
78
- "jest": "^26.1.0",
79
- "lint-staged": "^10.2.11",
71
+ "es-check": "^5.1.1",
72
+ "eslint": "^7.11.0",
73
+ "eslint-config-prettier": "^6.12.0",
74
+ "eslint-plugin-import": "^2.22.1",
75
+ "file-loader": "^6.1.1",
76
+ "husky": "^4.3.0",
77
+ "jest": "^26.5.3",
78
+ "less": "^3.12.2",
79
+ "less-loader": "^7.0.2",
80
+ "lint-staged": "^10.4.0",
80
81
  "memfs": "^3.2.0",
81
- "mini-css-extract-plugin": "^0.9.0",
82
+ "mini-css-extract-plugin": "^1.0.0",
82
83
  "npm-run-all": "^4.1.5",
83
- "postcss-loader": "^3.0.0",
84
+ "postcss-loader": "^4.0.4",
84
85
  "postcss-preset-env": "^6.7.0",
85
- "prettier": "^2.0.5",
86
- "sass": "^1.26.10",
87
- "sass-loader": "^9.0.2",
88
- "standard-version": "^8.0.2",
86
+ "prettier": "^2.1.2",
87
+ "sass": "^1.27.0",
88
+ "sass-loader": "^10.0.3",
89
+ "standard-version": "^9.0.0",
89
90
  "strip-ansi": "^6.0.0",
90
- "style-loader": "^1.2.1",
91
- "url-loader": "^4.1.0",
92
- "webpack": "^4.44.0"
91
+ "style-loader": "^2.0.0",
92
+ "stylus": "^0.54.8",
93
+ "stylus-loader": "^4.1.1",
94
+ "url-loader": "^4.1.1",
95
+ "webpack": "^5.0.0"
93
96
  },
94
97
  "keywords": [
95
98
  "webpack",