Repository: webpack-contrib/css-loader
Pull request #1192 (2020-09-22 16:12:57)

Feat: auto enable icss modules
<!--
  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:

- [ ] **bugfix**
- [x] new **feature**
- [ ] **code refactor**
- [x] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [x] **metadata update**

### Motivation / Use-Case

Auto enable `icss` modules for all files for which `/\.icss\.\w+$/i.test(filename)` return `true`

### Breaking Changes

No

### Additional Info

No


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

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

```diff
@@            Coverage Diff             @@
##           master    #1192      +/-   ##
==========================================
- Coverage   99.24%   98.94%   -0.31%     
==========================================
  Files          10       10              
  Lines         666      666              
  Branches      212      211       -1     
==========================================
- Hits          661      659       -2     
- Misses          5        7       +2     
```


| [Impacted Files](https://codecov.io/gh/webpack-contrib/css-loader/pull/1192?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/utils.js](https://codecov.io/gh/webpack-contrib/css-loader/pull/1192/diff?src=pr&el=tree#diff-c3JjL3V0aWxzLmpz) | `97.68% <100.00%> (-0.67%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/webpack-contrib/css-loader/pull/1192?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/1192?src=pr&el=footer). Last update [df111b8...5358a36](https://codecov.io/gh/webpack-contrib/css-loader/pull/1192?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/utils.js b/src/utils.js
index 67e5056..ca167e2 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -109,15 +109,21 @@ function getFilter(filter, resourcePath) {
   };
 }
 
