css-loader 6.3.0 → 6.6.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/README.md CHANGED
@@ -872,6 +872,36 @@ module.exports = {
872
872
  };
873
873
  ```
874
874
 
875
+ ##### `hashStrategy`
876
+
877
+ Type: `'resource-path-and-local-name' | 'minimal-subset'`
878
+ Default: `'resource-path-and-local-name'`
879
+
880
+ Should local name be used when computing the hash.
881
+
882
+ - `'resource-path-and-local-name'` Both resource path and local name are used when hashing. Each identifier in a module gets its own hash digest, always.
883
+ - `'minimal-subset'` Auto detect if identifier names can be omitted from hashing. Use this value to optimize the output for better GZIP or Brotli compression.
884
+
885
+ **webpack.config.js**
886
+
887
+ ```js
888
+ module.exports = {
889
+ module: {
890
+ rules: [
891
+ {
892
+ test: /\.css$/i,
893
+ loader: "css-loader",
894
+ options: {
895
+ modules: {
896
+ hashStrategy: "minimal-subset",
897
+ },
898
+ },
899
+ },
900
+ ],
901
+ },
902
+ };
903
+ ```
904
+
875
905
  ##### `localIdentRegExp`
876
906
 
877
907
  Type: `String|RegExp`
@@ -1446,7 +1476,7 @@ For `production` builds it's recommended to extract the CSS from your bundle bei
1446
1476
  This can be achieved by using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin), because it creates separate css files.
1447
1477
  For `development` mode (including `webpack-dev-server`) you can use [style-loader](https://github.com/webpack-contrib/style-loader), because it injects CSS into the DOM using multiple <style></style> and works faster.
1448
1478
 
1449
- > i Do not use together `style-loader` and `mini-css-extract-plugin`.
1479
+ > i Do not use `style-loader` and `mini-css-extract-plugin` together.
1450
1480
 
1451
1481
  **webpack.config.js**
1452
1482
 
package/dist/index.js CHANGED
@@ -49,9 +49,18 @@ async function loader(content, map, meta) {
49
49
 
50
50
  const importPluginImports = [];
51
51
  const importPluginApi = [];
52
+ let isSupportAbsoluteURL = false; // TODO enable by default in the next major release
53
+
54
+ if (this._compilation && this._compilation.options && this._compilation.options.experiments && this._compilation.options.experiments.buildHttp) {
55
+ isSupportAbsoluteURL = true;
56
+ }
57
+
58
+ const isSupportDataURL = options.esModule && Boolean("fsStartTime" in this._compiler);
52
59
 
53
60
  if ((0, _utils.shouldUseImportPlugin)(options)) {
54
61
  plugins.push((0, _plugins.importParser)({
62
+ isSupportAbsoluteURL: false,
63
+ isSupportDataURL: false,
55
64
  isCSSStyleSheet: options.exportType === "css-style-sheet",
56
65
  loaderContext: this,
57
66
  imports: importPluginImports,
@@ -65,22 +74,21 @@ async function loader(content, map, meta) {
65
74
 
66
75
  if ((0, _utils.shouldUseURLPlugin)(options)) {
67
76
  const needToResolveURL = !options.esModule;
68
- const isSupportDataURLInNewURL = options.esModule && Boolean("fsStartTime" in this._compiler);
69
77
  plugins.push((0, _plugins.urlParser)({
78
+ isSupportAbsoluteURL,
79
+ isSupportDataURL,
70
80
  imports: urlPluginImports,
71
81
  replacements,
72
82
  context: this.context,
73
83
  rootContext: this.rootContext,
74
84
  filter: (0, _utils.getFilter)(options.url.filter, this.resourcePath),
75
- needToResolveURL,
76
85
  resolver: needToResolveURL ? this.getResolve({
77
86
  mainFiles: [],
78
87
  extensions: []
79
88
  }) : // eslint-disable-next-line no-undefined
80
89
  undefined,
81
- urlHandler: url => (0, _utils.stringifyRequest)(this, url),
82
- // Support data urls as input in new URL added in webpack@5.38.0
83
- isSupportDataURLInNewURL
90
+ urlHandler: url => (0, _utils.stringifyRequest)(this, url) // Support data urls as input in new URL added in webpack@5.38.0
91
+
84
92
  }));
85
93
  }
86
94
 
package/dist/options.json CHANGED
@@ -114,6 +114,11 @@
114
114
  "link": "https://github.com/webpack-contrib/css-loader#localidenthashdigestlength",
115
115
  "type": "number"
116
116
  },
117
+ "hashStrategy": {
118
+ "description": "Allows to specify should localName be used when computing the hash.",
119
+ "link": "https://github.com/webpack-contrib/css-loader#hashstrategy",
120
+ "enum": ["resource-path-and-local-name", "minimal-subset"]
121
+ },
117
122
  "localIdentRegExp": {
118
123
  "description": "Allows to specify custom RegExp for local ident name.",
119
124
  "link": "https://github.com/webpack-contrib/css-loader#localidentregexp",
@@ -3,16 +3,16 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "importParser", {
6
+ Object.defineProperty(exports, "icssParser", {
7
7
  enumerable: true,
8
8
  get: function () {
9
- return _postcssImportParser.default;
9
+ return _postcssIcssParser.default;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "icssParser", {
12
+ Object.defineProperty(exports, "importParser", {
13
13
  enumerable: true,
14
14
  get: function () {
15
- return _postcssIcssParser.default;
15
+ return _postcssImportParser.default;
16
16
  }
17
17
  });
18
18
  Object.defineProperty(exports, "urlParser", {
@@ -11,7 +11,7 @@ var _utils = require("../utils");
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
14
- function parseNode(atRule, key) {
14
+ function parseNode(atRule, key, options) {
15
15
  // Convert only top-level @import
16
16
  if (atRule.parent.type !== "root") {
17
17
  return;
@@ -74,10 +74,13 @@ function parseNode(atRule, key) {
74
74
  }
75
75
 
76
76
  url = (0, _utils.normalizeUrl)(url, isStringValue);
77
- const isRequestable = (0, _utils.isUrlRequestable)(url);
77
+ const {
78
+ requestable,
79
+ needResolve
80
+ } = (0, _utils.isURLRequestable)(url, options);
78
81
  let prefix;
79
82
 
80
- if (isRequestable) {
83
+ if (requestable && needResolve) {
81
84
  const queryParts = url.split("!");
82
85
 
83
86
  if (queryParts.length > 1) {
@@ -139,7 +142,8 @@ function parseNode(atRule, key) {
139
142
  layer,
140
143
  supports,
141
144
  media,
142
- isRequestable
145
+ requestable,
146
+ needResolve
143
147
  };
144
148
  }
145
149
 
@@ -157,10 +161,17 @@ const plugin = (options = {}) => {
157
161
  return;
158
162
  }
159
163
 
164
+ const {
165
+ isSupportDataURL,
166
+ isSupportAbsoluteURL
167
+ } = options;
160
168
  let parsedAtRule;
161
169
 
162
170
  try {
163
- parsedAtRule = parseNode(atRule, "params", result);
171
+ parsedAtRule = parseNode(atRule, "params", {
172
+ isSupportAbsoluteURL,
173
+ isSupportDataURL
174
+ });
164
175
  } catch (error) {
165
176
  result.warn(error.message, {
166
177
  node: error.node
@@ -195,7 +206,8 @@ const plugin = (options = {}) => {
195
206
  const resolvedAtRules = await Promise.all(parsedAtRules.map(async parsedAtRule => {
196
207
  const {
197
208
  atRule,
198
- isRequestable,
209
+ requestable,
210
+ needResolve,
199
211
  prefix,
200
212
  url,
201
213
  layer,
@@ -211,7 +223,7 @@ const plugin = (options = {}) => {
211
223
  }
212
224
  }
213
225
 
214
- if (isRequestable) {
226
+ if (needResolve) {
215
227
  const request = (0, _utils.requestify)(url, loaderContext.rootContext);
216
228
  const resolvedUrl = await (0, _utils.resolveRequests)(resolver, loaderContext.context, [...new Set([request, url])]);
217
229
 
@@ -232,7 +244,7 @@ const plugin = (options = {}) => {
232
244
  supports,
233
245
  media,
234
246
  prefix,
235
- isRequestable
247
+ requestable
236
248
  };
237
249
  }
238
250
 
@@ -244,7 +256,7 @@ const plugin = (options = {}) => {
244
256
  supports,
245
257
  media,
246
258
  prefix,
247
- isRequestable
259
+ requestable
248
260
  };
249
261
  }));
250
262
  const urlToNameMap = new Map();
@@ -259,13 +271,13 @@ const plugin = (options = {}) => {
259
271
 
260
272
  const {
261
273
  url,
262
- isRequestable,
274
+ requestable,
263
275
  layer,
264
276
  supports,
265
277
  media
266
278
  } = resolvedAtRule;
267
279
 
268
- if (!isRequestable) {
280
+ if (!requestable) {
269
281
  options.api.push({
270
282
  url,
271
283
  layer,
@@ -49,32 +49,21 @@ function getWebpackIgnoreCommentValue(index, nodes, inBetween) {
49
49
  return matched && matched[2] === "true";
50
50
  }
51
51
 
52
- function shouldHandleURL(url, declaration, result, isSupportDataURLInNewURL) {
52
+ function shouldHandleURL(url, declaration, result, options) {
53
53
  if (url.length === 0) {
54
54
  result.warn(`Unable to find uri in '${declaration.toString()}'`, {
55
55
  node: declaration
56
56
  });
57
- return false;
57
+ return {
58
+ requestable: false,
59
+ needResolve: false
60
+ };
58
61
  }
59
62
 
60
- if ((0, _utils.isDataUrl)(url) && isSupportDataURLInNewURL) {
61
- try {
62
- decodeURIComponent(url);
63
- } catch (ignoreError) {
64
- return false;
65
- }
66
-
67
- return true;
68
- }
69
-
70
- if (!(0, _utils.isUrlRequestable)(url)) {
71
- return false;
72
- }
73
-
74
- return true;
63
+ return (0, _utils.isURLRequestable)(url, options);
75
64
  }
76
65
 
77
- function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
66
+ function parseDeclaration(declaration, key, result, options) {
78
67
  if (!needParseDeclaration.test(declaration[key])) {
79
68
  return;
80
69
  }
@@ -126,9 +115,13 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
126
115
  } = valueNode;
127
116
  const isStringValue = nodes.length !== 0 && nodes[0].type === "string";
128
117
  let url = isStringValue ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
129
- url = (0, _utils.normalizeUrl)(url, isStringValue); // Do not traverse inside `url`
118
+ url = (0, _utils.normalizeUrl)(url, isStringValue);
119
+ const {
120
+ requestable,
121
+ needResolve
122
+ } = shouldHandleURL(url, declaration, result, options); // Do not traverse inside `url`
130
123
 
131
- if (!shouldHandleURL(url, declaration, result, isSupportDataURLInNewURL)) {
124
+ if (!requestable) {
132
125
  // eslint-disable-next-line consistent-return
133
126
  return false;
134
127
  }
@@ -147,7 +140,8 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
147
140
  node: getNodeFromUrlFunc(valueNode),
148
141
  prefix,
149
142
  url,
150
- needQuotes: false
143
+ needQuotes: false,
144
+ needResolve
151
145
  }); // eslint-disable-next-line consistent-return
152
146
 
153
147
  return false;
@@ -176,9 +170,13 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
176
170
  } = nNode;
177
171
  const isStringValue = nodes.length !== 0 && nodes[0].type === "string";
178
172
  let url = isStringValue ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
179
- url = (0, _utils.normalizeUrl)(url, isStringValue); // Do not traverse inside `url`
173
+ url = (0, _utils.normalizeUrl)(url, isStringValue);
174
+ const {
175
+ requestable,
176
+ needResolve
177
+ } = shouldHandleURL(url, declaration, result, options); // Do not traverse inside `url`
180
178
 
181
- if (!shouldHandleURL(url, declaration, result, isSupportDataURLInNewURL)) {
179
+ if (!requestable) {
182
180
  // eslint-disable-next-line consistent-return
183
181
  return false;
184
182
  }
@@ -197,7 +195,8 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
197
195
  node: getNodeFromUrlFunc(nNode),
198
196
  prefix,
199
197
  url,
200
- needQuotes: false
198
+ needQuotes: false,
199
+ needResolve
201
200
  });
202
201
  } else if (type === "string") {
203
202
  needIgnore = getWebpackIgnoreCommentValue(innerIndex, valueNode.nodes);
@@ -212,9 +211,13 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
212
211
  continue;
213
212
  }
214
213
 
215
- let url = (0, _utils.normalizeUrl)(value, true); // Do not traverse inside `url`
214
+ let url = (0, _utils.normalizeUrl)(value, true);
215
+ const {
216
+ requestable,
217
+ needResolve
218
+ } = shouldHandleURL(url, declaration, result, options); // Do not traverse inside `url`
216
219
 
217
- if (!shouldHandleURL(url, declaration, result, isSupportDataURLInNewURL)) {
220
+ if (!requestable) {
218
221
  // eslint-disable-next-line consistent-return
219
222
  return false;
220
223
  }
@@ -233,7 +236,8 @@ function parseDeclaration(declaration, key, result, isSupportDataURLInNewURL) {
233
236
  node: nNode,
234
237
  prefix,
235
238
  url,
236
- needQuotes: true
239
+ needQuotes: true,
240
+ needResolve
237
241
  });
238
242
  }
239
243
  } // Do not traverse inside `image-set`
@@ -256,9 +260,13 @@ const plugin = (options = {}) => {
256
260
  return {
257
261
  Declaration(declaration) {
258
262
  const {
259
- isSupportDataURLInNewURL
263
+ isSupportDataURL,
264
+ isSupportAbsoluteURL
260
265
  } = options;
261
- const parsedURL = parseDeclaration(declaration, "value", result, isSupportDataURLInNewURL);
266
+ const parsedURL = parseDeclaration(declaration, "value", result, {
267
+ isSupportDataURL,
268
+ isSupportAbsoluteURL
269
+ });
262
270
 
263
271
  if (!parsedURL) {
264
272
  return;
@@ -274,7 +282,8 @@ const plugin = (options = {}) => {
274
282
 
275
283
  const resolvedDeclarations = await Promise.all(parsedDeclarations.map(async parsedDeclaration => {
276
284
  const {
277
- url
285
+ url,
286
+ needResolve
278
287
  } = parsedDeclaration;
279
288
 
280
289
  if (options.filter) {
@@ -286,7 +295,7 @@ const plugin = (options = {}) => {
286
295
  }
287
296
  }
288
297
 
289
- if ((0, _utils.isDataUrl)(url)) {
298
+ if (!needResolve) {
290
299
  // eslint-disable-next-line consistent-return
291
300
  return parsedDeclaration;
292
301
  }
@@ -296,12 +305,12 @@ const plugin = (options = {}) => {
296
305
  let hash = query ? "?" : "";
297
306
  hash += hashOrQuery ? `#${hashOrQuery}` : "";
