Search code examples
javascriptwebpackwebpack-5hot-reload

Webpack 5 HMR throws Uncaught TypeError: cannot set property <filename> of undefined at self.webpackHotUpdate


After upgrading to Webpack 5, HMR has stopped working on our React project.

Current versions of modules are: @webpack-cli/[email protected], [email protected], [email protected], [email protected] [email protected] (note, it was failing exactly the same way with earlier non-rc version of webpack-dev-server)

The browser console reports:

Uncaught TypeError: Cannot set property 
'./resources/assets/js/screens/LandingPage/LandingPage.js' of undefined
at self.webpackHotUpdate (jsonp chunk loading:44)
at bundle.7fe3c7a98c4f94dbfe6d.hot-update.js:2

The above happens when the code is changed - the watch detects it, and the recompile takes place, but the above error is thrown preventing the browser reloading. Manual reload on the browser works fine.

Running

webpack-cli serve --config=webpack.dev.config.js

Config file is:

module.exports = {
    mode: 'development',
    entry: {
        [bundleNames.js]: path.join(__dirname, `${assetsDir}/js/app.js`),
        [bundleNames.css]: path.join(__dirname, `${assetsDir}/less/styles.less`)
    },
    output: {
        filename: '[name].js',
        path: path.join(__dirname, publicPath),
        publicPath: '/',
    },
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                use: 'babel-loader',
                include: [path.resolve(__dirname, `${assetsDir}/js`)],
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader',
                ],
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.png$|\.xml$|\.ico$|\.svg$/,
                use: ['file-loader?name=[name].[ext]'],
                include: [path.resolve(__dirname, `${assetsDir}/favicons`)],
            },
            {
                test: /\.json$/,
                use: ['file-loader?name=[name].[ext]'],
                type: 'javascript/auto',
                include: [path.resolve(__dirname, `${assetsDir}/favicons`)],
            },
            {
                test: /\.woff2?$|\.ttf$|\.eot$|\.svg$|\.png$|\.jpe?g$|\.gif$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            esModule: false,
                            name: './static/[name].[ext]',
                        },
                    },
                ],
            },
            {
                test: /\.js$/,
                use: ['file-loader?name=static/[name].[ext]'],
                include: [path.resolve(__dirname, `${assetsDir}/static`)],
            },
        ],
    },
    plugins: [
        new webpack.DefinePlugin({
            'LOCALE_HASH': `'${LOCALE_HASH}'`,
        }),
        new webpack.HotModuleReplacementPlugin({}),
    ],
    resolve: {
        extensions: ['.js'],
        fallback: {
            "fs": false
        }
    },
    devServer: {
        hot: true,
        host: '0.0.0.0',
        port: 3000,
        proxy: {
            '*': {
                target: config.WEBPACK_PROXY_URL,
                changeOrigin: true
            }
        },
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        historyApiFallback: false,
    }
};

Solution

  • The solution was:

    Remove the CSS line from Webpack config:

    entry: {
            [bundleNames.js]: path.join(__dirname, `${assetsDir}/js/app.js`),
    -->     [bundleNames.css]: path.join(__dirname, `${assetsDir}/less/styles.less`)
        },
    

    instead import the Less directly in app.js:

    import '../less/styles.less';