css-loader 2.1.1 → 3.2.1

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.
@@ -9,6 +9,8 @@ var _postcss = _interopRequireDefault(require("postcss"));
9
9
 
10
10
  var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
11
11
 
12
+ var _utils = require("../utils");
13
+
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
15
 
14
16
  const pluginName = 'postcss-url-parser';
@@ -54,68 +56,73 @@ function walkUrls(parsed, callback) {
54
56
  });
55
57
  }
56
58
 
57
- function walkDeclsWithUrl(css, result, filter) {
58
- const items = [];
59
- css.walkDecls(decl => {
60
- if (!needParseDecl.test(decl.value)) {
59
+ function getUrlsFromValue(value, result, filter, decl = null) {
60
+ if (!needParseDecl.test(value)) {
61
+ return;
62
+ }
63
+
64
+ const parsed = (0, _postcssValueParser.default)(value);
65
+ const urls = [];
66
+ walkUrls(parsed, (node, url, needQuotes) => {
67
+ if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
68
+ result.warn(`Unable to find uri in '${decl ? decl.toString() : value}'`, decl ? {
69
+ node: decl
70
+ } : {});
61
71
  return;
62
72
  }
63
73
 
64
- const parsed = (0, _postcssValueParser.default)(decl.value);
65
- const urls = [];
66
- walkUrls(parsed, (node, url, needQuotes) => {
67
- if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
68
- result.warn(`Unable to find uri in '${decl.toString()}'`, {
69
- node: decl
70
- });
71
- return;
72
- }
73
-
74
- if (filter && !filter(url)) {
75
- return;
76
- }
74
+ if (filter && !filter(url)) {
75
+ return;
76
+ }
77
77
 
78
- urls.push({
79
- url,
80
- needQuotes
81
- });
78
+ urls.push({
79
+ url,
80
+ needQuotes
82
81
  });
82
+ }); // eslint-disable-next-line consistent-return
83
+
84
+ return {
85
+ parsed,
86
+ urls
87
+ };
88
+ }
83
89
 
84
- if (urls.length === 0) {
90
+ function walkDeclsWithUrl(css, result, filter) {
91
+ const items = [];
92
+ css.walkDecls(decl => {
93
+ const item = getUrlsFromValue(decl.value, result, filter, decl);
94
+
95
+ if (!item) {
96
+ return;
97
+ }
98
+
99
+ if (item.urls.length === 0) {
85
100
  return;
86
101
  }
87
102
 
88
103
  items.push({
89
104
  decl,
90
- parsed,
91
- urls
105
+ parsed: item.parsed,
106
+ urls: item.urls
92
107
  });
93
108
  });
94
109
  return items;
95
110
  }
96
111
 
97
- function uniqWith(array, comparator) {
98
- return array.reduce((acc, d) => !acc.some(item => comparator(d, item)) ? [...acc, d] : acc, []);
99
- }
100
-
101
- function flatten(array) {
102
- return array.reduce((a, b) => a.concat(b), []);
103
- }
104
-
105
- function isEqual(value, other) {
106
- return value.url === other.url && value.needQuotes === other.needQuotes;
107
- }
108
-
109
112
  var _default = _postcss.default.plugin(pluginName, (options = {}) => function process(css, result) {
110
113
  const traversed = walkDeclsWithUrl(css, result, options.filter);
111
- const paths = uniqWith(flatten(traversed.map(item => item.urls)), isEqual);
114
+ const paths = (0, _utils.uniqWith)((0, _utils.flatten)(traversed.map(item => item.urls)), (value, other) => value.url === other.url && value.needQuotes === other.needQuotes);
112
115
 
113
116
  if (paths.length === 0) {
114
117
  return;
115
118
  }
116
119
 
117
120
  const placeholders = [];
121
+ let hasUrlHelper = false;
118
122
  paths.forEach((path, index) => {
123
+ const {
124
+ loaderContext
125
+ } = options;
119
126
  const placeholder = `___CSS_LOADER_URL___${index}___`;
120
127
  const {
121
128
  url,
@@ -125,14 +132,27 @@ var _default = _postcss.default.plugin(pluginName, (options = {}) => function pr
125
132
  placeholder,
126
133
  path
127
134
  });
135
+
136
+ if (!hasUrlHelper) {
137
+ result.messages.push({
138
+ pluginName,
139
+ type: 'import',
140
+ import: (0, _utils.getUrlHelperCode)(loaderContext)
141
+ }); // eslint-disable-next-line no-param-reassign
142
+
143
+ hasUrlHelper = true;
144
+ }
145
+
128
146
  result.messages.push({
129
147
  pluginName,
130
- type: 'url',
131
- item: {
148
+ type: 'import',
149
+ import: (0, _utils.getUrlItemCode)({
132
150
  url,
133
151
  placeholder,
134
152
  needQuotes
135
- }
153
+ }, loaderContext),
154
+ importType: 'url',
155
+ placeholder
136
156
  });
137
157
  });
138
158
  traversed.forEach(item => {
@@ -5,6 +5,7 @@
5
5
  Author Tobias Koppers @sokra
6
6
  */
7
7
  // css base code, injected by the css-loader
8
+ // eslint-disable-next-line func-names
8
9
  module.exports = function (useSourceMap) {
9
10
  var list = []; // return the list of modules as css string
10
11
 
@@ -13,22 +14,25 @@ module.exports = function (useSourceMap) {
13
14
  var content = cssWithMappingToString(item, useSourceMap);
14
15
 
15
16
  if (item[2]) {
16
- return '@media ' + item[2] + '{' + content + '}';
17
- } else {
18
- return content;
17
+ return "@media ".concat(item[2], "{").concat(content, "}");
19
18
  }
19
+
20
+ return content;
20
21
  }).join('');
21
22
  }; // import a list of modules into the list
23
+ // eslint-disable-next-line func-names
22
24
 
23
25
 
24
26
  list.i = function (modules, mediaQuery) {
25
27
  if (typeof modules === 'string') {
28
+ // eslint-disable-next-line no-param-reassign
26
29
  modules = [[null, modules, '']];
27
30
  }
28
31
 
29
32
  var alreadyImportedModules = {};
30
33
 
31
34
  for (var i = 0; i < this.length; i++) {
35
+ // eslint-disable-next-line prefer-destructuring
32
36
  var id = this[i][0];
33
37
 
34
38
  if (id != null) {
@@ -36,8 +40,8 @@ module.exports = function (useSourceMap) {
36
40
  }
37
41
  }
38
42
 
39
- for (i = 0; i < modules.length; i++) {
40
- var item = modules[i]; // skip already imported module
43
+ for (var _i = 0; _i < modules.length; _i++) {
44
+ var item = modules[_i]; // skip already imported module
41
45
  // this implementation is not 100% perfect for weird media query combinations
42
46
  // when a module is imported multiple times with different media queries.
43
47
  // I hope this will never occur (Hey this way we have smaller bundles)
@@ -46,7 +50,7 @@ module.exports = function (useSourceMap) {
46
50
  if (mediaQuery && !item[2]) {
47
51
  item[2] = mediaQuery;
48
52
  } else if (mediaQuery) {
49
- item[2] = '(' + item[2] + ') and (' + mediaQuery + ')';
53
+ item[2] = "(".concat(item[2], ") and (").concat(mediaQuery, ")");
50
54
  }
51
55
 
52
56
  list.push(item);
@@ -58,7 +62,8 @@ module.exports = function (useSourceMap) {
58
62
  };
59
63
 
60
64
  function cssWithMappingToString(item, useSourceMap) {
61
- var content = item[1] || '';
65
+ var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring
66
+
62
67
  var cssMapping = item[3];
63
68
 
64
69
  if (!cssMapping) {
@@ -68,7 +73,7 @@ function cssWithMappingToString(item, useSourceMap) {
68
73
  if (useSourceMap && typeof btoa === 'function') {
69
74
  var sourceMapping = toComment(cssMapping);
70
75
  var sourceURLs = cssMapping.sources.map(function (source) {
71
- return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */';
76
+ return "/*# sourceURL=".concat(cssMapping.sourceRoot).concat(source, " */");
72
77
  });
73
78
  return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
74
79
  }
@@ -80,6 +85,6 @@ function cssWithMappingToString(item, useSourceMap) {
80
85
  function toComment(sourceMap) {
81
86
  // eslint-disable-next-line no-undef
82
87
  var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
83
- var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
84
- return '/*# ' + data + ' */';
88
+ var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
89
+ return "/*# ".concat(data, " */");
85
90
  }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ module.exports = function (url, options) {
4
+ if (!options) {
5
+ // eslint-disable-next-line no-param-reassign
6
+ options = {};
7
+ } // eslint-disable-next-line no-underscore-dangle, no-param-reassign
8
+
9
+
10
+ url = url.__esModule ? url.default : url;
11
+
12
+ if (typeof url !== 'string') {
13
+ return url;
14
+ } // If url is already wrapped in quotes, remove them
15
+
16
+
17
+ if (/^['"].*['"]$/.test(url)) {
18
+ // eslint-disable-next-line no-param-reassign
19
+ url = url.slice(1, -1);
20
+ }
21
+
22
+ if (options.hash) {
23
+ // eslint-disable-next-line no-param-reassign
24
+ url += options.hash;
25
+ } // Should url be wrapped?
26
+ // See https://drafts.csswg.org/css-values-3/#urls
27
+
28
+
29
+ if (/["'() \t\n]/.test(url) || options.needQuotes) {
30
+ return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, '\\n'), "\"");
31
+ }
32
+
33
+ return url;
34
+ };
package/dist/utils.js CHANGED
@@ -3,18 +3,45 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.uniqWith = uniqWith;
7
+ exports.flatten = flatten;
8
+ exports.dashesCamelCase = dashesCamelCase;
6
9
  exports.getImportPrefix = getImportPrefix;
7
10
  exports.getLocalIdent = getLocalIdent;
8
- exports.camelCase = camelCase;
9
- exports.dashesCamelCase = dashesCamelCase;
10
11
  exports.getFilter = getFilter;
11
- exports.placholderRegExps = void 0;
12
+ exports.getModulesPlugins = getModulesPlugins;
13
+ exports.normalizeSourceMap = normalizeSourceMap;
14
+ exports.getImportItemCode = getImportItemCode;
15
+ exports.getUrlHelperCode = getUrlHelperCode;
16
+ exports.getUrlItemCode = getUrlItemCode;
17
+ exports.getApiCode = getApiCode;
18
+ exports.getImportCode = getImportCode;
19
+ exports.getModuleCode = getModuleCode;
20
+ exports.getExportItemCode = getExportItemCode;
21
+ exports.getExportCode = getExportCode;
22
+ exports.prepareCode = prepareCode;
12
23
 
13
24
  var _path = _interopRequireDefault(require("path"));
14
25
 
26
+ var _loaderUtils = _interopRequireWildcard(require("loader-utils"));
27
+
28
+ var _normalizePath = _interopRequireDefault(require("normalize-path"));
29
+
30
+ var _cssesc = _interopRequireDefault(require("cssesc"));
31
+
32
+ var _postcssModulesValues = _interopRequireDefault(require("postcss-modules-values"));
33
+
34
+ var _postcssModulesLocalByDefault = _interopRequireDefault(require("postcss-modules-local-by-default"));
35
+
36
+ var _postcssModulesExtractImports = _interopRequireDefault(require("postcss-modules-extract-imports"));
37
+
38
+ var _postcssModulesScope = _interopRequireDefault(require("postcss-modules-scope"));
39
+
15
40
  var _camelcase = _interopRequireDefault(require("camelcase"));
16
41
 
17
- var _loaderUtils = _interopRequireDefault(require("loader-utils"));
42
+ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
43
+
44
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
18
45
 
19
46
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
47
 
@@ -22,13 +49,17 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
22
49
  MIT License http://www.opensource.org/licenses/mit-license.php
23
50
  Author Tobias Koppers @sokra
24
51
  */
52
+ function uniqWith(array, comparator) {
53
+ return array.reduce((acc, d) => !acc.some(item => comparator(d, item)) ? [...acc, d] : acc, []);
54
+ }
25
55
 
26
- /* eslint-disable line-comment-position */
27
- const placholderRegExps = {
28
- importItemG: /___CSS_LOADER_IMPORT___([0-9]+)___/g,
29
- importItem: /___CSS_LOADER_IMPORT___([0-9]+)___/
30
- };
31
- exports.placholderRegExps = placholderRegExps;
56
+ function flatten(array) {
57
+ return array.reduce((a, b) => a.concat(b), []);
58
+ }
59
+
60
+ function dashesCamelCase(str) {
61
+ return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
62
+ }
32
63
 
33
64
  function getImportPrefix(loaderContext, importLoaders) {
34
65
  if (importLoaders === false) {
@@ -40,20 +71,14 @@ function getImportPrefix(loaderContext, importLoaders) {
40
71
  return `-!${loadersRequest}!`;
41
72
  }
42
73
 
43
- function camelCase(str) {
44
- return (0, _camelcase.default)(str);
45
- }
46
-
47
- function dashesCamelCase(str) {
48
- return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
49
- }
50
-
51
74
  const whitespace = '[\\x20\\t\\r\\n\\f]';
52
75
  const unescapeRegExp = new RegExp(`\\\\([\\da-f]{1,6}${whitespace}?|(${whitespace})|.)`, 'ig');
53
76
 
54
77
  function unescape(str) {
55
78
  return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
56
- const high = `0x${escaped}` - 0x10000; // NaN means non-codepoint
79
+ const high = `0x${escaped}` - 0x10000;
80
+ /* eslint-disable line-comment-position */
81
+ // NaN means non-codepoint
57
82
  // Workaround erroneous numeric interpretation of +"0x"
58
83
  // eslint-disable-next-line no-self-compare
59
84
 
@@ -61,8 +86,15 @@ function unescape(str) {
61
86
  String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
62
87
  // eslint-disable-next-line no-bitwise
63
88
  String.fromCharCode(high >> 10 | 0xd800, high & 0x3ff | 0xdc00);
89
+ /* eslint-enable line-comment-position */
64
90
  });
65
- }
91
+ } // eslint-disable-next-line no-control-regex
92
+
93
+
94
+ const filenameReservedRegex = /[<>:"/\\|?*\x00-\x1F]/g; // eslint-disable-next-line no-control-regex
95
+
96
+ const reControlChars = /[\u0000-\u001f\u0080-\u009f]/g;
97
+ const reRelativePath = /^\.+/;
66
98
 
67
99
  function getLocalIdent(loaderContext, localIdentName, localName, options) {
68
100
  if (!options.context) {
@@ -70,28 +102,257 @@ function getLocalIdent(loaderContext, localIdentName, localName, options) {
70
102
  options.context = loaderContext.rootContext;
71
103
  }
72
104
 
73
- const request = _path.default.relative(options.context, loaderContext.resourcePath).replace(/\\/g, '/'); // eslint-disable-next-line no-param-reassign
74
-
75
-
76
- options.content = `${options.hashPrefix + request}+${unescape(localName)}`; // eslint-disable-next-line no-param-reassign
105
+ const request = (0, _normalizePath.default)(_path.default.relative(options.context || '', loaderContext.resourcePath)); // eslint-disable-next-line no-param-reassign
77
106
 
78
- localIdentName = localIdentName.replace(/\[local\]/gi, localName);
107
+ options.content = `${options.hashPrefix + request}+${unescape(localName)}`; // Using `[path]` placeholder outputs `/` we need escape their
108
+ // Also directories can contains invalid characters for css we need escape their too
79
109
 
80
- const hash = _loaderUtils.default.interpolateName(loaderContext, localIdentName, options);
81
-
82
- return hash.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-').replace(/^((-?[0-9])|--)/, '_$1');
110
+ return (0, _cssesc.default)(_loaderUtils.default.interpolateName(loaderContext, localIdentName, options) // For `[hash]` placeholder
111
+ .replace(/^((-?[0-9])|--)/, '_$1').replace(filenameReservedRegex, '-').replace(reControlChars, '-').replace(reRelativePath, '-').replace(/\./g, '-'), {
112
+ isIdentifier: true
113
+ }).replace(/\\\[local\\\]/gi, localName);
83
114
  }
84
115
 
85
116
  function getFilter(filter, resourcePath, defaultFilter = null) {
86
- return content => {
87
- if (defaultFilter && !defaultFilter(content)) {
117
+ return item => {
118
+ if (defaultFilter && !defaultFilter(item)) {
88
119
  return false;
89
120
  }
90
121
 
91
122
  if (typeof filter === 'function') {
92
- return !filter(content, resourcePath);
123
+ return filter(item, resourcePath);
93
124
  }
94
125
 
95
126
  return true;
96
127
  };
128
+ }
129
+
130
+ function getModulesPlugins(options, loaderContext) {
131
+ let modulesOptions = {
132
+ mode: 'local',
133
+ localIdentName: '[hash:base64]',
134
+ getLocalIdent,
135
+ hashPrefix: '',
136
+ localIdentRegExp: null
137
+ };
138
+
139
+ if (typeof options.modules === 'boolean' || typeof options.modules === 'string') {
140
+ modulesOptions.mode = typeof options.modules === 'string' ? options.modules : 'local';
141
+ } else {
142
+ modulesOptions = Object.assign({}, modulesOptions, options.modules);
143
+ }
144
+
145
+ return [_postcssModulesValues.default, (0, _postcssModulesLocalByDefault.default)({
146
+ mode: modulesOptions.mode
147
+ }), (0, _postcssModulesExtractImports.default)(), (0, _postcssModulesScope.default)({
148
+ generateScopedName: function generateScopedName(exportName) {
149
+ let localIdent = modulesOptions.getLocalIdent(loaderContext, modulesOptions.localIdentName, exportName, {
150
+ context: modulesOptions.context,
151
+ hashPrefix: modulesOptions.hashPrefix,
152
+ regExp: modulesOptions.localIdentRegExp
153
+ });
154
+
155
+ if (!localIdent) {
156
+ localIdent = getLocalIdent(loaderContext, modulesOptions.localIdentName, exportName, {
157
+ context: modulesOptions.context,
158
+ hashPrefix: modulesOptions.hashPrefix,
159
+ regExp: modulesOptions.localIdentRegExp
160
+ });
161
+ }
162
+
163
+ return localIdent;
164
+ }
165
+ })];
166
+ }
167
+
168
+ function normalizeSourceMap(map) {
169
+ let newMap = map; // Some loader emit source map as string
170
+ // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
171
+
172
+ if (typeof newMap === 'string') {
173
+ newMap = JSON.parse(newMap.replace(/^\)]}'[^\n]*\n/, ''));
174
+ } // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
175
+ // We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
176
+
177
+
178
+ if (newMap.file) {
179
+ newMap.file = (0, _normalizePath.default)(newMap.file);
180
+ }
181
+
182
+ if (newMap.sourceRoot) {
183
+ newMap.sourceRoot = (0, _normalizePath.default)(newMap.sourceRoot);
184
+ }
185
+
186
+ if (newMap.sources) {
187
+ newMap.sources = newMap.sources.map(source => (0, _normalizePath.default)(source));
188
+ }
189
+
190
+ return newMap;
191
+ }
192
+
193
+ function getImportItemCode(item, loaderContext, importPrefix) {
194
+ const {
195
+ url
196
+ } = item;
197
+ const media = item.media || '';
198
+
199
+ if (!(0, _loaderUtils.isUrlRequest)(url)) {
200
+ return `exports.push([module.id, ${JSON.stringify(`@import url(${url});`)}, ${JSON.stringify(media)}]);`;
201
+ }
202
+
203
+ const importUrl = importPrefix + (0, _loaderUtils.urlToRequest)(url);
204
+ return `exports.i(require(${(0, _loaderUtils.stringifyRequest)(loaderContext, importUrl)}), ${JSON.stringify(media)});`;
205
+ }
206
+
207
+ function getUrlHelperCode(loaderContext) {
208
+ return `var getUrl = require(${(0, _loaderUtils.stringifyRequest)(loaderContext, require.resolve('./runtime/getUrl.js'))});`;
209
+ }
210
+
211
+ function getUrlItemCode(item, loaderContext) {
212
+ const {
213
+ url,
214
+ placeholder,
215
+ needQuotes
216
+ } = item; // Remove `#hash` and `?#hash` from `require`
217
+
218
+ const [normalizedUrl, singleQuery, hashValue] = url.split(/(\?)?#/);
219
+ const hash = singleQuery || hashValue ? `"${singleQuery ? '?' : ''}${hashValue ? `#${hashValue}` : ''}"` : '';
220
+ const options = [];
221
+
222
+ if (hash) {
223
+ options.push(`hash: ${hash}`);
224
+ }
225
+
226
+ if (needQuotes) {
227
+ options.push(`needQuotes: true`);
228
+ }
229
+
230
+ const preparedOptions = options.length > 0 ? `, { ${options.join(', ')} }` : '';
231
+ return `var ${placeholder} = getUrl(require(${(0, _loaderUtils.stringifyRequest)(loaderContext, (0, _loaderUtils.urlToRequest)(normalizedUrl))})${preparedOptions});`;
232
+ }
233
+
234
+ function getApiCode(loaderContext, sourceMap, onlyLocals) {
235
+ if (onlyLocals) {
236
+ return '';
237
+ }
238
+
239
+ return `exports = module.exports = require(${(0, _loaderUtils.stringifyRequest)(loaderContext, require.resolve('./runtime/api'))})(${sourceMap});\n`;
240
+ }
241
+
242
+ function getImportCode(importItems, onlyLocals) {
243
+ if (importItems.length === 0 || onlyLocals) {
244
+ return '';
245
+ }
246
+
247
+ return `// Imports\n${importItems.join('\n')}\n`;
248
+ }
249
+
250
+ function getModuleCode(result, sourceMap, onlyLocals) {
251
+ if (onlyLocals) {
252
+ return '';
253
+ }
254
+
255
+ return `// Module\nexports.push([module.id, ${JSON.stringify(result.css)}, ""${sourceMap && result.map ? `,${result.map}` : ''}]);\n`;
256
+ }
257
+
258
+ function getExportItemCode(key, value, localsConvention) {
259
+ let targetKey;
260
+ const items = [];
261
+
262
+ function addEntry(k) {
263
+ items.push(`\t${JSON.stringify(k)}: ${JSON.stringify(value)}`);
264
+ }
265
+
266
+ switch (localsConvention) {
267
+ case 'camelCase':
268
+ addEntry(key);
269
+ targetKey = (0, _camelcase.default)(key);
270
+
271
+ if (targetKey !== key) {
272
+ addEntry(targetKey);
273
+ }
274
+
275
+ break;
276
+
277
+ case 'camelCaseOnly':
278
+ addEntry((0, _camelcase.default)(key));
279
+ break;
280
+
281
+ case 'dashes':
282
+ addEntry(key);
283
+ targetKey = dashesCamelCase(key);
284
+
285
+ if (targetKey !== key) {
286
+ addEntry(targetKey);
287
+ }
288
+
289
+ break;
290
+
291
+ case 'dashesOnly':
292
+ addEntry(dashesCamelCase(key));
293
+ break;
294
+
295
+ case 'asIs':
296
+ default:
297
+ addEntry(key);
298
+ break;
299
+ }
300
+
301
+ return items.join(',\n');
302
+ }
303
+
304
+ function getExportCode(exportItems, onlyLocals) {
305
+ if (exportItems.length === 0) {
306
+ return '';
307
+ }
308
+
309
+ return `// Exports\n${onlyLocals ? 'module.exports' : 'exports.locals'} = {\n${exportItems.join(',\n')}\n};`;
310
+ }
311
+
312
+ function getIcssReplacer(item, loaderContext, importPrefix, onlyLocals) {
313
+ const importUrl = importPrefix + (0, _loaderUtils.urlToRequest)(item.url);
314
+ return () => onlyLocals ? `" + require(${(0, _loaderUtils.stringifyRequest)(loaderContext, importUrl)})[${JSON.stringify(item.export)}] + "` : `" + require(${(0, _loaderUtils.stringifyRequest)(loaderContext, importUrl)}).locals[${JSON.stringify(item.export)}] + "`;
315
+ }
316
+
317
+ function prepareCode(file, messages, loaderContext, importPrefix, onlyLocals) {
318
+ const {
319
+ apiCode,
320
+ importCode
321
+ } = file;
322
+ let {
323
+ moduleCode,
324
+ exportCode
325
+ } = file;
326
+ messages.filter(message => message.type === 'icss-import' || message.type === 'import' && message.importType === 'url').forEach(message => {
327
+ // Replace all urls on `require`
328
+ if (message.type === 'import') {
329
+ const {
330
+ placeholder
331
+ } = message;
332
+
333
+ if (moduleCode) {
334
+ // eslint-disable-next-line no-param-reassign
335
+ moduleCode = moduleCode.replace(new RegExp(placeholder, 'g'), () => `" + ${placeholder} + "`);
336
+ }
337
+ } // Replace external ICSS import on `require`
338
+
339
+
340
+ if (message.type === 'icss-import') {
341
+ const {
342
+ item
343
+ } = message;
344
+ const replacer = getIcssReplacer(item, loaderContext, importPrefix, onlyLocals);
345
+
346
+ if (moduleCode) {
347
+ // eslint-disable-next-line no-param-reassign
348
+ moduleCode = moduleCode.replace(new RegExp(`___CSS_LOADER_IMPORT___(${item.index})___`, 'g'), replacer);
349
+ }
350
+
351
+ if (exportCode) {
352
+ // eslint-disable-next-line no-param-reassign
353
+ exportCode = exportCode.replace(new RegExp(`___CSS_LOADER_IMPORT___(${item.index})___`, 'g'), replacer);
354
+ }
355
+ }
356
+ });
357
+ return [apiCode, importCode, moduleCode, exportCode].filter(Boolean).join('');
97
358
  }