298
307
  const {
299
- needToResolveURL,
308
+ resolver,
300
309
  rootContext
301
310
  } = options;
302
- const request = (0, _utils.requestify)(pathname, rootContext, needToResolveURL);
311
+ const request = (0, _utils.requestify)(pathname, rootContext, Boolean(resolver));
303
312
 
304
- if (!needToResolveURL) {
313
+ if (!resolver) {
305
314
  // eslint-disable-next-line consistent-return
306
315
  return { ...parsedDeclaration,
307
316
  url: request,
@@ -309,20 +318,16 @@ const plugin = (options = {}) => {
309
318
  };
310
319
  }
311
320
 
312
- const {
313
- resolver,
314
- context
315
- } = options;
316
- const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([request, url])]);
321
+ const resolvedURL = await (0, _utils.resolveRequests)(resolver, options.context, [...new Set([request, url])]);
317
322
 
318
- if (!resolvedUrl) {
323
+ if (!resolvedURL) {
319
324
  // eslint-disable-next-line consistent-return
320
325
  return;
321
326
  } // eslint-disable-next-line consistent-return
322
327
 
323
328
 
324
329
  return { ...parsedDeclaration,
325
- url: resolvedUrl,
330
+ url: resolvedURL,
326
331
  hash
327
332
  };
328
333
  }));