-const moduleRegExp = /\.module\.\w+$/i;
+const moduleRegExp = /\.module(s)?\.\w+$/i;
+const icssRegExp = /\.icss\.\w+$/i;
 
 function getModulesOptions(rawOptions, loaderContext) {
   const { resourcePath } = loaderContext;
+  let isIcss;
 
   if (typeof rawOptions.modules === 'undefined') {
     const isModules = moduleRegExp.test(resourcePath);
 
     if (!isModules) {
+      isIcss = icssRegExp.test(resourcePath);
+    }
+
+    if (!isModules && !isIcss) {
       return false;
     }
   } else if (
@@ -128,7 +134,7 @@ function getModulesOptions(rawOptions, loaderContext) {
   }
 
   let modulesOptions = {
-    compileType: rawOptions.icss ? 'icss' : 'module',
+    compileType: isIcss ? 'icss' : 'module',
     auto: true,
     mode: 'local',
     exportGlobals: false,
@@ -205,14 +211,6 @@ function getModulesOptions(rawOptions, loaderContext) {
 }
 
 function normalizeOptions(rawOptions, loaderContext) {
-  if (rawOptions.icss) {
-    loaderContext.emitWarning(
-      new Error(
-        'The "icss" option is deprecated, use "modules.compileType: "icss"" instead'
-      )
-    );
-  }
-
   const modulesOptions = getModulesOptions(rawOptions, loaderContext);
 
   return {


Test patch:
diff --git a/test/__snapshots__/modules-option.test.js.snap b/test/__snapshots__/modules-option.test.js.snap
index 7e4dfd8..b57716f 100644
--- a/test/__snapshots__/modules-option.test.js.snap
+++ b/test/__snapshots__/modules-option.test.js.snap
@@ -12227,6 +12227,76 @@ Array [
 
 exports[`"modules" option should work with the "[local]" placeholder for the "localIdentName" option: warnings 1`] = `Array []`;
 
+exports[`"modules" option should work with the "auto" by default for icss: errors 1`] = `Array []`;
+
+exports[`"modules" option should work with the "auto" by default for icss: module 1`] = `
+"// Imports
+import ___CSS_LOADER_API_IMPORT___ from \\"../../../../../src/runtime/api.js\\";
+import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../../src/index.js??[ident]!./vars.icss.css\\";
+var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
+___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true);
+// Module
+___CSS_LOADER_EXPORT___.push([module.id, \\".className {\\\\n  color: \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"primary-color\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
+// Exports
+___CSS_LOADER_EXPORT___.locals = {
+	\\"primary-color\\": \\"\\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"primary-color\\"] + \\"\\"
+};
+export default ___CSS_LOADER_EXPORT___;
+"
+`;
+
+exports[`"modules" option should work with the "auto" by default for icss: result 1`] = `
+Array [
+  Array [
+    "../../src/index.js?[ident]!./modules/mode/icss/vars.icss.css",
+    "
+",
+    "",
+  ],
+  Array [
+    "./modules/mode/icss/relative.icss.css",
+    ".className {
+  color: red;
+}
+",
+    "",
+  ],
+]
+`;
+
+exports[`"modules" option should work with the "auto" by default for icss: warnings 1`] = `Array []`;
+
+exports[`"modules" option should work with the "auto" by default with "modules" filename: errors 1`] = `Array []`;
+
+exports[`"modules" option should work with the "auto" by default with "modules" filename: module 1`] = `
+"// Imports
+import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
+var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
+// Module
+___CSS_LOADER_EXPORT___.push([module.id, \\".af0LbFVUmIAO7cXelO_aA {\\\\n  color: red;\\\\n}\\\\n\\", \\"\\"]);
+// Exports
+___CSS_LOADER_EXPORT___.locals = {
+	\\"relative\\": \\"af0LbFVUmIAO7cXelO_aA\\"
+};
+export default ___CSS_LOADER_EXPORT___;
+"
+`;
+
+exports[`"modules" option should work with the "auto" by default with "modules" filename: result 1`] = `
+Array [
+  Array [
+    "./modules/mode/relative.modules.css",
+    ".af0LbFVUmIAO7cXelO_aA {
+  color: red;
+}
+",
+    "",
+  ],
+]
+`;
+
+exports[`"modules" option should work with the "auto" by default with "modules" filename: warnings 1`] = `Array []`;
+
 exports[`"modules" option should work with the "auto" by default: errors 1`] = `Array []`;
 
 exports[`"modules" option should work with the "auto" by default: module 1`] = `
diff --git a/test/fixtures/modules/mode/icss/icss.js b/test/fixtures/modules/mode/icss/icss.js
new file mode 100644
index 0000000..d6b82f6
--- /dev/null
+++ b/test/fixtures/modules/mode/icss/icss.js
@@ -0,0 +1,5 @@
+import relative from './relative.icss.css';
+
+__export__ = relative;
+
+export default relative;
diff --git a/test/fixtures/modules/mode/icss/relative.icss.css b/test/fixtures/modules/mode/icss/relative.icss.css
new file mode 100644
index 0000000..c4fd934
--- /dev/null
+++ b/test/fixtures/modules/mode/icss/relative.icss.css
@@ -0,0 +1,11 @@
+:import("./vars.icss.css") {
+  IMPORTED_NAME: primary-color;
+}
+
+.className {
+  color: IMPORTED_NAME;
+}
+
+:export {
+  primary-color: IMPORTED_NAME
+}
diff --git a/test/fixtures/modules/mode/icss/vars.icss.css b/test/fixtures/modules/mode/icss/vars.icss.css
new file mode 100644
index 0000000..d4fdfda
--- /dev/null
+++ b/test/fixtures/modules/mode/icss/vars.icss.css
@@ -0,0 +1,3 @@
+:export {
+  primary-color: red;
+}
diff --git a/test/fixtures/modules/mode/modules-2.js b/test/fixtures/modules/mode/modules-2.js
new file mode 100644
index 0000000..174a7f4
--- /dev/null
+++ b/test/fixtures/modules/mode/modules-2.js
@@ -0,0 +1,5 @@
+import relative from './relative.modules.css';
+
+__export__ = relative;
+
+export default relative;
diff --git a/test/fixtures/modules/mode/relative.modules.css b/test/fixtures/modules/mode/relative.modules.css
new file mode 100644
index 0000000..7359762
--- /dev/null
+++ b/test/fixtures/modules/mode/relative.modules.css
@@ -0,0 +1,3 @@
+.relative {
+  color: red;
+}
diff --git a/test/modules-option.test.js b/test/modules-option.test.js
index 44276e1..a31c2f1 100644
--- a/test/modules-option.test.js
+++ b/test/modules-option.test.js
@@ -737,6 +737,34 @@ describe('"modules" option', () => {
     expect(getErrors(stats)).toMatchSnapshot('errors');
   });
 
+  it('should work with the "auto" by default with "modules" filename', async () => {
+    const compiler = getCompiler('./modules/mode/modules-2.js');
+    const stats = await compile(compiler);
+
+    expect(
+      getModuleSource('./modules/mode/relative.modules.css', stats)
+    ).toMatchSnapshot('module');
+    expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
+      'result'
+    );
+    expect(getWarnings(stats)).toMatchSnapshot('warnings');
+    expect(getErrors(stats)).toMatchSnapshot('errors');
+  });
+
+  it('should work with the "auto" by default for icss', async () => {
+    const compiler = getCompiler('./modules/mode/icss/icss.js');
+    const stats = await compile(compiler);
+
+    expect(
+      getModuleSource('./modules/mode/icss/relative.icss.css', stats)
+    ).toMatchSnapshot('module');
+    expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
+      'result'
+    );
+    expect(getWarnings(stats)).toMatchSnapshot('warnings');
+    expect(getErrors(stats)).toMatchSnapshot('errors');
+  });
+
   it('should work with the "auto" when it is "false"', async () => {
     const compiler = getCompiler('./modules/mode/modules.js', {
       modules: {