11

I am trying to set up webpack hot reloading with react-hot-loader. It mostly seems to be working. I am using webpack in an existing rails app.

But it isn't hot-reloading. It is simply triggering a reload every time my react code is changed. The error messages I get are:

[HMR] Cannot apply update. Need to do a full reload! - dev-server.js:18
[HMR] Error: Aborted because 0 is not accepted - dev-server.js:19
  at hotApply (http://localhost:8080/assets/webpack/bundle.js?body=1:380:31)
  at hotUpdateDownloaded (http://localhost:8080/assets/webpack/bundle.js?body=1:293:13)
  at hotAddUpdateChunk (http://localhost:8080/assets/webpack/bundle.js?body=1:273:13)
  at webpackHotUpdateCallback (http://localhost:8080/assets/webpack/bundle.js?body=1:5:12)
  at http://localhost:8080/assets/webpack0.bd89931b2fa8e2901794.hot-update.js:1:1

Navigated to http://lvh.me:3000/react_page

Here is my webpack.hot.config.js settings:

var path = require('path');
var webpack = require('webpack');

var config = module.exports = {

    // Set 'context' for Rails Asset Pipeline
    context: __dirname,

    entry: {
        App: [
            'webpack-dev-server/client?http://localhost:8080/', // WebpackDevServer host and port
            'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
            './app/frontend/javascripts/app.js' // Your appʼs entry point
        ],
        vendor: ['jquery', 'react', 'react-dom', 'react-redux', 'redux','redux-thunk']
    },

    devtool: 'inline-source-map',

    // Require the webpack and react-hot-loader plugins
    plugins: [
        //new webpack.HotModuleReplacementPlugin(),
        new webpack.optimize.CommonsChunkPlugin(
        {
            name: 'vendor',
            chunks: [''],
            filename: 'vendor.js',
            minChunks: Infinity
        }),
        new webpack.NoErrorsPlugin(),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jquery': 'jquery'
        })
    ],
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loaders: [
                    'react-hot',
                    'babel?presets[]=es2015&presets[]=react'
                ],
                cacheDirectory: true
            }
        ]
    },
    output: {
        path: path.join(__dirname, 'app', 'assets', 'javascripts', 'webpack'), // Save to Rails Asset Pipeline
        filename: 'bundle.js', // Will output App_wp_bundle.js
        publicPath: 'http://localhost:8080/assets/webpack',

        //publicPath: 'http://localhost:8080/assets/webpack' // Required for webpack-dev-server
    },
    resolve: {
        extensions: ['', '.js', '.jsx'],
        modulesDirectories: ['node_modules'],
    },

};

And I run the code with

webpack-dev-server -d --config webpack.hot.config.js --hot --inline

The rails development environment serves the webpack files outside the application asset pipeline via the webpack-dev-server because of the following setting in my development.rb file.

config.action_controller.asset_host = Proc.new { |source|
  if source =~ /webpack\/bundle\.js$/i
    "http://localhost:8080"
  end
}

I have been trying to get this working for hours. Any help would be appreciated.

Thanks guys!

S.Kiers
  • 4,086
  • 3
  • 32
  • 38

6 Answers6

6

Ok i was getting the same error, but after trying some things out i figured this out: My root component was a stateless functional component (pure function). I refactored it to a class component and BAM! the hot reloading is working again.

Before:

const App = (props) => (
  <div>
    <Header links={headerLinks} logoSrc={logoSrc} />
    {props.children}
  </div>
);

After:

class App extends React.Component {
  render() {
    return (
      <div>
        <Header links={headerLinks} logoSrc={logoSrc} />
        {this.props.children}
      </div>
    );
  }
}
5

As the answers provided above are still not working on my side with webpack 5, Here is the working config from webpack

In webpack.config.js

devServer: {
    .
    .
    .
    hot: true,
  }

In the webpack entrypoint index.js add

if (module.hot) {
    module.hot.accept();
}

In package.json start script

"scripts": {
    .
    .
    "start": "webpack serve --config /webpack.config.js"
  },
Nwawel A Iroume
  • 1,249
  • 3
  • 21
  • 42
2

I recently ran into this exact issue, the fix for me was removing this from the entries array: 'webpack-dev-server/client?http://localhost:9000/',.

As I was also running --hot as a command line argument, there were two instances of webpack-dev-server getting into a bad state.

Tyler Kelley
  • 167
  • 7
1

I don't know if this will specifically help your issue, but I encountered this error recently as well - i fixed it by adding a .js extension to the module I was trying to set up with hmr - here was my code

if (module.hot) {
  module.hot.accept('app/Routes', () => (
    getRoutes = require('app/Routes')
  ))
}

I updated it to getRoutes = require('app/Routes.js') and the error disappeared, using webpack ^2.0.0-beta.

it also works if i add the JS extension as the first argument of hot accept like so:

if (module.hot) {
  module.hot.accept('app/Routes.js', () => (
    getRoutes = require('app/Routes')
  ))
}

so now it matches whats on the webpack HMR page

random-forest-cat
  • 33,652
  • 11
  • 120
  • 99
1

I ran into a similar problem. After 2 days of research and trying different things, I found out the simplest cause to my problem ever: in webpack.config.js, I had a HRM dev server enabled. And I also had a HMR server run from command line. Thanks to hint from Tyler Kelley (see above), just by removing --hot from command line, it works OK now.

current webpack.config.js

devtool: "inline-source-map",
devServer: {
    publicPath: '/dist/',
    contentBase: path.join(__dirname, 'public'),
    port: 9000,
    hot: true
},

With this configuration, don't do this:

npx webpack-dev-server --hot --inline

Do this:

npx webpack-dev-server

voltel
  • 41
  • 4
0

For "webpack": "^5.74.0" and "webpack-dev-server": "^4.11.1". I set devServer.static = ['./webpack-dev-server', './dist'], in webpack.config.js. There is my config:

module.exports = {
devtool: 'inline-source-map',
devServer: {
    open: true,
    static: ['./webpack-dev-server', './dist']
},
entry: path.join(__dirname, 'src', 'index.ts'),
module: {
    rules: [
        {
            test: /\.(ttf|png|svg|jpg|jpeg)$/i,
            type: 'asset/resource',
        },
        {
            test: /\.css$/,
            use: ['style-loader', 'css-loader'],
        },
        {
            test: /\.ts$/,
            loader: 'ts-loader',
            options: {
                configFile: path.join(__dirname, 'tsconfig.json')
            }
        }
    ]
},
mode: 'development',
output: {
    filename: '[name][contenthash].js',
    path: path.join(__dirname, 'dist'),
    clean: true,
},
plugins: [
    new HtmlWebpackPlugin({
        template: path.join(__dirname, 'src', 'index.html'),
        inject: 'body'
    })
],
resolve: {
    extensions: ['.js', '.ts']
}

}