Repository: webpack-contrib/mini-css-extract-plugin (js)

Issue:
Using url() in CSS requires publicPath to be set with Webpack 5
<!--
  Issues are so 🔥

  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.

  👉🏽 Need support, advice, or help? Don't open an issue!
  Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System: Windows 10
- Node Version: 14.15.0
- NPM Version: not npm, but yarn 1.22.5
- webpack Version: 5.24.0
- mini-css-extract-plugin Version: 1.3.8

### Expected Behavior

The situation is: there is a CSS file referencing an asset through `url("...")`, let's say a PNG. This CSS file is loaded by `css-loader` and the PNG by `file-loader` (Webpack 4) or an asset module (Webpack 5). I expect this to work with both Webpack 4 and 5, and a valid CSS file to be produced in the `dist` directory.

### Actual Behavior

Webpack 5 prints the error `Automatic publicPath is not supported in this browser`:
```
$ webpack
assets by status 1.42 KiB [cached] 2 assets
./css/test.css 39 bytes [built] [code generated] [1 error]

ERROR in ./css/test.css
Module build failed (from ../node_modules/mini-css-extract-plugin/dist/loader.js):
Error: Automatic publicPath is not supported in this browser
    at C:\git\webpack-repro\node_modules\css-loader\dist\cjs.js!C:\git\webpack-repro\src\css\test.css:243:34
    at C:\git\webpack-repro\node_modules\css-loader\dist\cjs.js!C:\git\webpack-repro\src\css\test.css:246:13
    at Object.<anonymous> (C:\git\webpack-repro\node_modules\css-loader\dist\cjs.js!C:\git\webpack-repro\src\css\test.css:256:12)
    at Module._compile (C:\git\webpack-repro\node_modules\v8-compile-cache\v8-compile-cache.js:192:30)
    at evalModuleCode (C:\git\webpack-repro\node_modules\mini-css-extract-plugin\dist\utils.js:42:10)
    at C:\git\webpack-repro\node_modules\mini-css-extract-plugin\dist\loader.js:214:57
    at C:\git\webpack-repro\node_modules\webpack\lib\Compiler.js:513:11
    at C:\git\webpack-repro\node_modules\webpack\lib\Compiler.js:1065:17
    at Hook.eval [as callAsync] (eval at create (C:\git\webpack-repro\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (C:\git\webpack-repro\node_modules\tapable\lib\Hook.js:18:14)

webpack 5.24.0 compiled with 1 error in 359 ms
```

However, when I set `output.publicPath` to `''`, everything seems to work correctly. With Webpack 4, the issue doesn't exist.

More information can also be found here: https://stackoverflow.com/questions/64294706/webpack5-automatic-publicpath-is-not-supported-in-this-browser. This StackOverflow post shows many people are experiencing the issue and there are workarounds available, but there's no real explanation or fix. (I guess it's a bug, because it works with Webpack 4 and Webpack should rely on sensible defaults.)

### Code

I created a minimal test case that demonstrates the issue:

```js
// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'production',
    context: path.resolve(__dirname, 'src'),
    entry: './css/test.css',
    output: {
        clean: true,

        // Workaround for the 'Automatic publicPath is not supported in this browser' error in Webpack 5 / mini-css-extract-plugin.
        // See: https://stackoverflow.com/questions/64294706/webpack5-automatic-publicpath-is-not-supported-in-this-browser
        // Uncomment the next line to make it work.
        // publicPath: "",
    },
    module: {
        rules: [
            {
                test: /\.css$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                ],
            },
            {
                test: /\.png$/i,
                type: 'asset/resource'
            },
        ],
    },
    plugins: [
        new MiniCssExtractPlugin(),
    ],
};
```

### How Do We Reproduce?

There is a repository containing a minimal reproduction here: https://github.com/evpaassen/webpack-repro.

* The `master` branch contains a version with Webpack 5. This version shows the error when running `webpack`.
* The `webpack4` branch uses Webpack 4 and this version doesn't show the error and the webpack build just succeeds.

I included the Yarn lock file, so you can reproduce the exact same setup using Yarn 1.22.5.


Pull request:
fix: `publicPath` auto
<!--
  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**
- [ ] **code refactor**
- [x] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [ ] **metadata update**

### Motivation / Use-Case

Fixed #707 

### Breaking Changes

No

### Additional Info

No


