78

I was working on webpack 4.44.2, I face this error when I convert to webpack5.0.0

ERROR in ./src/assets/sass/styles.scss Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): Error: Automatic publicPath is not supported in this browser at E:\maktab\Control-panel\newcontrol\final-control\node_modules\css-loader\dist\cjs.js!

the error is from the font file bath in fonts.scss

@font-face {
    font-family: "Janna LT";
    src: local("Janna LT"), url(../fonts/janna.woff) format("woff");
    font-weight: normal;
}

@font-face {
    font-family: "Janna LT";
    src: local("Janna LT"), url(../fonts/janna-bold.woff) format("woff");
    font-weight: bold;
}

my src structure https://i.stack.imgur.com/vKyfW.png

dist structure https://i.stack.imgur.com/mLgmF.png

webpack.config.js

const path = require('path');

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry:  {
      'main': './src/index.js',
    },
  
    output: {
      path: path.join(__dirname, "/dist"),
      filename: '[name].js',
    }, 

    devServer: {
        contentBase: path.join(__dirname, "/dist"),
        port: 8087,
        writeToDisk: true,
        overlay :true
    },
    

    module: {
        rules: [
    
            {
                test: /\.html$/,
                use: [
                    {
                        loader: "html-loader",
                    }
                ]
            },

            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                MiniCssExtractPlugin.loader, 
                'css-loader', 
                'postcss-loader',
                'sass-loader'
                ]
            },
                    
            {
                test: /\.(png|svg|jpe?g|gif)$/,
                exclude: /fonts/,
                use: [
                    {
                        loader: "file-loader", 
                        options: {
                        name: '[name].[ext]',
                        outputPath: "/assets/images",
                        }
                    }
                ]
            },

            {
                test: /\.(svg|eot|woff|woff2|ttf)$/,
                exclude: /images/,
                use: [
                    {
                        loader: "file-loader", 
                        options: {
                        name: '[name].[ext]',
                        outputPath: "assets/fonts",
                        }
                    }
                ]
            },

        ]
    },

    plugins: [
        new CleanWebpackPlugin(),

        new HtmlWebpackPlugin({ 
          filename: "index.html",
          template: "./src/index.html",
          chunks: ['main']
        }),
      

        new MiniCssExtractPlugin({filename: "assets/css/styles.css"}),
        new OptimizeCSSAssetsPlugin({}),
    ]
    
} 

styles.scss

@import "base/fonts";
@import "base/global";
@import "base/typography";
@import "base/links";
@import "components/components";
@import "components/demo";

index.js

import './assets/sass/styles.scss';
import 'normalize.css/normalize.css';

console.log("hellow from webpack5");
entesar
  • 929
  • 1
  • 8
  • 12
  • 1
    it works well with no any error; when replacing mini-css-extract-plugin with style-loder!!! – entesar Oct 10 '20 at 15:09
  • As I suspect this is a bug with mini-css-extract-plugin, I opened an issue with minimal reproduction: https://github.com/webpack-contrib/mini-css-extract-plugin/issues/707 – P44T Feb 23 '21 at 09:05

9 Answers9

94

The suggested solutions didn't work for me. However, I found that setting publicPath to an empty string did the trick.

output: {
  publicPath: '',
  ...
}
NorthernIsle
  • 941
  • 6
  • 6
  • 1
    Don't forget to remove `style-loader` if you use one. Otherwise you get the following error: [`ReferenceError: window is not defined`](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/288) fixed it by removing the `style-loader`. Info from this [GitHub comment](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/288#issuecomment-464665178) – TessavWalstijn Dec 17 '20 at 09:08
  • thanks, that worked for me! – globus243 Sep 27 '21 at 17:59
  • I got the error only on IE ( exactly IE11). And prio to this error reported, ie report error found in this comment line `// or pass an empty string ("") and set the __webpack_public_path__ variable` from webpack. I dont know why, but `publicPath: '',` fixed both. – scil Aug 02 '22 at 16:27
