4

I am new to React webpack and such and I am trying to implement Hot Module replacement into my workflow. I am using webpack, express, Babel ES6 with React and I believe I have all the loaders that i need.

I have got HMR working for my CSS files and it updates CSS perfectly but for some reason, when I try and update a React component, I get the following error and have to refresh the page in order to see my changes. I've been struggling the whole day so any assistance would be greatly received! The error I get is the following (my code follows afterward):

>Ignored an update to unaccepted module 28 -> 17
>
[HMR] The following modules couldn't be hot updated: (Full reload needed)
This is usually because the modules which have changed (and their parents) do not know how to hot reload themselves. See https://webpack.js.org/concepts/hot-module-replacement/ for more details.
>
[HMR]  - ./app/scripts/libs/index.js

index.js (Entry)

import React from 'react';
import ReactDOM from 'react-dom';
import style from 'css/main.css';
import Sections from 'components/Sections/index.js';


ReactDOM.render(
    <div>
        <h2>Hek</h2> 
        <Sections></Sections>
    </div>, 

    document.getElementById('app')
)

console.log('check for me');

index.js (Sections Component)

import React from 'react';
import ReactDOM from 'react-dom';

export class Sections extends React.Component{
    render(){
        return(
            <div>
                <h1>Yo yo yo wahts</h1>
                <p>hlfgdfd</p>
            </div>
        )
    }
}

module.exports = Sections;

BuildScript.js 'use strict';

var express = require('express'); //get the express module
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');

var app = express(); //create a new instance of that class
var config = require('../../../webpack.config.js');
var compiler = webpack(config);


app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath
}));

app.use(webpackHotMiddleware(compiler));

app.listen(3000, function () {
    // return console.log('Example app listening on port 3000!');
});

Webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    entry: [ 'webpack-hot-middleware/client' , './app/scripts/libs/index.js'], //Can also use "main" property
    output: {
        path: path.resolve(__dirname, 'tmp'), //resolves the absolute path 
        filename: '[name].bundle.js', //
        publicPath: '/'
    },
    devtool: 'inline-source-map',
    resolve:{
        alias: {
            components: path.resolve(__dirname, 'app/scripts/components'),
            fonts: path.resolve(__dirname,  'app/scripts/fonts'),
            images: path.resolve(__dirname,  'app/images'),
            sass: path.resolve(__dirname,  'app/styles/sass'),
            css: path.resolve(__dirname,  'app/styles/css')
        }
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'] //to use the CSS imported - in your index.js file you 
            },
            {
                test: /\.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(jpg|png|svg|gif)$/,
                use:['file-loader']
            },            
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: ['file-loader']
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                query: {
                    presets: ['env', 'react']
                }

            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            title: 'African Banker Awards 2018',
            template: './app/scripts/libs/template.ejs',
            inject: 'body'
        }), 
        new CleanWebpackPlugin(['tmp']),
        new webpack.HotModuleReplacementPlugin()
        //new UglifyJsPlugin()
    ]
  };

NPM Packages Installed

  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "clean-webpack-plugin": "^0.1.17",
    "css-loader": "^0.28.7",
    "eslint": "^4.10.0",
    "file-loader": "^1.1.5",
    "html-webpack-plugin": "^2.30.1",
    "install": "^0.10.1",
    "npm": "^5.5.1",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.19.0",
    "uglifyjs-webpack-plugin": "^1.1.4",
    "webpack": "^3.10.0",
    "webpack-dev-middleware": "^2.0.1",
    "webpack-hot-middleware": "^2.21.0"
  }
}
Daniel Takyi
  • 159
  • 1
  • 9
  • 5
    At `webpack.config.js` Have you tried finishing the request parameter on your entry for webpack-hot-middleware? You should typically assign the `reload` key to a value of `true` such as... ``js entry: [ 'webpack-hot-middleware/client?reload=true' , './app/scripts/libs/index.js'], `` – Tobiah Rex Jan 25 '18 at 19:17
  • @TobiahRex - You are the man dude! the "reload=true" i guess forces the reload and now its working great! i would have never realised. Thank you so much! – Daniel Takyi Jan 25 '18 at 23:30
  • 1
    Glad to hear it. You may already know this, but in case not: Webpack uses inline params in most string delineated entries. For example when specifying loaders - you're allowed to use option objects with key/value pairs or inline strings with options articulated as query params. [More Info](https://webpack.js.org/concepts/loaders/#inline) – Tobiah Rex Jan 25 '18 at 23:38

0 Answers0