css-loader 6.2.0 → 6.3.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
@@ -54,69 +54,19 @@ module.exports = {
54
54
 
55
55
  And run `webpack` via your preferred method.
56
56
 
57
- ### `toString`
58
-
59
- You can also use the css-loader results directly as a string, such as in Angular's component style.
60
-
61
- **webpack.config.js**
62
-
63
- ```js
64
- module.exports = {
65
- module: {
66
- rules: [
67
- {
68
- test: /\.css$/i,
69
- use: ["to-string-loader", "css-loader"],
70
- },
71
- ],
72
- },
73
- };
74
- ```
75
-
76
- or
77
-
78
- ```js
79
- const css = require("./test.css").toString();
80
-
81
- console.log(css); // {String}
82
- ```
83
-
84
- If there are SourceMaps, they will also be included in the result string.
85
-
86
- If, for one reason or another, you need to extract CSS as a
87
- plain string resource (i.e. not wrapped in a JS module) you
88
- might want to check out the [extract-loader](https://github.com/peerigon/extract-loader).
89
- It's useful when you, for instance, need to post process the CSS as a string.
90
-
91
- **webpack.config.js**
92
-
93
- ```js
94
- module.exports = {
95
- module: {
96
- rules: [
97
- {
98
- test: /\.css$/i,
99
- use: [
100
- "handlebars-loader", // handlebars loader expects raw resource string
101
- "extract-loader",
102
- "css-loader",
103
- ],
104
- },
105
- ],
106
- },
107
- };
108
- ```
57
+ If, for one reason or another, you need to extract CSS as a file (i.e. do not store CSS in a JS module) you might want to check out the [recommend example](https://github.com/webpack-contrib/css-loader#recommend).
109
58
 
110
59
  ## Options
111
60
 
112
- | Name | Type | Default | Description |
113
- | :-----------------------------------: | :-------------------------: | :----------------: | :----------------------------------------------------------------------------------------------------------------------- |
114
- | **[`url`](#url)** | `{Boolean\|Object}` | `true` | Allows to enables/disables `url()`/`image-set()` functions handling |
115
- | **[`import`](#import)** | `{Boolean\|Object}` | `true` | Allows to enables/disables `@import` at-rules handling |
116
- | **[`modules`](#modules)** | `{Boolean\|String\|Object}` | `{auto: true}` | Allows to enables/disables or setup CSS Modules options |
117
- | **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps |
118
- | **[`importLoaders`](#importloaders)** | `{Number}` | `0` | Allows enables/disables or setups number of loaders applied before CSS loader for `@import`/CSS Modules and ICSS imports |
119
- | **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax |
61
+ | Name | Type | Default | Description |
62
+ | :-----------------------------------: | :------------------------------------------: | :----------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63
+ | **[`url`](#url)** | `{Boolean\|Object}` | `true` | Allows to enables/disables `url()`/`image-set()` functions handling |
64
+ | **[`import`](#import)** | `{Boolean\|Object}` | `true` | Allows to enables/disables `@import` at-rules handling |
65
+ | **[`modules`](#modules)** | `{Boolean\|String\|Object}` | `{auto: true}` | Allows to enables/disables or setup CSS Modules options |
66
+ | **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps |
67
+ | **[`importLoaders`](#importloaders)** | `{Number}` | `0` | Allows enables/disables or setups number of loaders applied before CSS loader for `@import`/CSS Modules and ICSS imports |
68
+ | **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax |
69
+ | **[`exportType`](#exporttype)** | `{'array' \| 'string' \| 'css-style-sheet'}` | `array` | Allows exporting styles as array with modules, string or [constructable stylesheet](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) (i.e. [`CSSStyleSheet`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet)) |
120
70
 
121
71
  ### `url`
122
72
 
@@ -745,13 +695,14 @@ For more information on options see:
745
695
 
746
696
  Supported template strings:
747
697
 
748
- - [name] the basename of the resource
749
- - [path] the path of the resource relative to the `compiler.context` option or `modules.localIdentContext` option.
750
- - [file] - filename and path.
751
- - [ext] - extension with leading .
752
- - [hash] - the hash of the string, generated based on `localIdentHashSalt`, `localIdentHashFunction`, `localIdentHashDigest`, `localIdentHashDigestLength`, `localIdentContext`, `resourcePath` and `exportName`
753
- - [<hashFunction>:hash:<hashDigest>:<hashDigestLength>] - hash with hash settings.
754
- - [local] - original class.
698
+ - `[name]` the basename of the resource
699
+ - `[folder]` the folder the resource relative to the `compiler.context` option or `modules.localIdentContext` option.
700
+ - `[path]` the path of the resource relative to the `compiler.context` option or `modules.localIdentContext` option.
701
+ - `[file]` - filename and path.
702
+ - `[ext]` - extension with leading `.`.
703
+ - `[hash]` - the hash of the string, generated based on `localIdentHashSalt`, `localIdentHashFunction`, `localIdentHashDigest`, `localIdentHashDigestLength`, `localIdentContext`, `resourcePath` and `exportName`
704
+ - `[<hashFunction>:hash:<hashDigest>:<hashDigestLength>]` - hash with hash settings.
705
+ - `[local]` - original class.
755
706
 
756
707
  Recommendations:
757
708
 
@@ -1290,6 +1241,203 @@ module.exports = {
1290
1241
  };
1291
1242
  ```
1292
1243
 
1244
+ ### `exportType`
1245
+
1246
+ Type: `'array' | 'string' | 'css-style-sheet'`
1247
+ Default: `'array'`
1248
+
1249
+ Allows exporting styles as array with modules, string or [constructable stylesheet](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) (i.e. [`CSSStyleSheet`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet)).
1250
+ Default value is `'array'`, i.e. loader exports array of modules with specific API which is used in `style-loader` or other.
1251
+
1252
+ **webpack.config.js**
1253
+
1254
+ ```js
1255
+ module.exports = {
1256
+ module: {
1257
+ rules: [
1258
+ {
1259
+ assert: { type: "css" },
1260
+ loader: "css-loader",
1261
+ options: {
1262
+ exportType: "css-style-sheet",
1263
+ },
1264
+ },
1265
+ ],
1266
+ },
1267
+ };
1268
+ ```
1269
+
1270
+ **src/index.js**
1271
+
1272
+ ```js
1273
+ import sheet from "./styles.css" assert { type: "css" };
1274
+
1275
+ document.adoptedStyleSheets = [sheet];
1276
+ shadowRoot.adoptedStyleSheets = [sheet];
1277
+ ```
1278
+
1279
+ #### `'array'`
1280
+
1281
+ The default export is array of modules with specific API which is used in `style-loader` or other.
1282
+
1283
+ **webpack.config.js**
1284
+
1285
+ ```js
1286
+ module.exports = {
1287
+ module: {
1288
+ rules: [
1289
+ {
1290
+ test: /\.(sa|sc|c)ss$/i,
1291
+ use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
1292
+ },
1293
+ ],
1294
+ },
1295
+ };
1296
+ ```
1297
+
1298
+ **src/index.js**
1299
+
1300
+ ```js
1301
+ // `style-loader` applies styles to DOM
1302
+ import "./styles.css";
1303
+ ```
1304
+
1305
+ #### `'string'`
1306
+
1307
+ > ⚠ You don't need [`style-loader`](https://github.com/webpack-contrib/style-loader) anymore, please remove it.
1308
+ > ⚠ The `esModules` option should be enabled if you want to use it with [`CSS modules`](https://github.com/webpack-contrib/css-loader#modules), by default for locals will be used [named export](https://github.com/webpack-contrib/css-loader#namedexport).
1309
+
1310
+ The default export is `string`.
1311
+
1312
+ **webpack.config.js**
1313
+
1314
+ ```js
1315
+ module.exports = {
1316
+ module: {
1317
+ rules: [
1318
+ {
1319
+ test: /\.(sa|sc|c)ss$/i,
1320
+ use: ["css-loader", "postcss-loader", "sass-loader"],
1321
+ },
1322
+ ],
1323
+ },
1324
+ };
1325
+ ```
1326
+
1327
+ **src/index.js**
1328
+
1329
+ ```js
1330
+ import sheet from "./styles.css";
1331
+
1332
+ console.log(sheet);
1333
+ ```
1334
+
1335
+ #### `'css-style-sheet'`
1336
+
1337
+ > ⚠ `@import` rules not yet allowed, more [information](https://web.dev/css-module-scripts/#@import-rules-not-yet-allowed)
1338
+ > ⚠ You don't need [`style-loader`](https://github.com/webpack-contrib/style-loader) anymore, please remove it.
1339
+ > ⚠ The `esModules` option should be enabled if you want to use it with [`CSS modules`](https://github.com/webpack-contrib/css-loader#modules), by default for locals will be used [named export](https://github.com/webpack-contrib/css-loader#namedexport).
1340
+ > ⚠ Source maps are not currently supported in `Chrome` due [bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1174094&q=CSSStyleSheet%20source%20maps&can=2)
1341
+
1342
+ The default export is a [constructable stylesheet](https://developers.google.com/web/updates/2019/02/constructable-stylesheets) (i.e. [`CSSStyleSheet`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet)).
1343
+
1344
+ Useful for [custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) and shadow DOM.
1345
+
1346
+ More information:
1347
+
1348
+ - [Using CSS Module Scripts to import stylesheets](https://web.dev/css-module-scripts/)
1349
+ - [Constructable Stylesheets: seamless reusable styles](https://developers.google.com/web/updates/2019/02/constructable-stylesheets)
1350
+
1351
+ **webpack.config.js**
1352
+
1353
+ ```js
1354
+ module.exports = {
1355
+ module: {
1356
+ rules: [
1357
+ {
1358
+ assert: { type: "css" },
1359
+ loader: "css-loader",
1360
+ options: {
1361
+ exportType: "css-style-sheet",
1362
+ },
1363
+ },
1364
+
1365
+ // For Sass/SCSS:
1366
+ //
1367
+ // {
1368
+ // assert: { type: "css" },
1369
+ // rules: [
1370
+ // {
1371
+ // loader: "css-loader",
1372
+ // options: {
1373
+ // exportType: "css-style-sheet",
1374
+ // // Other options
1375
+ // },
1376
+ // },
1377
+ // {
1378
+ // loader: "sass-loader",
1379
+ // options: {
1380
+ // // Other options
1381
+ // },
1382
+ // },
1383
+ // ],
1384
+ // },
1385
+ ],
1386
+ },
1387
+ };
1388
+ ```
1389
+
1390
+ **src/index.js**
1391
+
1392
+ ```js
1393
+ // Example for Sass/SCSS:
1394
+ // import sheet from "./styles.scss" assert { type: "css" };
1395
+
1396
+ // Example for CSS modules:
1397
+ // import sheet, { myClass } from "./styles.scss" assert { type: "css" };
1398
+
1399
+ // Example for CSS:
1400
+ import sheet from "./styles.css" assert { type: "css" };
1401
+
1402
+ document.adoptedStyleSheets = [sheet];
1403
+ shadowRoot.adoptedStyleSheets = [sheet];
1404
+ ```
1405
+
1406
+ For migration purposes, you can use the following configuration:
1407
+
1408
+ ```js
1409
+ module.exports = {
1410
+ module: {
1411
+ rules: [
1412
+ {
1413
+ test: /\.css$/i,
1414
+ oneOf: [
1415
+ {
1416
+ assert: { type: "css" },
1417
+ loader: "css-loader",
1418
+ options: {
1419
+ exportType: "css-style-sheet",
1420
+ // Other options
1421
+ },
1422
+ },
1423
+ {
1424
+ use: [
1425
+ "style-loader",
1426
+ {
1427
+ loader: "css-loader",
1428
+ options: {
1429
+ // Other options
1430
+ },
1431
+ },
1432
+ ],
1433
+ },
1434
+ ],
1435
+ },
1436
+ ],
1437
+ },
1438
+ };
1439
+ ```
1440
+
1293
1441
  ## Examples
1294
1442
 
1295
1443
  ### Recommend
@@ -1310,7 +1458,7 @@ module.exports = {
1310
1458
  module: {
1311
1459
  rules: [
1312
1460
  {
1313
- test: /\.(sa|sc|c)ss$/,
1461
+ test: /\.(sa|sc|c)ss$/i,
1314
1462
  use: [
1315
1463
  devMode ? "style-loader" : MiniCssExtractPlugin.loader,
1316
1464
  "css-loader",
@@ -1533,8 +1681,8 @@ module.exports = {
1533
1681
  // --------
1534
1682
  // SCSS ALL EXCEPT MODULES
1535
1683
  {
1536
- test: /\.scss$/,
1537
- exclude: /\.module\.scss$/,
1684
+ test: /\.scss$/i,
1685
+ exclude: /\.module\.scss$/i,
1538
1686
  use: [
1539
1687
  {
1540
1688
  loader: "style-loader",
@@ -1556,7 +1704,7 @@ module.exports = {
1556
1704
  // --------
1557
1705
  // SCSS MODULES
1558
1706
  {
1559
- test: /\.module\.scss$/,
1707
+ test: /\.module\.scss$/i,
1560
1708
  use: [
1561
1709
  {
1562
1710
  loader: "style-loader",
package/dist/index.js CHANGED
@@ -51,22 +51,12 @@ async function loader(content, map, meta) {
51
51
  const importPluginApi = [];
52
52
 
53
53
  if ((0, _utils.shouldUseImportPlugin)(options)) {
54
- const resolver = this.getResolve({
55
- dependencyType: "css",
56
- conditionNames: ["style"],
57
- mainFields: ["css", "style", "main", "..."],
58
- mainFiles: ["index", "..."],
59
- extensions: [".css", "..."],
60
- preferRelative: true
61
- });
62
54
  plugins.push((0, _plugins.importParser)({
55
+ isCSSStyleSheet: options.exportType === "css-style-sheet",
56
+ loaderContext: this,
63
57
  imports: importPluginImports,
64
58
  api: importPluginApi,
65
- context: this.context,
66
- rootContext: this.rootContext,
67
- resourcePath: this.resourcePath,
68
- filter: (0, _utils.getFilter)(options.import.filter, this.resourcePath),
69
- resolver,
59
+ filter: options.import.filter,
70
60
  urlHandler: url => (0, _utils.stringifyRequest)(this, (0, _utils.combineRequests)((0, _utils.getPreRequester)(this)(options.importLoaders), url))
71
61
  }));
72
62
  }
@@ -99,22 +89,12 @@ async function loader(content, map, meta) {
99
89
  const needToUseIcssPlugin = (0, _utils.shouldUseIcssPlugin)(options);
100
90
 
101
91
  if (needToUseIcssPlugin) {
102
- const icssResolver = this.getResolve({
103
- dependencyType: "icss",
104
- conditionNames: ["style"],
105
- extensions: ["..."],
106
- mainFields: ["css", "style", "main", "..."],
107
- mainFiles: ["index", "..."],
108
- preferRelative: true
109
- });
110
92
  plugins.push((0, _plugins.icssParser)({
93
+ loaderContext: this,
111
94
  imports: icssPluginImports,
112
95
  api: icssPluginApi,
113
96
  replacements,
114
97
  exports,
115
- context: this.context,
116
- rootContext: this.rootContext,
117
- resolver: icssResolver,
118
98
  urlHandler: url => (0, _utils.stringifyRequest)(this, (0, _utils.combineRequests)((0, _utils.getPreRequester)(this)(options.importLoaders), url))
119
99
  }));
120
100
  } // Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
@@ -172,9 +152,13 @@ async function loader(content, map, meta) {
172
152
 
173
153
  if (options.sourceMap) {
174
154
  imports.unshift({
175
- type: "api_sourcemap_import",
176
155
  importName: "___CSS_LOADER_API_SOURCEMAP_IMPORT___",
177
- url: (0, _utils.stringifyRequest)(this, require.resolve("./runtime/cssWithMappingToString"))
156
+ url: (0, _utils.stringifyRequest)(this, require.resolve("./runtime/sourceMaps"))
157
+ });
158
+ } else {
159
+ imports.unshift({
160
+ importName: "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___",
161
+ url: (0, _utils.stringifyRequest)(this, require.resolve("./runtime/noSourceMaps"))
178
162
  });
179
163
  }
180
164
  }
package/dist/options.json CHANGED
@@ -193,6 +193,11 @@
193
193
  "description": "Use the ES modules syntax.",
194
194
  "link": "https://github.com/webpack-contrib/css-loader#esmodule",
195
195
  "type": "boolean"
196
+ },
197
+ "exportType": {
198
+ "description": "Allows exporting styles as array with modules, string or constructable stylesheet (i.e. `CSSStyleSheet`).",
199
+ "link": "https://github.com/webpack-contrib/css-loader#exporttype",
200
+ "enum": ["array", "string", "css-style-sheet"]
196
201
  }
197
202
  },
198
203
  "type": "object"
@@ -20,7 +20,18 @@ const plugin = (options = {}) => {
20
20
  icssExports
21
21
  } = (0, _icssUtils.extractICSS)(root);
22
22
  const imports = new Map();
23
- const tasks = []; // eslint-disable-next-line guard-for-in
23
+ const tasks = [];
24
+ const {
25
+ loaderContext
26
+ } = options;
27
+ const resolver = loaderContext.getResolve({
28
+ dependencyType: "icss",
29
+ conditionNames: ["style"],
30
+ extensions: ["..."],
31
+ mainFields: ["css", "style", "main", "..."],
32
+ mainFiles: ["index", "..."],
33
+ preferRelative: true
34
+ }); // eslint-disable-next-line guard-for-in
24
35
 
25
36
  for (const url in icssImports) {
26
37
  const tokens = icssImports[url];
@@ -39,14 +50,10 @@ const plugin = (options = {}) => {
39
50
  prefix = queryParts.join("!");
40
51
  }
41
52
 
42
- const request = (0, _utils.requestify)((0, _utils.normalizeUrl)(normalizedUrl, true), options.rootContext);
53
+ const request = (0, _utils.requestify)((0, _utils.normalizeUrl)(normalizedUrl, true), loaderContext.rootContext);
43
54
 
44
55
  const doResolve = async () => {
45
- const {
46
- resolver,
47
- context
48
- } = options;
49
- const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([normalizedUrl, request])]);
56
+ const resolvedUrl = await (0, _utils.resolveRequests)(resolver, loaderContext.context, [...new Set([normalizedUrl, request])]);
50
57
 
51
58
  if (!resolvedUrl) {
52
59
  return;
@@ -43,9 +43,10 @@ function parseNode(atRule, key) {
43
43
  throw error;
44
44
  }
45
45
 
46
+ const rawParams = atRule.raws && atRule.raws[key] && typeof atRule.raws[key].raw !== "undefined" ? atRule.raws[key].raw : atRule[key];
46
47
  const {
47
48
  nodes: paramsNodes
48
- } = (0, _postcssValueParser.default)(atRule[key]); // No nodes - `@import ;`
49
+ } = (0, _postcssValueParser.default)(rawParams); // No nodes - `@import ;`
49
50
  // Invalid type - `@import foo-bar;`
50
51
 
51
52
  if (paramsNodes.length === 0 || paramsNodes[0].type !== "string" && paramsNodes[0].type !== "function") {
@@ -92,11 +93,42 @@ function parseNode(atRule, key) {
92
93
  throw error;
93
94
  }
94
95
 
95
- const mediaNodes = paramsNodes.slice(1);
96
+ const additionalNodes = paramsNodes.slice(1);
97
+ let supports;
98
+ let layer;
96
99
  let media;
97
100
 
98
- if (mediaNodes.length > 0) {
99
- media = _postcssValueParser.default.stringify(mediaNodes).trim().toLowerCase();
101
+ if (additionalNodes.length > 0) {
102
+ let nodes = [];
103
+
104
+ for (const node of additionalNodes) {
105
+ nodes.push(node);
106
+ const isLayerFunction = node.type === "function" && node.value.toLowerCase() === "layer";
107
+ const isLayerWord = node.type === "word" && node.value.toLowerCase() === "layer";
108
+
109
+ if (isLayerFunction || isLayerWord) {
110
+ if (isLayerFunction) {
111
+ nodes.splice(nodes.length - 1, 1, ...node.nodes);
112
+ } else {
113
+ nodes.splice(nodes.length - 1, 1, {
114
+ type: "string",
115
+ value: "",
116
+ unclosed: false
117
+ });
118
+ }
119
+
120
+ layer = _postcssValueParser.default.stringify(nodes).trim().toLowerCase();
121
+ nodes = [];
122
+ } else if (node.type === "function" && node.value.toLowerCase() === "supports") {
123
+ nodes.splice(nodes.length - 1, 1, ...node.nodes);
124
+ supports = _postcssValueParser.default.stringify(nodes).trim().toLowerCase();
125
+ nodes = [];
126
+ }
127
+ }
128
+
129
+ if (nodes.length > 0) {
130
+ media = _postcssValueParser.default.stringify(nodes).trim().toLowerCase();
131
+ }
100
132
  } // eslint-disable-next-line consistent-return
101
133
 
102
134
 
@@ -104,6 +136,8 @@ function parseNode(atRule, key) {
104
136
  atRule,
105
137
  prefix,
106
138
  url,
139
+ layer,
140
+ supports,
107
141
  media,
108
142
  isRequestable
109
143
  };
@@ -118,6 +152,11 @@ const plugin = (options = {}) => {
118
152
  return {
119
153
  AtRule: {
120
154
  import(atRule) {
155
+ if (options.isCSSStyleSheet) {
156
+ options.loaderContext.emitError(new Error(atRule.error("'@import' rules are not allowed here and will not be processed").message));
157
+ return;
158
+ }
159
+
121
160
  let parsedAtRule;
122
161
 
123
162
  try {
@@ -142,17 +181,30 @@ const plugin = (options = {}) => {
142
181
  return;
143
182
  }
144
183
 
184
+ const {
185
+ loaderContext
186
+ } = options;
187
+ const resolver = loaderContext.getResolve({
188
+ dependencyType: "css",
189
+ conditionNames: ["style"],
190
+ mainFields: ["css", "style", "main", "..."],
191
+ mainFiles: ["index", "..."],
192
+ extensions: [".css", "..."],
193
+ preferRelative: true
194
+ });
145
195
  const resolvedAtRules = await Promise.all(parsedAtRules.map(async parsedAtRule => {
146
196
  const {
147
197
  atRule,
148
198
  isRequestable,
149
199
  prefix,
150
200
  url,
201
+ layer,
202
+ supports,
151
203
  media
152
204
  } = parsedAtRule;
153
205
 
154
206
  if (options.filter) {
155
- const needKeep = await options.filter(url, media);
207
+ const needKeep = await options.filter(url, media, loaderContext.resourcePath, supports, layer);
156
208
 
157
209
  if (!needKeep) {
158
210
  return;
@@ -160,18 +212,14 @@ const plugin = (options = {}) => {
160
212
  }
161
213
 
162
214
  if (isRequestable) {
163
- const request = (0, _utils.requestify)(url, options.rootContext);
164
- const {
165
- resolver,
166
- context
167
- } = options;
168
- const resolvedUrl = await (0, _utils.resolveRequests)(resolver, context, [...new Set([request, url])]);
215
+ const request = (0, _utils.requestify)(url, loaderContext.rootContext);
216
+ const resolvedUrl = await (0, _utils.resolveRequests)(resolver, loaderContext.context, [...new Set([request, url])]);
169
217
 
170
218
  if (!resolvedUrl) {
171
219
  return;
172
220
  }
173
221
 
174
- if (resolvedUrl === options.resourcePath) {
222
+ if (resolvedUrl === loaderContext.resourcePath) {
175
223
  atRule.remove();
176
224
  return;
177
225
  }
@@ -180,6 +228,8 @@ const plugin = (options = {}) => {
180
228
 
181
229
  return {
182
230
  url: resolvedUrl,
231
+ layer,
232
+ supports,
183
233
  media,
184
234
  prefix,
185
235
  isRequestable
@@ -190,6 +240,8 @@ const plugin = (options = {}) => {
190
240
 
191
241
  return {
192
242
  url,
243
+ layer,
244
+ supports,
193
245
  media,
194
246
  prefix,
195
247
  isRequestable
@@ -208,12 +260,16 @@ const plugin = (options = {}) => {
208
260
  const {
209
261
  url,
210
262
  isRequestable,
263
+ layer,
264
+ supports,
211
265
  media
212
266
  } = resolvedAtRule;
213
267
 
214
268
  if (!isRequestable) {
215
269
  options.api.push({
216
270
  url,
271
+ layer,
272
+ supports,
217
273
  media,
218
274
  index
219
275
  }); // eslint-disable-next-line no-continue
@@ -240,6 +296,8 @@ const plugin = (options = {}) => {
240
296
 
241
297
  options.api.push({
242
298
  importName,
299
+ layer,
300
+ supports,
243
301
  media,
244
302
  index
245
303
  });
@@ -4,37 +4,55 @@
4
4
  MIT License http://www.opensource.org/licenses/mit-license.php
5
5
  Author Tobias Koppers @sokra
6
6
  */
7
- // css base code, injected by the css-loader
8
- // eslint-disable-next-line func-names
9
7
  module.exports = function (cssWithMappingToString) {
10
8
  var list = []; // return the list of modules as css string
11
9
 
12
10
  list.toString = function toString() {
13
11
  return this.map(function (item) {
14
- var content = cssWithMappingToString(item);
12
+ var content = "";
13
+ var needLayer = typeof item[5] !== "undefined";
14
+
15
+ if (item[4]) {
16
+ content += "@supports (".concat(item[4], ") {");
17
+ }
18
+
19
+ if (item[2]) {
20
+ content += "@media ".concat(item[2], " {");
21
+ }
22
+
23
+ if (needLayer) {
24
+ content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
25
+ }
26
+
27
+ content += cssWithMappingToString(item);
28
+
29
+ if (needLayer) {
30
+ content += "}";
31
+ }
15
32
 
16
33
  if (item[2]) {
17
- return "@media ".concat(item[2], " {").concat(content, "}");
34
+ content += "}";
35
+ }
36
+
37
+ if (item[4]) {
38
+ content += "}";
18
39
  }
19
40
 
20
41
  return content;
21
42
  }).join("");
22
43
  }; // import a list of modules into the list
23
- // eslint-disable-next-line func-names
24
44
 
25
45
 
26
- list.i = function (modules, mediaQuery, dedupe) {
46
+ list.i = function i(modules, media, dedupe, supports, layer) {
27
47
  if (typeof modules === "string") {
28
- // eslint-disable-next-line no-param-reassign
29
- modules = [[null, modules, ""]];
48
+ modules = [[null, modules, undefined]];
30
49
  }
31
50
 
32
51
  var alreadyImportedModules = {};
33
52
 
34
53
  if (dedupe) {
35
- for (var i = 0; i < this.length; i++) {
36
- // eslint-disable-next-line prefer-destructuring
37
- var id = this[i][0];
54
+ for (var _i = 0; _i < this.length; _i++) {
55
+ var id = this[_i][0];
38
56
 
39
57
  if (id != null) {
40
58
  alreadyImportedModules[id] = true;
@@ -42,19 +60,37 @@ module.exports = function (cssWithMappingToString) {
42
60
  }
43
61
  }
44
62
 
45
- for (var _i = 0; _i < modules.length; _i++) {
46
- var item = [].concat(modules[_i]);
63
+ for (var _i2 = 0; _i2 < modules.length; _i2++) {
64
+ var item = [].concat(modules[_i2]);
47
65
 
48
66
  if (dedupe && alreadyImportedModules[item[0]]) {
49
- // eslint-disable-next-line no-continue
50
67
  continue;
51
68
  }
52
69
 
53
- if (mediaQuery) {
70
+ if (typeof layer !== "undefined") {
71
+ if (typeof item[5] === "undefined") {
72
+ item[5] = layer;
73
+ } else {
74
+ item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
75
+ item[5] = layer;
76
+ }
77
+ }
78
+
79
+ if (media) {
54
80
  if (!item[2]) {
55
- item[2] = mediaQuery;
81
+ item[2] = media;
82
+ } else {
83
+ item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
84
+ item[2] = media;
85
+ }
86
+ }
87
+
88
+ if (supports) {
89
+ if (!item[4]) {
90
+ item[4] = "".concat(supports);
56
91
  } else {
57
- item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
92
+ item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
93
+ item[4] = supports;
58
94
  }
59
95
  }
60
96
 
@@ -2,24 +2,20 @@
2
2
 
3
3
  module.exports = function (url, options) {
4
4
  if (!options) {
5
- // eslint-disable-next-line no-param-reassign
6
5
  options = {};
7
6
  }
8
7
 
9
8
  if (!url) {
10
9
  return url;
11
- } // eslint-disable-next-line no-underscore-dangle, no-param-reassign
12
-
10
+ }
13
11
 
14
12
  url = String(url.__esModule ? url.default : url); // If url is already wrapped in quotes, remove them
15
13
 
16
14
  if (/^['"].*['"]$/.test(url)) {
17
- // eslint-disable-next-line no-param-reassign
18
15
  url = url.slice(1, -1);
19
16
  }
20
17
 
21
18
  if (options.hash) {
22
- // eslint-disable-next-line no-param-reassign
23
19
  url += options.hash;
24
20
  } // Should url be wrapped?
25
21
  // See https://drafts.csswg.org/css-values-3/#urls
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ module.exports = function (i) {
4
+ return i[1];
5
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ module.exports = function (item) {
4
+ var content = item[1];
5
+ var cssMapping = item[3];
6
+
7
+ if (!cssMapping) {
8
+ return content;
9
+ }
10
+
11
+ if (typeof btoa === "function") {
12
+ var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
13
+ var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
14
+ var sourceMapping = "/*# ".concat(data, " */");
15
+ var sourceURLs = cssMapping.sources.map(function (source) {
16
+ return "/*# sourceURL=".concat(cssMapping.sourceRoot || "").concat(source, " */");
17
+ });
18
+ return [content].concat(sourceURLs).concat([sourceMapping]).join("\n");
19
+ }
20
+
21
+ return [content].join("\n");
22
+ };
package/dist/utils.js CHANGED
@@ -313,14 +313,20 @@ function escapeLocalIdent(localident) {
313
313
  }
314
314
 
315
315
  function defaultGetLocalIdent(loaderContext, localIdentName, localName, options) {
316
- let relativeMatchResource = ""; // eslint-disable-next-line no-underscore-dangle
316
+ let relativeMatchResource = "";
317
+ const {
318
+ context
319
+ } = options;
320
+ const {
321
+ resourcePath
322
+ } = loaderContext; // eslint-disable-next-line no-underscore-dangle
317
323
 
318
324
  if (loaderContext._module && loaderContext._module.matchResource) {
319
325
  relativeMatchResource = `${normalizePath( // eslint-disable-next-line no-underscore-dangle
320
- _path.default.relative(options.context, loaderContext._module.matchResource))}\x00`;
326
+ _path.default.relative(context, loaderContext._module.matchResource))}\x00`;
321
327
  }
322
328
 
323
- const relativeResourcePath = normalizePath(_path.default.relative(options.context, loaderContext.resourcePath)); // eslint-disable-next-line no-param-reassign
329
+ const relativeResourcePath = normalizePath(_path.default.relative(context, resourcePath)); // eslint-disable-next-line no-param-reassign
324
330
 
325
331
  options.content = `${relativeMatchResource}${relativeResourcePath}\x00${localName}`;
326
332
  let {
@@ -328,13 +334,13 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
328
334
  hashDigest,
329
335
  hashDigestLength
330
336
  } = options;
331
- const mathes = localIdentName.match(/\[(?:([^:\]]+):)?(?:(hash|contenthash|fullhash))(?::([a-z]+\d*))?(?::(\d+))?\]/i);
337
+ const matches = localIdentName.match(/\[(?:([^:\]]+):)?(?:(hash|contenthash|fullhash))(?::([a-z]+\d*))?(?::(\d+))?\]/i);
332
338
 
333
- if (mathes) {
334
- const hashName = mathes[2] || hashFunction;
335
- hashFunction = mathes[1] || hashFunction;
336
- hashDigest = mathes[3] || hashDigest;
337
- hashDigestLength = mathes[4] || hashDigestLength; // `hash` and `contenthash` are same in `loader-utils` context
339
+ if (matches) {
340
+ const hashName = matches[2] || hashFunction;
341
+ hashFunction = matches[1] || hashFunction;
342
+ hashDigest = matches[3] || hashDigest;
343
+ hashDigestLength = matches[4] || hashDigestLength; // `hash` and `contenthash` are same in `loader-utils` context
338
344
  // let's keep `hash` for backward compatibility
339
345
  // eslint-disable-next-line no-param-reassign
340
346
 
@@ -355,13 +361,13 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
355
361
  hash.update(options.content);
356
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
357
363
 
358
- const ext = _path.default.extname(loaderContext.resourcePath);
364
+ const ext = _path.default.extname(resourcePath);
359
365
 
360
- const base = _path.default.basename(loaderContext.resourcePath);
366
+ const base = _path.default.basename(resourcePath);
361
367
 
362
368
  const name = base.slice(0, base.length - ext.length);
363
369
  const data = {
364
- filename: _path.default.relative(options.context, loaderContext.resourcePath),
370
+ filename: _path.default.relative(context, resourcePath),
365
371
  contentHash: localIdentHash,
366
372
  chunk: {
367
373
  name,
@@ -372,8 +378,22 @@ function defaultGetLocalIdent(loaderContext, localIdentName, localName, options)
372
378
 
373
379
  let result = loaderContext._compilation.getPath(localIdentName, data);
374
380
 
381
+ if (/\[folder\]/gi.test(result)) {
382
+ const dirname = _path.default.dirname(resourcePath);
383
+
384
+ let directory = normalizePath(_path.default.relative(context, `${dirname + _path.default.sep}_`));
385
+ directory = directory.substr(0, directory.length - 1);
386
+ let folder = "";
387
+
388
+ if (directory.length > 1) {
389
+ folder = _path.default.basename(directory);
390
+ }
391
+
392
+ result = result.replace(/\[folder\]/gi, () => folder);
393
+ }
394
+
375
395
  if (options.regExp) {
376
- const match = loaderContext.resourcePath.match(options.regExp);
396
+ const match = resourcePath.match(options.regExp);
377
397
 
378
398
  if (match) {
379
399
  match.forEach((matched, i) => {
@@ -462,22 +482,14 @@ function getFilter(filter, resourcePath) {
462
482
  }
463
483
 
464
484
  function getValidLocalName(localName, exportLocalsConvention) {
465
- if (typeof exportLocalsConvention === "function") {
466
- const result = exportLocalsConvention(localName);
467
- return Array.isArray(result) ? result[0] : result;
468
- }
469
-
470
- if (exportLocalsConvention === "dashesOnly") {
471
- return dashesCamelCase(localName);
472
- }
473
-
474
- return camelCase(localName);
485
+ const result = exportLocalsConvention(localName);
486
+ return Array.isArray(result) ? result[0] : result;
475
487
  }
476
488
 
477
489
  const IS_MODULES = /\.module(s)?\.\w+$/i;
478
490
  const IS_ICSS = /\.icss\.\w+$/i;
479
491
 
480
- function getModulesOptions(rawOptions, loaderContext) {
492
+ function getModulesOptions(rawOptions, exportType, loaderContext) {
481
493
  if (typeof rawOptions.modules === "boolean" && rawOptions.modules === false) {
482
494
  return false;
483
495
  }
@@ -507,6 +519,7 @@ function getModulesOptions(rawOptions, loaderContext) {
507
519
  const {
508
520
  outputOptions
509
521
  } = loaderContext._compilation;
522
+ const needNamedExport = exportType === "css-style-sheet" || exportType === "string";
510
523
  const modulesOptions = {
511
524
  auto,
512
525
  mode: "local",
@@ -521,11 +534,44 @@ function getModulesOptions(rawOptions, loaderContext) {
521
534
  localIdentRegExp: undefined,
522
535
  // eslint-disable-next-line no-undefined
523
536
  getLocalIdent: undefined,
524
- namedExport: false,
525
- exportLocalsConvention: rawModulesOptions.namedExport === true && typeof rawModulesOptions.exportLocalsConvention === "undefined" ? "camelCaseOnly" : "asIs",
537
+ namedExport: needNamedExport || false,
538
+ exportLocalsConvention: (rawModulesOptions.namedExport === true || needNamedExport) && typeof rawModulesOptions.exportLocalsConvention === "undefined" ? "camelCaseOnly" : "asIs",
526
539
  exportOnlyLocals: false,
527
540
  ...rawModulesOptions
528
541
  };
542
+ let exportLocalsConventionType;
543
+
544
+ if (typeof modulesOptions.exportLocalsConvention === "string") {
545
+ exportLocalsConventionType = modulesOptions.exportLocalsConvention;
546
+
547
+ modulesOptions.exportLocalsConvention = name => {
548
+ switch (exportLocalsConventionType) {
549
+ case "camelCase":
550
+ {
551
+ return [name, camelCase(name)];
552
+ }
553
+
554
+ case "camelCaseOnly":
555
+ {
556
+ return camelCase(name);
557
+ }
558
+
559
+ case "dashes":
560
+ {
561
+ return [name, dashesCamelCase(name)];
562
+ }
563
+
564
+ case "dashesOnly":
565
+ {
566
+ return dashesCamelCase(name);
567
+ }
568
+
569
+ case "asIs":
570
+ default:
571
+ return name;
572
+ }
573
+ };
574
+ }
529
575
 
530
576
  if (typeof modulesOptions.auto === "boolean") {
531
577
  const isModules = modulesOptions.auto && IS_MODULES.test(resourcePath);
@@ -560,12 +606,22 @@ function getModulesOptions(rawOptions, loaderContext) {
560
606
  modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath);
561
607
  }
562
608
 
609
+ if (needNamedExport) {
610
+ if (rawOptions.esModule === false) {
611
+ throw new Error("The 'exportType' option with the 'css-style-sheet' or 'string' value requires the 'esModules' option to be enabled");
612
+ }
613
+
614
+ if (modulesOptions.namedExport === false) {
615
+ throw new Error("The 'exportType' option with the 'css-style-sheet' or 'string' value requires the 'modules.namedExport' option to be enabled");
616
+ }
617
+ }
618
+
563
619
  if (modulesOptions.namedExport === true) {
564
620
  if (rawOptions.esModule === false) {
565
- throw new Error('The "modules.namedExport" option requires the "esModules" option to be enabled');
621
+ throw new Error("The 'modules.namedExport' option requires the 'esModules' option to be enabled");
566
622
  }
567
623
 
568
- if (typeof modulesOptions.exportLocalsConvention === "string" && modulesOptions.exportLocalsConvention !== "camelCaseOnly" && modulesOptions.exportLocalsConvention !== "dashesOnly") {
624
+ if (typeof exportLocalsConventionType === "string" && exportLocalsConventionType !== "camelCaseOnly" && exportLocalsConventionType !== "dashesOnly") {
569
625
  throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly" or "dashesOnly"');
570
626
  }
571
627
  }
@@ -574,14 +630,16 @@ function getModulesOptions(rawOptions, loaderContext) {
574
630
  }
575
631
 
576
632
  function normalizeOptions(rawOptions, loaderContext) {
577
- const modulesOptions = getModulesOptions(rawOptions, loaderContext);
633
+ const exportType = typeof rawOptions.exportType === "undefined" ? "array" : rawOptions.exportType;
634
+ const modulesOptions = getModulesOptions(rawOptions, exportType, loaderContext);
578
635
  return {
579
636
  url: typeof rawOptions.url === "undefined" ? true : rawOptions.url,
580
637
  import: typeof rawOptions.import === "undefined" ? true : rawOptions.import,
581
638
  modules: modulesOptions,
582
639
  sourceMap: typeof rawOptions.sourceMap === "boolean" ? rawOptions.sourceMap : loaderContext.sourceMap,
583
640
  importLoaders: typeof rawOptions.importLoaders === "string" ? parseInt(rawOptions.importLoaders, 10) : rawOptions.importLoaders,
584
- esModule: typeof rawOptions.esModule === "undefined" ? true : rawOptions.esModule
641
+ esModule: typeof rawOptions.esModule === "undefined" ? true : rawOptions.esModule,
642
+ exportType
585
643
  };
586
644
  }
587
645
 
@@ -810,6 +868,34 @@ function normalizeSourceMapForRuntime(map, loaderContext) {
810
868
  return JSON.stringify(resultMap);
811
869
  }
812
870
 
871
+ function printParams(media, dedupe, supports, layer) {
872
+ let result = "";
873
+
874
+ if (typeof layer !== "undefined") {
875
+ result = `, ${JSON.stringify(layer)}`;
876
+ }
877
+
878
+ if (typeof supports !== "undefined") {
879
+ result = `, ${JSON.stringify(supports)}${result}`;
880
+ } else if (result.length > 0) {
881
+ result = `, undefined${result}`;
882
+ }
883
+
884
+ if (dedupe) {
885
+ result = `, true${result}`;
886
+ } else if (result.length > 0) {
887
+ result = `, false${result}`;
888
+ }
889
+
890
+ if (media) {
891
+ result = `${JSON.stringify(media)}${result}`;
892
+ } else if (result.length > 0) {
893
+ result = `""${result}`;
894
+ }
895
+
896
+ return result;
897
+ }
898
+
813
899
  function getModuleCode(result, api, replacements, options, loaderContext) {
814
900
  if (options.modules.exportOnlyLocals === true) {
815
901
  return "";
@@ -817,15 +903,25 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
817
903
 
818
904
  const sourceMapValue = options.sourceMap ? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}` : "";
819
905
  let code = JSON.stringify(result.css);
820
- let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap ? "___CSS_LOADER_API_SOURCEMAP_IMPORT___" : "function(i){return i[1]}"});\n`;
906
+ let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap ? "___CSS_LOADER_API_SOURCEMAP_IMPORT___" : "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___"});\n`;
821
907
 
822
908
  for (const item of api) {
823
909
  const {
824
910
  url,
911
+ layer,
912
+ supports,
825
913
  media,
826
914
  dedupe
827
915
  } = item;
828
- beforeCode += url ? `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(`@import url(${url});`)}${media ? `, ${JSON.stringify(media)}` : ""}]);\n` : `___CSS_LOADER_EXPORT___.i(${item.importName}${media ? `, ${JSON.stringify(media)}` : dedupe ? ', ""' : ""}${dedupe ? ", true" : ""});\n`;
916
+
917
+ if (url) {
918
+ // eslint-disable-next-line no-undefined
919
+ const printedParam = printParams(media, undefined, supports, layer);
920
+ beforeCode += `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(`@import url(${url});`)}${printedParam.length > 0 ? `, ${printedParam}` : ""}]);\n`;
921
+ } else {
922
+ const printedParam = printParams(media, dedupe, supports, layer);
923
+ beforeCode += `___CSS_LOADER_EXPORT___.i(${item.importName}${printedParam.length > 0 ? `, ${printedParam}` : ""});\n`;
924
+ }
829
925
  }
830
926
 
831
927
  for (const item of replacements) {
@@ -847,7 +943,14 @@ function getModuleCode(result, api, replacements, options, loaderContext) {
847
943
  beforeCode += `var ${replacementName} = ___CSS_LOADER_GET_URL_IMPORT___(${importName}${preparedOptions});\n`;
848
944
  code = code.replace(new RegExp(replacementName, "g"), () => `" + ${replacementName} + "`);
849
945
  }
850
- }
946
+ } // Indexes description:
947
+ // 0 - module id
948
+ // 1 - CSS code
949
+ // 2 - media
950
+ // 3 - source map
951
+ // 4 - supports
952
+ // 5 - layer
953
+
851
954
 
852
955
  return `${beforeCode}// Module\n___CSS_LOADER_EXPORT___.push([module.id, ${code}, ""${sourceMapValue}]);\n`;
853
956
  }
@@ -856,107 +959,92 @@ function dashesCamelCase(str) {
856
959
  return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
857
960
  }
858
961
 
859
- function getExportCode(exports, replacements, needToUseIcssPlugin, options) {
962
+ function getExportCode(exports, replacements, icssPluginUsed, options) {
860
963
  let code = "// Exports\n";
861
964
 
862
- if (!needToUseIcssPlugin) {
863
- code += `${options.esModule ? "export default" : "module.exports ="} ___CSS_LOADER_EXPORT___;\n`;
864
- return code;
865
- }
965
+ if (icssPluginUsed) {
966
+ let localsCode = "";
866
967
 
867
- let localsCode = "";
968
+ const addExportToLocalsCode = (names, value) => {
969
+ const normalizedNames = Array.isArray(names) ? new Set(names) : new Set([names]);
868
970
 
869
- const addExportToLocalsCode = (names, value) => {
870
- const normalizedNames = Array.isArray(names) ? new Set(names) : new Set([names]);
971
+ for (const name of normalizedNames) {
972
+ if (options.modules.namedExport) {
973
+ localsCode += `export var ${name} = ${JSON.stringify(value)};\n`;
974
+ } else {
975
+ if (localsCode) {
976
+ localsCode += `,\n`;
977
+ }
871
978
 
872
- for (const name of normalizedNames) {
873
- if (options.modules.namedExport) {
874
- localsCode += `export var ${name} = ${JSON.stringify(value)};\n`;
875
- } else {
876
- if (localsCode) {
877
- localsCode += `,\n`;
979
+ localsCode += `\t${JSON.stringify(name)}: ${JSON.stringify(value)}`;
878
980
  }
879
-
880
- localsCode += `\t${JSON.stringify(name)}: ${JSON.stringify(value)}`;
881
981
  }
982
+ };
983
+
984
+ for (const {
985
+ name,
986
+ value
987
+ } of exports) {
988
+ addExportToLocalsCode(options.modules.exportLocalsConvention(name), value);
882
989
  }
883
- };
884
990
 
885
- for (const {
886
- name,
887
- value
888
- } of exports) {
889
- if (typeof options.modules.exportLocalsConvention === "function") {
890
- addExportToLocalsCode(options.modules.exportLocalsConvention(name), value); // eslint-disable-next-line no-continue
991
+ for (const item of replacements) {
992
+ const {
993
+ replacementName,
994
+ localName
995
+ } = item;
891
996
 
892
- continue;
997
+ if (localName) {
998
+ const {
999
+ importName
1000
+ } = item;
1001
+ localsCode = localsCode.replace(new RegExp(replacementName, "g"), () => {
1002
+ if (options.modules.namedExport) {
1003
+ return `" + ${importName}_NAMED___[${JSON.stringify(getValidLocalName(localName, options.modules.exportLocalsConvention))}] + "`;
1004
+ } else if (options.modules.exportOnlyLocals) {
1005
+ return `" + ${importName}[${JSON.stringify(localName)}] + "`;
1006
+ }
1007
+
1008
+ return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
1009
+ });
1010
+ } else {
1011
+ localsCode = localsCode.replace(new RegExp(replacementName, "g"), () => `" + ${replacementName} + "`);
1012
+ }
893
1013
  }
894
1014
 
895
- switch (options.modules.exportLocalsConvention) {
896
- case "camelCase":
897
- {
898
- const modifiedName = camelCase(name);
899
- addExportToLocalsCode([name, modifiedName], value);
900
- break;
901
- }
902
-
903
- case "camelCaseOnly":
904
- {
905
- addExportToLocalsCode(camelCase(name), value);
906
- break;
907
- }
1015
+ if (options.modules.exportOnlyLocals) {
1016
+ code += options.modules.namedExport ? localsCode : `${options.esModule ? "export default" : "module.exports ="} {\n${localsCode}\n};\n`;
1017
+ return code;
1018
+ }
908
1019
 
909
- case "dashes":
910
- {
911
- const modifiedName = dashesCamelCase(name);
912
- addExportToLocalsCode([name, modifiedName], value);
913
- break;
914
- }
1020
+ code += options.modules.namedExport ? localsCode : `___CSS_LOADER_EXPORT___.locals = {${localsCode ? `\n${localsCode}\n` : ""}};\n`;
1021
+ }
915
1022
 
916
- case "dashesOnly":
917
- {
918
- addExportToLocalsCode(dashesCamelCase(name), value);
919
- break;
920
- }
1023
+ const isCSSStyleSheetExport = options.exportType === "css-style-sheet";
921
1024
 
922
- case "asIs":
923
- default:
924
- addExportToLocalsCode(name, value);
925
- break;
926
- }
1025
+ if (isCSSStyleSheetExport) {
1026
+ code += "var ___CSS_LOADER_STYLE_SHEET___ = new CSSStyleSheet();\n";
1027
+ code += "___CSS_LOADER_STYLE_SHEET___.replaceSync(___CSS_LOADER_EXPORT___.toString());\n";
927
1028
  }
928
1029
 
929
- for (const item of replacements) {
930
- const {
931
- replacementName,
932
- localName
933
- } = item;
1030
+ let finalExport;
934
1031
 
935
- if (localName) {
936
- const {
937
- importName
938
- } = item;
939
- localsCode = localsCode.replace(new RegExp(replacementName, "g"), () => {
940
- if (options.modules.namedExport) {
941
- return `" + ${importName}_NAMED___[${JSON.stringify(getValidLocalName(localName, options.modules.exportLocalsConvention))}] + "`;
942
- } else if (options.modules.exportOnlyLocals) {
943
- return `" + ${importName}[${JSON.stringify(localName)}] + "`;
944
- }
1032
+ switch (options.exportType) {
1033
+ case "string":
1034
+ finalExport = "___CSS_LOADER_EXPORT___.toString()";
1035
+ break;
945
1036
 
946
- return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
947
- });
948
- } else {
949
- localsCode = localsCode.replace(new RegExp(replacementName, "g"), () => `" + ${replacementName} + "`);
950
- }
951
- }
1037
+ case "css-style-sheet":
1038
+ finalExport = "___CSS_LOADER_STYLE_SHEET___";
1039
+ break;
952
1040
 
953
- if (options.modules.exportOnlyLocals) {
954
- code += options.modules.namedExport ? localsCode : `${options.esModule ? "export default" : "module.exports ="} {\n${localsCode}\n};\n`;
955
- return code;
1041
+ default:
1042
+ case "array":
1043
+ finalExport = "___CSS_LOADER_EXPORT___";
1044
+ break;
956
1045
  }
957
1046
 
958
- code += options.modules.namedExport ? localsCode : `___CSS_LOADER_EXPORT___.locals = {${localsCode ? `\n${localsCode}\n` : ""}};\n`;
959
- code += `${options.esModule ? "export default" : "module.exports ="} ___CSS_LOADER_EXPORT___;\n`;
1047
+ code += `${options.esModule ? "export default" : "module.exports ="} ${finalExport};\n`;
960
1048
  return code;
961
1049
  }
962
1050
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-loader",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "description": "css loader module for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/css-loader",
@@ -55,14 +55,14 @@
55
55
  "@babel/cli": "^7.14.5",
56
56
  "@babel/core": "^7.14.6",
57
57
  "@babel/preset-env": "^7.14.7",
58
- "@commitlint/cli": "^12.1.4",
59
- "@commitlint/config-conventional": "^12.1.4",
58
+ "@commitlint/cli": "^13.1.0",
59
+ "@commitlint/config-conventional": "^13.1.0",
60
60
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
61
61
  "babel-jest": "^27.0.6",
62
62
  "cross-env": "^7.0.3",
63
63
  "del": "^6.0.0",
64
64
  "del-cli": "^4.0.1",
65
- "es-check": "^5.2.4",
65
+ "es-check": "^6.0.0",
66
66
  "eslint": "^7.30.0",
67
67
  "eslint-config-prettier": "^8.3.0",
68
68
  "eslint-plugin-import": "^2.23.4",
@@ -83,7 +83,7 @@
83
83
  "standard-version": "^9.3.1",
84
84
  "strip-ansi": "^6.0.0",
85
85
  "style-loader": "^3.1.0",
86
- "stylus": "^0.54.8",
86
+ "stylus": "^0.55.0",
87
87
  "stylus-loader": "^6.1.0",
88
88
  "url-loader": "^4.1.1",
89
89
  "webpack": "^5.45.1"
@@ -1,36 +0,0 @@
1
- "use strict";
2
-
3
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
-
5
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
6
-
7
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
-
9
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
10
-
11
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
12
-
13
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
14
-
15
- module.exports = function cssWithMappingToString(item) {
16
- var _item = _slicedToArray(item, 4),
17
- content = _item[1],
18
- cssMapping = _item[3];
19
-
20
- if (!cssMapping) {
21
- return content;
22
- }
23
-
24
- if (typeof btoa === "function") {
25
- // eslint-disable-next-line no-undef
26
- var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
27
- var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
28
- var sourceMapping = "/*# ".concat(data, " */");
29
- var sourceURLs = cssMapping.sources.map(function (source) {
30
- return "/*# sourceURL=".concat(cssMapping.sourceRoot || "").concat(source, " */");
31
- });
32
- return [content].concat(sourceURLs).concat([sourceMapping]).join("\n");
33
- }
34
-
35
- return [content].join("\n");
36
- };