Patch:
diff --git a/src/loader.js b/src/loader.js
index 450790c..a72366a 100644
--- a/src/loader.js
+++ b/src/loader.js
@@ -44,16 +44,22 @@ export function pitch(request) {
   const childFilename = '*';
   const publicPath =
     typeof options.publicPath === 'string'
-      ? options.publicPath === '' || options.publicPath.endsWith('/')
+      ? options.publicPath === 'auto'
+        ? ''
+        : options.publicPath === '' || options.publicPath.endsWith('/')
         ? options.publicPath
         : `${options.publicPath}/`
       : typeof options.publicPath === 'function'
       ? options.publicPath(this.resourcePath, this.rootContext)
+      : this._compilation.outputOptions.publicPath === 'auto'
+      ? ''
       : this._compilation.outputOptions.publicPath;
+
   const outputOptions = {
     filename: childFilename,
     publicPath,
   };
+
   const childCompiler = this._compilation.createChildCompiler(
     `${pluginName} ${request}`,
     outputOptions


Test patch:
diff --git a/test/cases/publicpath-compiler-auto/expected/main.css b/test/cases/publicpath-compiler-auto/expected/main.css
new file mode 100644
index 0000000..339ed98
--- /dev/null
+++ b/test/cases/publicpath-compiler-auto/expected/main.css
@@ -0,0 +1,5 @@
+body {
+  background: red;
+  background-image: url(c9e192c015437a21dea1faa1d30f4941.svg);
+}
+
diff --git a/test/cases/publicpath-compiler-auto/index.js b/test/cases/publicpath-compiler-auto/index.js
new file mode 100644
index 0000000..aa3357b
--- /dev/null
+++ b/test/cases/publicpath-compiler-auto/index.js
@@ -0,0 +1,1 @@
+import './style.css';
diff --git a/test/cases/publicpath-compiler-auto/react.svg b/test/cases/publicpath-compiler-auto/react.svg
new file mode 100644
index 0000000..5b3b22a
--- /dev/null
+++ b/test/cases/publicpath-compiler-auto/react.svg
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3046.7 875.7"><title>logo-on-dark-bg</title><path fill="#FFF" d="M387 0l387 218.9v437.9L387 875.7 0 656.8V218.9L387 0z"/><path fill="#8ED6FB" d="M704.9 641.7L399.8 814.3V679.9l190.1-104.6 115 66.4zm20.9-18.9V261.9l-111.6 64.5v232l111.6 64.4zM67.9 641.7L373 814.3V679.9L182.8 575.3 67.9 641.7zM47 622.8V261.9l111.6 64.5v232L47 622.8zm13.1-384.3L373 61.5v129.9L172.5 301.7l-1.6.9-110.8-64.1zm652.6 0l-312.9-177v129.9l200.5 110.2 1.6.9 110.8-64z"/><path fill="#1C78C0" d="M373 649.3L185.4 546.1V341.8L373 450.1v199.2zm26.8 0l187.6-103.1V341.8L399.8 450.1v199.2zM198.1 318.2l188.3-103.5 188.3 103.5-188.3 108.7-188.3-108.7z"/><path fill="#F5FAFA" d="M1164.3 576.3h82.5l84.1-280.2h-80.4l-49.8 198.8-53.1-198.8H1078l-53.6 198.8-49.3-198.8h-80.4l83.6 280.2h82.5l52-179.5 51.5 179.5zM1335.2 437c0 84.1 57.3 146.3 147.4 146.3 69.7 0 107.2-41.8 117.9-61.6l-48.8-37c-8 11.8-30 34.3-68.1 34.3-41.3 0-71.3-26.8-72.9-64.3H1608c.5-5.4.5-10.7.5-16.1 0-91.6-49.3-149.5-136.1-149.5-79.9 0-137.2 63.2-137.2 147.9zm77.7-30.6c3.2-32.1 25.7-56.8 60.6-56.8 33.8 0 58.4 22.5 60 56.8h-120.6zm223.5 169.9h69.7v-28.9c7.5 9.1 35.4 35.9 83.1 35.9 80.4 0 137.2-60.5 137.2-146.8 0-86.8-52.5-147.3-132.9-147.3-48.2 0-76.1 26.8-83.1 36.4V188.9h-73.9v387.4h-.1zm71.8-139.3c0-52.5 31.1-82.5 71.8-82.5 42.9 0 71.8 33.8 71.8 82.5 0 49.8-30 80.9-71.8 80.9-45 0-71.8-36.5-71.8-80.9zm247 239.5h73.9V547.3c7 9.1 34.8 35.9 83.1 35.9 80.4 0 132.9-60.5 132.9-147.3 0-85.7-56.8-146.8-137.2-146.8-47.7 0-75.6 26.8-83.1 36.4V296h-69.7v380.5h.1zm71.8-241.1c0-44.5 26.8-80.9 71.8-80.9 41.8 0 71.8 31.1 71.8 80.9 0 48.8-28.9 82.5-71.8 82.5-40.7 0-71.8-30-71.8-82.5zm231.5 54.1c0 58.9 48.2 93.8 105 93.8 32.2 0 53.6-9.6 68.1-25.2l4.8 18.2h65.4V398.9c0-62.7-26.8-109.8-116.8-109.8-42.9 0-85.2 16.1-110.4 33.2l27.9 50.4c20.9-10.7 46.6-19.8 74.5-19.8 32.7 0 50.9 16.6 50.9 41.3v18.2c-10.2-7-32.2-15.5-60.6-15.5-65.4-.1-108.8 37.4-108.8 92.6zm73.9-2.2c0-23 19.8-39.1 48.2-39.1s48.8 14.5 48.8 39.1c0 23.6-20.4 38.6-48.2 38.6s-48.8-15.5-48.8-38.6zm348.9 30.6c-46.6 0-79.8-33.8-79.8-81.4 0-45 29.5-82 77.2-82 31.6 0 53.1 15.5 65.4 26.8l20.9-62.2c-18.2-13.9-47.2-30-88.4-30-85.2 0-149 62.7-149 147.9s62.2 146.3 149.5 146.3c40.7 0 71.3-17.1 87.3-30l-19.8-60.5c-12.4 10.1-34.9 25.1-63.3 25.1zm110.9 58.4h73.9V431.6l93.8 144.7h86.8L2940.6 423l98.6-127h-83.1l-90 117.9v-225h-73.9v387.4z"/></svg>
\ No newline at end of file
diff --git a/test/cases/publicpath-compiler-auto/style.css b/test/cases/publicpath-compiler-auto/style.css
new file mode 100644
index 0000000..52c2b3e
--- /dev/null
+++ b/test/cases/publicpath-compiler-auto/style.css
@@ -0,0 +1,4 @@
+body {
+  background: red;
+  background-image: url(./react.svg);
+}
diff --git a/test/cases/publicpath-compiler-auto/webpack.config.js b/test/cases/publicpath-compiler-auto/webpack.config.js
new file mode 100644
index 0000000..9b1ec19
--- /dev/null
+++ b/test/cases/publicpath-compiler-auto/webpack.config.js
@@ -0,0 +1,38 @@
+import Self from '../../../src';
+
+module.exports = {
+  entry: './index.js',
+  output: {
+    publicPath: 'auto',
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        use: [
+          {
+            loader: Self.loader,
+            options: {},
+          },
+          'css-loader',
+        ],
+      },
+      {
+        test: /\.(svg|png)$/,
+        use: [
+          {
+            loader: 'file-loader',
+            options: {
+              filename: '[name].[ext]',
+            },
+          },
+        ],
+      },
+    ],
+  },
+  plugins: [
+    new Self({
+      filename: '[name].css',
+    }),
+  ],
+};
diff --git a/test/cases/publicpath-loader-auto/expected/main.css b/test/cases/publicpath-loader-auto/expected/main.css
new file mode 100644
index 0000000..339ed98
--- /dev/null
+++ b/test/cases/publicpath-loader-auto/expected/main.css
@@ -0,0 +1,5 @@
+body {
+  background: red;
+  background-image: url(c9e192c015437a21dea1faa1d30f4941.svg);
+}
+
diff --git a/test/cases/publicpath-loader-auto/index.js b/test/cases/publicpath-loader-auto/index.js
new file mode 100644
index 0000000..aa3357b
--- /dev/null
+++ b/test/cases/publicpath-loader-auto/index.js
@@ -0,0 +1,1 @@
+import './style.css';
diff --git a/test/cases/publicpath-loader-auto/react.svg b/test/cases/publicpath-loader-auto/react.svg
new file mode 100644
index 0000000..5b3b22a
--- /dev/null
+++ b/test/cases/publicpath-loader-auto/react.svg
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3046.7 875.7"><title>logo-on-dark-bg</title><path fill="#FFF" d="M387 0l387 218.9v437.9L387 875.7 0 656.8V218.9L387 0z"/><path fill="#8ED6FB" d="M704.9 641.7L399.8 814.3V679.9l190.1-104.6 115 66.4zm20.9-18.9V261.9l-111.6 64.5v232l111.6 64.4zM67.9 641.7L373 814.3V679.9L182.8 575.3 67.9 641.7zM47 622.8V261.9l111.6 64.5v232L47 622.8zm13.1-384.3L373 61.5v129.9L172.5 301.7l-1.6.9-110.8-64.1zm652.6 0l-312.9-177v129.9l200.5 110.2 1.6.9 110.8-64z"/><path fill="#1C78C0" d="M373 649.3L185.4 546.1V341.8L373 450.1v199.2zm26.8 0l187.6-103.1V341.8L399.8 450.1v199.2zM198.1 318.2l188.3-103.5 188.3 103.5-188.3 108.7-188.3-108.7z"/><path fill="#F5FAFA" d="M1164.3 576.3h82.5l84.1-280.2h-80.4l-49.8 198.8-53.1-198.8H1078l-53.6 198.8-49.3-198.8h-80.4l83.6 280.2h82.5l52-179.5 51.5 179.5zM1335.2 437c0 84.1 57.3 146.3 147.4 146.3 69.7 0 107.2-41.8 117.9-61.6l-48.8-37c-8 11.8-30 34.3-68.1 34.3-41.3 0-71.3-26.8-72.9-64.3H1608c.5-5.4.5-10.7.5-16.1 0-91.6-49.3-149.5-136.1-149.5-79.9 0-137.2 63.2-137.2 147.9zm77.7-30.6c3.2-32.1 25.7-56.8 60.6-56.8 33.8 0 58.4 22.5 60 56.8h-120.6zm223.5 169.9h69.7v-28.9c7.5 9.1 35.4 35.9 83.1 35.9 80.4 0 137.2-60.5 137.2-146.8 0-86.8-52.5-147.3-132.9-147.3-48.2 0-76.1 26.8-83.1 36.4V188.9h-73.9v387.4h-.1zm71.8-139.3c0-52.5 31.1-82.5 71.8-82.5 42.9 0 71.8 33.8 71.8 82.5 0 49.8-30 80.9-71.8 80.9-45 0-71.8-36.5-71.8-80.9zm247 239.5h73.9V547.3c7 9.1 34.8 35.9 83.1 35.9 80.4 0 132.9-60.5 132.9-147.3 0-85.7-56.8-146.8-137.2-146.8-47.7 0-75.6 26.8-83.1 36.4V296h-69.7v380.5h.1zm71.8-241.1c0-44.5 26.8-80.9 71.8-80.9 41.8 0 71.8 31.1 71.8 80.9 0 48.8-28.9 82.5-71.8 82.5-40.7 0-71.8-30-71.8-82.5zm231.5 54.1c0 58.9 48.2 93.8 105 93.8 32.2 0 53.6-9.6 68.1-25.2l4.8 18.2h65.4V398.9c0-62.7-26.8-109.8-116.8-109.8-42.9 0-85.2 16.1-110.4 33.2l27.9 50.4c20.9-10.7 46.6-19.8 74.5-19.8 32.7 0 50.9 16.6 50.9 41.3v18.2c-10.2-7-32.2-15.5-60.6-15.5-65.4-.1-108.8 37.4-108.8 92.6zm73.9-2.2c0-23 19.8-39.1 48.2-39.1s48.8 14.5 48.8 39.1c0 23.6-20.4 38.6-48.2 38.6s-48.8-15.5-48.8-38.6zm348.9 30.6c-46.6 0-79.8-33.8-79.8-81.4 0-45 29.5-82 77.2-82 31.6 0 53.1 15.5 65.4 26.8l20.9-62.2c-18.2-13.9-47.2-30-88.4-30-85.2 0-149 62.7-149 147.9s62.2 146.3 149.5 146.3c40.7 0 71.3-17.1 87.3-30l-19.8-60.5c-12.4 10.1-34.9 25.1-63.3 25.1zm110.9 58.4h73.9V431.6l93.8 144.7h86.8L2940.6 423l98.6-127h-83.1l-90 117.9v-225h-73.9v387.4z"/></svg>
\ No newline at end of file
diff --git a/test/cases/publicpath-loader-auto/style.css b/test/cases/publicpath-loader-auto/style.css
new file mode 100644
index 0000000..52c2b3e
--- /dev/null
+++ b/test/cases/publicpath-loader-auto/style.css
@@ -0,0 +1,4 @@
+body {
+  background: red;
+  background-image: url(./react.svg);
+}
diff --git a/test/cases/publicpath-loader-auto/webpack.config.js b/test/cases/publicpath-loader-auto/webpack.config.js
new file mode 100644
index 0000000..9ea565d
--- /dev/null
+++ b/test/cases/publicpath-loader-auto/webpack.config.js
@@ -0,0 +1,37 @@
+import Self from '../../../src';
+
+module.exports = {
+  entry: './index.js',
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        use: [
+          {
+            loader: Self.loader,
+            options: {
+              publicPath: 'auto',
+            },
+          },
+          'css-loader',
+        ],
+      },
+      {
+        test: /\.(svg|png)$/,
+        use: [
+          {
+            loader: 'file-loader',
+            options: {
+              filename: '[name].[ext]',
+            },
+          },
+        ],
+      },
+    ],
+  },
+  plugins: [
+    new Self({
+      filename: '[name].css',
+    }),
+  ],
+};