Repository: webpack-contrib/css-loader
Pull request #1128 (2020-07-24 15:43:07)

Fix perf
<!--
  HOLY CRAP a Pull Request. We ❤️ those!

  If you remove or skip this template, you'll make the 🐼 sad and the mighty god
  of Github will appear and pile-drive the close button from a great height
  while making animal noises.

  Please place an x (no spaces!) in all [ ] that apply
-->

This PR contains a:

- [x] **bugfix**
- [ ] new **feature**
- [x] **code refactor**
- [x] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [ ] **metadata update**

### Motivation / Use-Case

perf + fix (but it was regression from other PRs)

### Breaking Changes

No

### Additional Info

No

codecov[bot]: # [Codecov](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=h1) Report
> Merging [#1128](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=desc) into [master](https://codecov.io/gh/webpack-contrib/css-loader/commit/1c20b1e32b138be5369c5300597c53cb1526c3bf&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/graphs/tree.svg?width=650&height=150&src=pr&token=DlN3OQ0JnO)](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1128      +/-   ##
==========================================
- Coverage   99.51%   99.50%   -0.02%     
==========================================
  Files          10       10              
  Lines         624      608      -16     
  Branches      195      186       -9     
==========================================
- Hits          621      605      -16     
  Misses          3        3              
```


| [Impacted Files](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/index.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/diff?src=pr&el=tree#diff-c3JjL2luZGV4Lmpz) | `100.00% <100.00%> (ø)` | |
| [src/plugins/postcss-icss-parser.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/diff?src=pr&el=tree#diff-c3JjL3BsdWdpbnMvcG9zdGNzcy1pY3NzLXBhcnNlci5qcw==) | `100.00% <100.00%> (ø)` | |
| [src/plugins/postcss-import-parser.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/diff?src=pr&el=tree#diff-c3JjL3BsdWdpbnMvcG9zdGNzcy1pbXBvcnQtcGFyc2VyLmpz) | `100.00% <100.00%> (ø)` | |
| [src/plugins/postcss-url-parser.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/diff?src=pr&el=tree#diff-c3JjL3BsdWdpbnMvcG9zdGNzcy11cmwtcGFyc2VyLmpz) | `100.00% <100.00%> (ø)` | |
| [src/utils.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128/diff?src=pr&el=tree#diff-c3JjL3V0aWxzLmpz) | `98.77% <100.00%> (-0.04%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=footer). Last update [1c20b1e...41ca434](https://codecov.io/gh/webpack-contrib/css-loader/pull/1128?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/index.js b/src/index.js
index 37a9e5a..06d3058 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,7 +24,7 @@ import {
   getModuleCode,
   getModulesPlugins,
   normalizeSourceMap,
-  sortImports,
+  sort,
 } from './utils';
 
 export default async function loader(content, map, meta) {
@@ -48,12 +48,18 @@ export default async function loader(content, map, meta) {
     return;
   }
 
+  const replacements = [];
+  const exports = [];
+
   const needUseModulesPlugins = shouldUseModulesPlugins(options);
 
   if (needUseModulesPlugins) {
     plugins.push(...getModulesPlugins(options, this));
   }
 
+  const importPluginImports = [];
+  const importPluginApi = [];
+
   if (shouldUseImportPlugin(options)) {
     const resolver = this.getResolve({
       mainFields: ['css', 'style', 'main', '...'],
@@ -65,6 +71,8 @@ export default async function loader(content, map, meta) {
 
     plugins.push(
       importParser({
+        imports: importPluginImports,
+        api: importPluginApi,
         context: this.context,
         rootContext: this.rootContext,
         filter: getFilter(options.import, this.resourcePath),
@@ -78,6 +86,8 @@ export default async function loader(content, map, meta) {
     );
   }
 
+  const urlPluginImports = [];
+
   if (shouldUseURLPlugin(options)) {
     const urlResolver = this.getResolve({
       mainFields: ['asset'],
@@ -87,6 +97,8 @@ export default async function loader(content, map, meta) {
 
     plugins.push(
       urlParser({
+        imports: urlPluginImports,
+        replacements,
         context: this.context,
         rootContext: this.rootContext,
         filter: getFilter(options.url, this.resourcePath),
@@ -96,6 +108,9 @@ export default async function loader(content, map, meta) {
     );
   }
 
+  const icssPluginImports = [];
+  const icssPluginApi = [];
+
   if (needUseModulesPlugins) {
     const icssResolver = this.getResolve({
       mainFields: ['css', 'style', 'main', '...'],
@@ -106,6 +121,10 @@ export default async function loader(content, map, meta) {
 
     plugins.push(
       icssParser({
+        imports: icssPluginImports,
+        api: icssPluginApi,
+        replacements,
+        exports,
         context: this.context,
         rootContext: this.rootContext,
         resolver: icssResolver,
@@ -163,34 +182,23 @@ export default async function loader(content, map, meta) {
     this.emitWarning(new Warning(warning));
   }
 
-  const imports = [];
-  const apiImports = [];
-  const replacements = [];
-  const exports = [];
-
-  for (const message of result.messages) {
-    // eslint-disable-next-line default-case
-    switch (message.type) {
-      case 'import':
-        imports.push(message.value);
-        break;
-      case 'api-import':
-        apiImports.push(message.value);
-        break;
-      case 'replacement':
-        replacements.push(message.value);
-        break;
-      case 'export':
-        exports.push(message.value);
-        break;
-    }
+  const imports = []
+    .concat(icssPluginImports.sort(sort))
+    .concat(importPluginImports.sort(sort))
+    .concat(urlPluginImports.sort(sort));
+  const api = []
+    .concat(importPluginApi.sort(sort))
+    .concat(icssPluginApi.sort(sort));
+
+  if (options.modules.exportOnlyLocals !== true) {
+    imports.unshift({
+      importName: '___CSS_LOADER_API_IMPORT___',
+      url: stringifyRequest(this, require.resolve('./runtime/api')),
+    });
   }
 
-  imports.sort(sortImports);
-  apiImports.sort(sortImports);
-
-  const importCode = getImportCode(this, imports, options);
-  const moduleCode = getModuleCode(result, apiImports, replacements, options);
+  const importCode = getImportCode(imports, options);
+  const moduleCode = getModuleCode(result, api, replacements, options);
   const exportCode = getExportCode(exports, replacements, options);
 
   callback(null, `${importCode}${moduleCode}${exportCode}`);
diff --git a/src/plugins/postcss-icss-parser.js b/src/plugins/postcss-icss-parser.js
index 6ff4b5d..939c78a 100644
--- a/src/plugins/postcss-icss-parser.js
+++ b/src/plugins/postcss-icss-parser.js
@@ -5,7 +5,7 @@ import { normalizeUrl, resolveRequests, requestify } from '../utils';
 
 export default postcss.plugin(
   'postcss-icss-parser',
-  (options) => async (css, result) => {
+  (options) => async (css) => {
     const importReplacements = Object.create(null);
     const { icssImports, icssExports } = extractICSS(css);
     const imports = new Map();
@@ -58,28 +58,14 @@ export default postcss.plugin(
         importName = `___CSS_LOADER_ICSS_IMPORT_${imports.size}___`;
         imports.set(importKey, importName);
 
-        result.messages.push(
-          {
-            type: 'import',
-            value: {
-              importName,
-              url: options.urlHandler(newUrl),
-              icss: true,
-              order: 0,
-              index,
-            },
-          },
-          {
-            type: 'api-import',
-            value: {
-              type: 'internal',
-              importName,
-              dedupe: true,
-              order: 0,
-              index,
-            },
-          }
-        );
+        options.imports.push({
+          importName,
+          url: options.urlHandler(newUrl),
+          icss: true,
+          index,
+        });
+
+        options.api.push({ importName, dedupe: true, index });
       }
 
       for (const [replacementIndex, token] of Object.keys(tokens).entries()) {
@@ -88,10 +74,7 @@ export default postcss.plugin(
 
         importReplacements[token] = replacementName;
 
-        result.messages.push({
-          type: 'replacement',
-          value: { type: 'icss', replacementName, importName, localName },
-        });
+        options.replacements.push({ replacementName, importName, localName });
       }
     }
 
@@ -102,7 +85,7 @@ export default postcss.plugin(
     for (const name of Object.keys(icssExports)) {
       const value = replaceValueSymbols(icssExports[name], importReplacements);
 
-      result.messages.push({ type: 'export', value: { name, value } });
+      options.exports.push({ name, value });
     }
   }
 );
diff --git a/src/plugins/postcss-import-parser.js b/src/plugins/postcss-import-parser.js
index 5218150..9fc64ce 100644
--- a/src/plugins/postcss-import-parser.js
+++ b/src/plugins/postcss-import-parser.js
@@ -179,31 +179,20 @@ export default postcss.plugin(pluginName, (options) => async (css, result) => {
         importName = `___CSS_LOADER_AT_RULE_IMPORT_${imports.size}___`;
         imports.set(importKey, importName);
 
-        result.messages.push({
-          type: 'import',
-          value: {
-            order: 1,
-            importName,
-            url: options.urlHandler(newUrl),
-            index,
-          },
+        options.imports.push({
+          importName,
+          url: options.urlHandler(newUrl),
+          index,
         });
       }
 
-      result.messages.push({
-        type: 'api-import',
-        value: { order: 1, type: 'internal', importName, media, index },
-      });
+      options.api.push({ importName, media, index });
 
       // eslint-disable-next-line no-continue
       continue;
     }
 
-    result.messages.push({
-      pluginName,
-      type: 'api-import',
-      value: { order: 1, type: 'external', url, media, index },
-    });
+    options.api.push({ url, media, index });
   }
 
   return Promise.resolve();
diff --git a/src/plugins/postcss-url-parser.js b/src/plugins/postcss-url-parser.js
index 7bd5e19..2a5ee69 100644
--- a/src/plugins/postcss-url-parser.js
+++ b/src/plugins/postcss-url-parser.js
@@ -61,11 +61,7 @@ function walkCss(css, result, options, callback) {
         };
 
         if (shouldHandleRule(rule, decl, result)) {
-          accumulator.push({
-            decl,
-            rule,
-            parsed,
-          });
+          accumulator.push({ decl, rule, parsed });
         }
 
         // Do not traverse inside `url`
@@ -91,11 +87,7 @@ function walkCss(css, result, options, callback) {
             };
 
             if (shouldHandleRule(rule, decl, result)) {
-              accumulator.push({
-                decl,
-                rule,
-                parsed,
-              });
+              accumulator.push({ decl, rule, parsed });
             }
           } else if (type === 'string') {
             const rule = {
@@ -106,11 +98,7 @@ function walkCss(css, result, options, callback) {
             };
 
             if (shouldHandleRule(rule, decl, result)) {
-              accumulator.push({
-                decl,
-                rule,
-                parsed,
-              });
+              accumulator.push({ decl, rule, parsed });
             }
           }
         }
@@ -166,15 +154,10 @@ export default postcss.plugin(pluginName, (options) => async (css, result) => {
     }
 
     if (!hasUrlImportHelper) {
-      result.messages.push({
-        pluginName,
-        type: 'import',
-        value: {
-          order: 2,
-          importName: '___CSS_LOADER_GET_URL_IMPORT___',
-          url: options.urlHandler(require.resolve('../runtime/getUrl.js')),
-          index: 1,
-        },
+      options.imports.push({
+        importName: '___CSS_LOADER_GET_URL_IMPORT___',
+        url: options.urlHandler(require.resolve('../runtime/getUrl.js')),
+        index: -1,
       });
 
       hasUrlImportHelper = true;
@@ -216,10 +199,10 @@ export default postcss.plugin(pluginName, (options) => async (css, result) => {
       importName = `___CSS_LOADER_URL_IMPORT_${imports.size}___`;
       imports.set(importKey, importName);
 
-      result.messages.push({
-        pluginName,
-        type: 'import',
-        value: { importName, url: options.urlHandler(newUrl), index, order: 3 },
+      options.imports.push({
+        importName,
+        url: options.urlHandler(newUrl),
+        index,
       });
     }
 
@@ -231,10 +214,11 @@ export default postcss.plugin(pluginName, (options) => async (css, result) => {
       replacementName = `___CSS_LOADER_URL_REPLACEMENT_${replacements.size}___`;
       replacements.set(replacementKey, replacementName);
 
-      result.messages.push({
-        pluginName,
-        type: 'replacement',
-        value: { type: 'url', replacementName, importName, hash, needQuotes },
+      options.replacements.push({
+        replacementName,
+        importName,
+        hash,
+        needQuotes,
       });
     }
 
diff --git a/src/utils.js b/src/utils.js
index e5b75cd..9effda0 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -4,12 +4,7 @@
 */
 import path from 'path';
 
-import {
-  stringifyRequest,
-  urlToRequest,
-  interpolateName,
-  isUrlRequest,
-} from 'loader-utils';
+import { urlToRequest, interpolateName, isUrlRequest } from 'loader-utils';
 import normalizePath from 'normalize-path';
 import cssesc from 'cssesc';
 import modulesValues from 'postcss-modules-values';
@@ -327,20 +322,9 @@ function getPreRequester({ loaders, loaderIndex }) {
   };
 }
 
-function getImportCode(loaderContext, imports, options) {
+function getImportCode(imports, options) {
   let code = '';
 
-  if (options.modules.exportOnlyLocals !== true) {
-    const apiUrl = stringifyRequest(
-      loaderContext,
-      require.resolve('./runtime/api')
-    );
-
-    code += options.esModule
-      ? `import ___CSS_LOADER_API_IMPORT___ from ${apiUrl};\n`
-      : `var ___CSS_LOADER_API_IMPORT___ = require(${apiUrl});\n`;
-  }
-
   for (const item of imports) {
     const { importName, url, icss } = item;
 
@@ -354,7 +338,7 @@ function getImportCode(loaderContext, imports, options) {
   return code ? `// Imports\n${code}` : '';
 }
 
-function getModuleCode(result, apiImports, replacements, options) {
+function getModuleCode(result, api, replacements, options) {
   if (options.modules.exportOnlyLocals === true) {
     return 'var ___CSS_LOADER_EXPORT___ = {};\n';
   }
@@ -364,25 +348,31 @@ function getModuleCode(result, apiImports, replacements, options) {
   let code = JSON.stringify(css);
   let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap});\n`;
 
-  for (const item of apiImports) {
-    const { type, media, dedupe } = item;
-
-    beforeCode +=
-      type === 'internal'
-        ? `___CSS_LOADER_EXPORT___.i(${item.importName}${
-            media ? `, ${JSON.stringify(media)}` : dedupe ? ', ""' : ''
-          }${dedupe ? ', true' : ''});\n`
-        : `___CSS_LOADER_EXPORT___.push([module.id, ${JSON.stringify(
-            `@import url(${item.url});`
-          )}${media ? `, ${JSON.stringify(media)}` : ''}]);\n`;
-  }
+  for (const item of api) {
+    const { url, media, dedupe } = item;
 
-  for (const replacement of replacements) {
-    const { replacementName, importName, type } = replacement;
+    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`;
+  }
 
-    if (type === 'url') {
-      const { hash, needQuotes } = replacement;
+  for (const item of replacements) {
+    const { replacementName, importName, localName } = item;
 
+    if (localName) {
+      code = code.replace(new RegExp(replacementName, 'g'), () =>
+        options.modules.namedExport
+          ? `" + ${importName}_NAMED___[${JSON.stringify(
+              camelCase(localName)
+            )}] + "`
+          : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`
+      );
+    } else {
+      const { hash, needQuotes } = item;
       const getUrlOptions = []
         .concat(hash ? [`hash: ${JSON.stringify(hash)}`] : [])
         .concat(needQuotes ? 'needQuotes: true' : []);
@@ -390,21 +380,10 @@ function getModuleCode(result, apiImports, replacements, options) {
         getUrlOptions.length > 0 ? `, { ${getUrlOptions.join(', ')} }` : '';
 
       beforeCode += `var ${replacementName} = ___CSS_LOADER_GET_URL_IMPORT___(${importName}${preparedOptions});\n`;
-
       code = code.replace(
         new RegExp(replacementName, 'g'),
         () => `" + ${replacementName} + "`
       );
-    } else {
-      const { localName } = replacement;
-
-      code = code.replace(new RegExp(replacementName, 'g'), () =>
-        options.modules.namedExport
-          ? `" + ${importName}_NAMED___[${JSON.stringify(
-              camelCase(localName)
-            )}] + "`
-          : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`
-      );
     }
   }
 
@@ -472,16 +451,11 @@ function getExportCode(exports, replacements, options) {
     }
   }
 
-  for (const replacement of replacements) {
-    const { replacementName, type } = replacement;
+  for (const item of replacements) {
+    const { replacementName, localName } = item;
 
-    if (type === 'url') {
-      localsCode = localsCode.replace(
-        new RegExp(replacementName, 'g'),
-        () => `" + ${replacementName} + "`
-      );
-    } else {
-      const { importName, localName } = replacement;
+    if (localName) {
+      const { importName } = item;
 
       localsCode = localsCode.replace(new RegExp(replacementName, 'g'), () =>
         options.modules.namedExport
@@ -490,6 +464,11 @@ function getExportCode(exports, replacements, options) {
             )}] + "`
           : `" + ${importName}.locals[${JSON.stringify(localName)}] + "`
       );
+    } else {
+      localsCode = localsCode.replace(
+        new RegExp(replacementName, 'g'),
+        () => `" + ${replacementName} + "`
+      );
     }
   }
 
@@ -545,11 +524,8 @@ function isUrlRequestable(url) {
   return isUrlRequest(url);
 }
 
-function sortImports(a, b) {
-  return (
-    (b.order < a.order) - (a.order < b.order) ||
-    (b.index < a.index) - (a.index < b.index)
-  );
+function sort(a, b) {
+  return a.index - b.index;
 }
 
 export {
@@ -569,5 +545,5 @@ export {
   getExportCode,
   resolveRequests,
   isUrlRequestable,
-  sortImports,
+  sort,
 };


Test patch:
diff --git a/test/__snapshots__/modules-option.test.js.snap b/test/__snapshots__/modules-option.test.js.snap
index f061ac8..c0ed06d 100644
--- a/test/__snapshots__/modules-option.test.js.snap
+++ b/test/__snapshots__/modules-option.test.js.snap
@@ -1187,6 +1187,7 @@ import ___CSS_LOADER_AT_RULE_IMPORT_0___ from \\"-!../../../../src/index.js??[id
 import ___CSS_LOADER_GET_URL_IMPORT___ from \\"../../../../src/runtime/getUrl.js\\";
 import ___CSS_LOADER_URL_IMPORT_0___ from \\"../../url/img.png\\";
 var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
+___CSS_LOADER_EXPORT___.i(___CSS_LOADER_AT_RULE_IMPORT_0___, \\"(min-width: 100px)\\");
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true);
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_1___, \\"\\", true);
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_2___, \\"\\", true);
@@ -1195,7 +1196,6 @@ ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_4___, \\"\\", true);
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_5___, \\"\\", true);
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_6___, \\"\\", true);
 ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_7___, \\"\\", true);
-___CSS_LOADER_EXPORT___.i(___CSS_LOADER_AT_RULE_IMPORT_0___, \\"(min-width: 100px)\\");
 var ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);
 // Module
 ___CSS_LOADER_EXPORT___.push([module.id, \\"._2ZmR2b3YBVn0i8sme-abcC {\\\\n  color: \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"v-def\\"] + \\";\\\\n}\\\\n\\\\n._3dxIylSbTBEe450DFBxy5D {\\\\n  color: blue;\\\\n}\\\\n\\\\n.EcQSwQce4PuQ5vNAybT9N {\\\\n  display: block;\\\\n}\\\\n\\\\n.hTH4alr_d-S0jPncN6ib3 {\\\\n  width: \\" + ___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"v-something\\"] + \\";\\\\n}\\\\n\\\\n._7sobwviowI6_CZkzLjYZG {\\\\n  color: \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"v-other\\"] + \\";\\\\n}\\\\n\\\\n.YpDepip9R1BGGAy-rGgvc {\\\\n  prop: \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"v-def\\"] + \\";\\\\n  duplicate: \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"v-other\\"] + \\";\\\\n}\\\\n\\\\n._3dfrN27nghAjb3tcT6R_Ov {\\\\n  color: red;\\\\n}\\\\n\\\\n._3aPunKIij5oyAtcB6y9-Xm {\\\\n  color: yellow;\\\\n}\\\\n\\\\n._3Qp0o615k38gm2l4OVRknw {\\\\n  color: gray;\\\\n}\\\\n\\\\n._2Zsff12VKF2NbAGVE1sdzC {\\\\n  color: gray;\\\\n}\\\\n\\\\n._3itMfHbLQSSkBisENyA8TF {\\\\n  color: gainsboro;\\\\n}\\\\n\\\\n._2ChGydqcGYRLzAo3_Iomr2 {\\\\n  color: gainsboro;\\\\n}\\\\n\\\\n._1ai7yu9kkZ_8JwK0EMbe6U {\\\\n  color: #BF4040;\\\\n}\\\\n\\\\n.OX01CBO1Ma7xJh6yAybXq {\\\\n  color: black;\\\\n}\\\\n\\\\n@media (min-width: 960px) {\\\\n  ._2Yk-wvfy8t_ESEwwB1Fc0y {\\\\n    padding: 0 20px;\\\\n  }\\\\n}\\\\n\\\\n.\\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"s-white\\"] + \\" {\\\\n  color: white;\\\\n}\\\\n\\\\n@media \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"m-small\\"] + \\" {\\\\n  ._2Yk-wvfy8t_ESEwwB1Fc0y {\\\\n    padding: 20px 20px;\\\\n  }\\\\n}\\\\n@value v-comment: /* comment */;\\\\n\\\\n._2PhbElc8FsODw7KMuxWJyk {\\\\n  v-ident: validIdent;\\\\n  v-pre-defined-ident: left;\\\\n  v-string: 'content';\\\\n  v-string-1: '';\\\\n  v-url: url(https://www.exammple.com/images/my-background.png);\\\\n  v-url-1: url('https://www.exammple.com/images/my-background.png');\\\\n  v-url-2: url(\\\\\\"https://www.exammple.com/images/my-background.png\\\\\\");\\\\n  v-integer: 100;\\\\n  v-integer-1: -100;\\\\n  v-integer-2: +100;\\\\n  v-number: .60;\\\\n  v-number-1: -456.8;\\\\n  v-number-2: -3.4e-2;\\\\n  v-dimension: 12px;\\\\n  v-percentage: 100%;\\\\n  v-hex: #fff;\\\\n  v-comment: v-comment 10px v-comment;\\\\n  v-function: rgb(0,0,0);\\\\n  v-unicode-range: U+0025-00FF;\\\\n  mutliple: #fff .60 100%;\\\\n}\\\\n\\\\n\\\\na {\\\\n  content: 'content';\\\\n}\\\\n\\\\n@supports (content: 'content') {\\\\n  a {\\\\n    content: 'content';\\\\n  }\\\\n}\\\\n\\\\n[class~='content'] {\\\\n  color:green;\\\\n}\\\\n\\\\n._1qvhWcgsRpzv9-_jaooxI0 {\\\\n  background: url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\");\\\\n}\\\\n\\\\n._1-QX-dLNLF1zFn-cPfLHcH {\\\\n  background: red;\\\\n}\\\\n\\", \\"\\"]);
@@ -1254,6 +1254,14 @@ export default ___CSS_LOADER_EXPORT___;
 
 exports[`"modules" option should support resolving in composes: result 1`] = `
 Array [
+  Array [
+    "../../src/index.js?[ident]!./modules/composes/test-other.css",
+    "._24axXNO_oC23T0D0YAz-0Y {
+  d: d;
+}
+",
+    "(min-width: 100px)",
+  ],
   Array [
     "../../src/index.js?[ident]!./modules/composes/values.css",
     "
@@ -1314,14 +1322,6 @@ Array [
 }",
     "",
   ],
-  Array [
-    "../../src/index.js?[ident]!./modules/composes/test-other.css",
-    "._24axXNO_oC23T0D0YAz-0Y {
-  d: d;
-}
-",
-    "(min-width: 100px)",
-  ],
   Array [
     "./modules/composes/composes.css",
     "._2ZmR2b3YBVn0i8sme-abcC {