@@ -361,7 +366,7 @@ const plugin = (options = {}) => {
361
366
  options.imports.push({
362
367
  type: "url",
363
368
  importName,
364
- url: options.needToResolveURL ? options.urlHandler(newUrl) : JSON.stringify(newUrl),
369
+ url: options.resolver ? options.urlHandler(newUrl) : JSON.stringify(newUrl),
365
370
  index
366
371
  });
367
372
  }
@@ -51,8 +51,8 @@ module.exports = function (cssWithMappingToString) {
51
51
  var alreadyImportedModules = {};
52
52
 
53
53
  if (dedupe) {
54
- for (var _i = 0; _i < this.length; _i++) {
55
- var id = this[_i][0];
54
+ for (var k = 0; k < this.length; k++) {
55
+ var id = this[k][0];
56
56
 
57
57
  if (id != null) {
58
58
  alreadyImportedModules[id] = true;
@@ -60,8 +60,8 @@ module.exports = function (cssWithMappingToString) {
60
60
  }
61
61
  }
62
62
 
63
- for (var _i2 = 0; _i2 < modules.length; _i2++) {
64
- var item = [].concat(modules[_i2]);
63
+ for (var _k = 0; _k < modules.length; _k++) {
64
+ var item = [].concat(modules[_k]);
65
65
 
66
66
  if (dedupe && alreadyImportedModules[item[0]]) {
67
67
  continue;
package/dist/utils.js CHANGED
@@ -3,29 +3,29 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.normalizeOptions = normalizeOptions;
7
- exports.shouldUseModulesPlugins = shouldUseModulesPlugins;
8
- exports.shouldUseImportPlugin = shouldUseImportPlugin;
9
- exports.shouldUseURLPlugin = shouldUseURLPlugin;
10
- exports.shouldUseIcssPlugin = shouldUseIcssPlugin;
11
- exports.normalizeUrl = normalizeUrl;
12
- exports.requestify = requestify;
6
+ exports.WEBPACK_IGNORE_COMMENT_REGEXP = void 0;
7
+ exports.camelCase = camelCase;
8
+ exports.combineRequests = combineRequests;
9
+ exports.getExportCode = getExportCode;
13
10
  exports.getFilter = getFilter;
11
+ exports.getImportCode = getImportCode;
12
+ exports.getModuleCode = getModuleCode;
14
13
  exports.getModulesOptions = getModulesOptions;
15
14
  exports.getModulesPlugins = getModulesPlugins;
16
- exports.normalizeSourceMap = normalizeSourceMap;
17
15
  exports.getPreRequester = getPreRequester;
18
- exports.getImportCode = getImportCode;
19
- exports.getModuleCode = getModuleCode;
20
- exports.getExportCode = getExportCode;
16
+ exports.isDataUrl = isDataUrl;
17
+ exports.isURLRequestable = isURLRequestable;
18
+ exports.normalizeOptions = normalizeOptions;
19
+ exports.normalizeSourceMap = normalizeSourceMap;
20
+ exports.normalizeUrl = normalizeUrl;
21
+ exports.requestify = requestify;
21
22
  exports.resolveRequests = resolveRequests;
22
- exports.isUrlRequestable = isUrlRequestable;
23
+ exports.shouldUseIcssPlugin = shouldUseIcssPlugin;
24
+ exports.shouldUseImportPlugin = shouldUseImportPlugin;
25
+ exports.shouldUseModulesPlugins = shouldUseModulesPlugins;
26
+ exports.shouldUseURLPlugin = shouldUseURLPlugin;
23
27
  exports.sort = sort;
24
- exports.combineRequests = combineRequests;
25
- exports.camelCase = camelCase;
26
28
  exports.stringifyRequest = stringifyRequest;
27
- exports.isDataUrl = isDataUrl;
28
- exports.WEBPACK_IGNORE_COMMENT_REGEXP = void 0;
29
29
 
30
30
  var _url = require("url");
31
31
 
@@ -55,9 +55,14 @@ function isAbsolutePath(str) {
55
55
 
56
56
  function isRelativePath(str) {
57
57
  return matchRelativePath.test(str);
58
- }
58
+ } // TODO simplify for the next major release
59
+
59
60
 
60
61
  function stringifyRequest(loaderContext, request) {
62
+ if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") {
63
+ return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
64
+ }
65
+
61
66
  const splitted = request.split("!");
62
67
  const {
63
68
  context
@@ -313,22 +318,17 @@ function escapeLocalIdent(localident) {
313
318
  }
314
319
 
315
320
  function defaultGetLocalIdent(loaderContext, localIdentName, localName, options) {
316
- let relativeMatchResource = "";
317
321
  const {
318
- context
322
+ context,
323
+ hashSalt,
324
+ hashStrategy
319
325
  } = options;
320
326
  const {
321
327
  resourcePath
322
- } = loaderContext; // eslint-disable-next-line no-underscore-dangle
323
-
324
- if (loaderContext._module && loaderContext._module.matchResource) {
325
- relativeMatchResource = `${normalizePath( // eslint-disable-next-line no-underscore-dangle
326
- _path.default.relative(context, loaderContext._module.matchResource))}\x00`;
327
- }
328
-
328
+ } = loaderContext;
329
329
  const relativeResourcePath = normalizePath(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
330
330
 
331
- options.content = `${relativeMatchResource}${relativeResourcePath}\x00${localName}`;
331
+ options.content = hashStrategy === "minimal-subset" && /\[local\]/.test(localIdentName) ? relativeResourcePath : `${relativeResourcePath}\x00${localName}`;
332
332
  let {
333
333
  hashFunction,
334
334
  hashDigest,
@@ -345,21 +345,30 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
345
345
  // eslint-disable-next-line no-param-reassign
346
346
 
347
347
  localIdentName = localIdentName.replace(/\[(?:([^:\]]+):)?(?:hash|contenthash|fullhash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi, () => hashName === "fullhash" ? "[fullhash]" : "[contenthash]");
348
- } // eslint-disable-next-line no-underscore-dangle
348
+ }
349
349
 
350
+ let localIdentHash = "";
350
351
 
351
- const hash = loaderContext._compiler.webpack.util.createHash(hashFunction);
352
+ for (let tier = 0; localIdentHash.length < hashDigestLength; tier++) {
353
+ // TODO remove this in the next major release
354
+ const hash = loaderContext.utils && typeof loaderContext.utils.createHash === "function" ? loaderContext.utils.createHash(hashFunction) : // eslint-disable-next-line no-underscore-dangle
355
+ loaderContext._compiler.webpack.util.createHash(hashFunction);
352
356
 
353
- const {
354
- hashSalt
355
- } = options;
357
+ if (hashSalt) {
358
+ hash.update(hashSalt);
359
+ }
356
360
 
357
- if (hashSalt) {
358
- hash.update(hashSalt);
359
- }
361
+ const tierSalt = Buffer.allocUnsafe(4);
362
+ tierSalt.writeUInt32LE(tier);
363
+ hash.update(tierSalt); // TODO: bug in webpack with unicode characters with strings
364
+
365
+ hash.update(Buffer.from(options.content, "utf8"));
366
+ localIdentHash = (localIdentHash + hash.digest(hashDigest) // Remove all leading digits
367
+ ).replace(/^\d+/, "") // Replace all slashes with underscores (same as in base64url)
368
+ .replace(/\//g, "_") // Remove everything that is not an alphanumeric or underscore
369
+ .replace(/[^A-Za-z0-9_]+/g, "").slice(0, hashDigestLength);
370
+ } // 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
360
371
 
361
- hash.update(options.content);
362
- const localIdentHash = hash.digest(hashDigest).slice(0, hashDigestLength).replace(/[/+]/g, "_").replace(/^\d/g, "_"); // 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
363
372
 
364
373
  const ext = _path.default.extname(resourcePath);
365
374
 
@@ -689,7 +698,8 @@ function getModulesPlugins(options, loaderContext) {
689
698
  localIdentHashFunction,
690
699
  localIdentHashDigest,
691
700
  localIdentHashDigestLength,
692
- localIdentRegExp
701
+ localIdentRegExp,
702
+ hashStrategy
693
703
  } = options.modules;
694
704
  let plugins = [];
695
705
 
@@ -707,6 +717,7 @@ function getModulesPlugins(options, loaderContext) {
707
717
  hashFunction: localIdentHashFunction,
708
718
  hashDigest: localIdentHashDigest,
709
719
  hashDigestLength: localIdentHashDigestLength,
720
+ hashStrategy,
710
721
  regExp: localIdentRegExp
711
722
  });
712
723
  } // A null/undefined value signals that we should invoke the default
@@ -720,6 +731,7 @@ function getModulesPlugins(options, loaderContext) {
720
731
  hashFunction: localIdentHashFunction,
721
732
  hashDigest: localIdentHashDigest,
722
733
  hashDigestLength: localIdentHashDigestLength,
734
+ hashStrategy,
723
735
  regExp: localIdentRegExp
724
736
  });
725
737
  return escapeLocalIdent(localIdent).replace(/\\\[local\\]/gi, exportName);
@@ -843,6 +855,13 @@ function normalizeSourceMapForRuntime(map, loaderContext) {
843
855
 
844
856
  if (resultMap) {
845
857
  delete resultMap.file;
858
+ /* eslint-disable no-underscore-dangle */
859
+
860
+ if (loaderContext._compilation && loaderContext._compilation.options && loaderContext._compilation.options.devtool && loaderContext._compilation.options.devtool.includes("nosources")) {
861
+ /* eslint-enable no-underscore-dangle */
862
+ delete resultMap.sourcesContent;
863
+ }
864
+
846
865
  resultMap.sourceRoot = "";
847
866
  resultMap.sources = resultMap.sources.map(source => {
848
867
  // Non-standard syntax from `postcss`
@@ -901,7 +920,13 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
901
920
  return "";
902
921
  }
903
922
 
904
- const sourceMapValue = options.sourceMap ? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}` : "";
923
+ let sourceMapValue = "";
924
+
925
+ if (options.sourceMap) {
926
+ const sourceMap = result.map;
927
+ sourceMapValue = `,${normalizeSourceMapForRuntime(sourceMap, loaderContext)}`;
928
+ }
929
+
905
930
  let code = JSON.stringify(result.css);
906
931
  let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap ? "___CSS_LOADER_API_SOURCEMAP_IMPORT___" : "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___"});\n`;
907
932
 
@@ -1060,28 +1085,67 @@ async function resolveRequests(resolve, context, possibleRequests) {
1060
1085
  });
1061
1086
  }
1062
1087
 
1063
- function isUrlRequestable(url) {
1088
+ function isURLRequestable(url, options = {}) {
1064
1089
  // Protocol-relative URLs
1065
1090
  if (/^\/\//.test(url)) {
1066
- return false;
1091
+ return {
1092
+ requestable: false,
1093
+ needResolve: false
1094
+ };
1095
+ } // `#` URLs
1096
+
1097
+
1098
+ if (/^#/.test(url)) {
1099
+ return {
1100
+ requestable: false,
1101
+ needResolve: false
1102
+ };
1103
+ } // Data URI
1104
+
1105
+
1106
+ if (isDataUrl(url) && options.isSupportDataURL) {
1107
+ try {
1108
+ decodeURIComponent(url);
1109
+ } catch (ignoreError) {
1110
+ return {
1111
+ requestable: false,
1112
+ needResolve: false
1113
+ };
1114
+ }
1115
+
1116
+ return {
1117
+ requestable: true,
1118
+ needResolve: false
1119
+ };
1067
1120
  } // `file:` protocol
1068
1121
 
1069
1122
 
1070
1123
  if (/^file:/i.test(url)) {
1071
- return true;
1124
+ return {
1125
+ requestable: true,
1126
+ needResolve: true
1127
+ };
1072
1128
  } // Absolute URLs
1073
1129
 
1074
1130
 
1075
1131
  if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !NATIVE_WIN32_PATH.test(url)) {
1076
- return false;
1077
- } // `#` URLs
1078
-
1132
+ if (options.isSupportAbsoluteURL && /^https?:/i.test(url)) {
1133
+ return {
1134
+ requestable: true,
1135
+ needResolve: false
1136
+ };
1137
+ }
1079
1138
 
1080
- if (/^#/.test(url)) {
1081
- return false;
1139
+ return {
1140
+ requestable: false,
1141
+ needResolve: false
1142
+ };
1082
1143
  }
1083
1144
 
1084
- return true;
1145
+ return {
1146
+ requestable: true,
1147
+ needResolve: true
1148
+ };
1085
1149
  }
1086
1150
 
1087
1151
  function sort(a, b) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-loader",
3
- "version": "6.3.0",
3
+ "version": "6.6.0",
4
4
  "description": "css loader module for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/css-loader",
@@ -43,50 +43,50 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "icss-utils": "^5.1.0",
46
- "postcss": "^8.2.15",
46
+ "postcss": "^8.4.5",
47
47
  "postcss-modules-extract-imports": "^3.0.0",
48
48
  "postcss-modules-local-by-default": "^4.0.0",
49
49
  "postcss-modules-scope": "^3.0.0",
50
50
  "postcss-modules-values": "^4.0.0",
51
- "postcss-value-parser": "^4.1.0",
51
+ "postcss-value-parser": "^4.2.0",
52
52
  "semver": "^7.3.5"
53
53
  },
54
54
  "devDependencies": {
55
- "@babel/cli": "^7.14.5",
56
- "@babel/core": "^7.14.6",
57
- "@babel/preset-env": "^7.14.7",
58
- "@commitlint/cli": "^13.1.0",
59
- "@commitlint/config-conventional": "^13.1.0",
55
+ "@babel/cli": "^7.16.8",
56
+ "@babel/core": "^7.16.12",
57
+ "@babel/preset-env": "^7.16.11",
58
+ "@commitlint/cli": "^16.1.0",
59
+ "@commitlint/config-conventional": "^16.0.0",
60
60
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
61
- "babel-jest": "^27.0.6",
61
+ "babel-jest": "^27.4.6",
62
62
  "cross-env": "^7.0.3",
63
63
  "del": "^6.0.0",
64
64
  "del-cli": "^4.0.1",
65
65
  "es-check": "^6.0.0",
66
- "eslint": "^7.30.0",
66
+ "eslint": "^8.7.0",
67
67
  "eslint-config-prettier": "^8.3.0",
68
- "eslint-plugin-import": "^2.23.4",
68
+ "eslint-plugin-import": "^2.25.4",
69
69
  "file-loader": "^6.2.0",
70
70
  "husky": "^7.0.1",
71
- "jest": "^27.0.6",
71
+ "jest": "^27.4.7",
72
72
  "less": "^4.1.1",
73
73
  "less-loader": "^10.0.1",
74
- "lint-staged": "^11.0.1",
75
- "memfs": "^3.2.2",
76
- "mini-css-extract-plugin": "^2.1.0",
74
+ "lint-staged": "^12.3.2",
75
+ "memfs": "^3.4.1",
76
+ "mini-css-extract-plugin": "^2.5.3",
77
77
  "npm-run-all": "^4.1.5",
78
- "postcss-loader": "^6.1.1",
79
- "postcss-preset-env": "^6.7.0",
80
- "prettier": "^2.3.2",
81
- "sass": "^1.35.2",
82
- "sass-loader": "^12.1.0",
78
+ "postcss-loader": "^6.2.1",
79
+ "postcss-preset-env": "^7.2.3",
80
+ "prettier": "^2.5.1",
81
+ "sass": "^1.49.0",
82
+ "sass-loader": "^12.4.0",
83
83
  "standard-version": "^9.3.1",
84
84
  "strip-ansi": "^6.0.0",
85
85
  "style-loader": "^3.1.0",
86
- "stylus": "^0.55.0",
86
+ "stylus": "^0.56.0",
87
87
  "stylus-loader": "^6.1.0",
88
88
  "url-loader": "^4.1.1",
89
- "webpack": "^5.45.1"
89
+ "webpack": "^5.67.0"
90
90
  },
91
91
  "keywords": [
92
92
  "webpack",