16

I encountered the same issue. My code compiles into the dist-folder without any further structure. The following code works for me and is simple since I need an empty path.

'module': {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader, 
                        options: {
                            publicPath: ''
                        }
                    },
                    {
                        loader: "css-loader"
                    }
                ]
            }
        ]
    }

You can go crazy and do things like that, too:

{
    loader: MiniCssExtractPlugin.loader,
    options: {
        publicPath: (resourcePath, context) => {
            return path.relative(path.dirname(resourcePath), context) + '/';
        },
    },
},

Details you can find here: https://webpack.js.org/plugins/mini-css-extract-plugin/#the-publicpath-option-as-function

Sven Bluege
  • 1,418
  • 1
  • 10
  • 19
  • could u tell me how to use the function, are we need to change "resourcePath" with src for example.. or change the context!! – entesar Nov 08 '20 at 10:46
10

The error is caused by a bug in mini-css-extract-plugin 1.3.8 and lower in combination with Webpack 5. It is triggered when a stylesheet references a resource using url(...) and the publicPath option is not set explicitly in the Webpack configuration.

I took the time to reproduce and report the issue here: https://github.com/webpack-contrib/mini-css-extract-plugin/issues/707

Yesterday, version 1.3.9 has been released and it includes the fix for this issue. You should be able to resolve this error by upgrading.

P44T
  • 1,109
  • 12
  • 21
  • Pfff! Thanks alot! It was driving me crazy, was about to delete the mini-css-extract-plugin, Thank you and yes indeed, this solves the Issue! – Alan Daniel Feb 27 '21 at 17:39
  • Where there any noticeable changes in the site when you had this error? – Jonathan Aug 10 '23 at 00:25
6

you can try this way:

//add output.publicpath
output: {
  publicPath: '/',
  ...
}
xoyimi
  • 61
  • 1
  • 2
    That was my first try. It resulted in absolute paths like /foo.jpg and will not work if images, css and js is placed in the same dist folder as the CSS file :) – Sven Bluege Nov 02 '20 at 18:06
4

Inside your webpack.config.js you have to do as following, either to use environment variable as following or the root it will take.

//step-1 const ASSET_PATH = process.env.ASSET_PATH || '/';

//step-2 Inside output object as below: publicPath: ASSET_PATH

//step-3 Inside plugins as below: 'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH)

For more info refer here, https://webpack.js.org/guides/public-path/

  • 4
    thanks, @Mannawar Hussain. the idea is in publicpath, in my case, adding publicPath: '/', in output (only), solve my issue. – entesar Oct 11 '20 at 15:07
4

I think it will be helpful that added publicPath to the options of MiniCssExtractPlugin.loader

reference: mini-css-extract-plugin

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '/public/path/to/',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
Littlefish
  • 81
  • 3
4

I was also getting the same error while loading images using 'file-loader'. I was only providing the outputPath. But then I also provided publicPath both with same value and it worked.

{
    test: /\.svg$/i,
    use: {
        loader: 'file-loader',
        options: {
            name: "[name].[ext]",
            outputPath: "imgs",
            publicPath: 'imgs',
        }
    }
  },

outputPath: tells where to put images/files. enter image description here

publicPath: is the path inserted into src="" of img element in html.

<img src="imgs/webpack.svg"/>

So both should have the same path.

sau0409
  • 153
  • 1
  • 5
3

pay attention to the tag of <script> in index.html,which type is default but not is module

Works

<script src="./build/bundle.js"></script> 

Creates Error

<script type="module" src="./build/bundle.js"></script>
Marcello B.
  • 4,177
  • 11
  • 45
  • 65
tsja 2001
  • 31
  • 2
0

I'm distributing a React app with a script tag only on 3rd party sites, so I'm using style-loader, and not emitting a separate CSS file.

The way I fixed this issue was defining an output.publicPath in the production webpack configuration and upgrading to the latest webpack version.

Dylan Pierce
  • 4,313
  • 3
  • 35
  • 45