1

I'm trying to set up an express server for developing a React project with hot-reload, but the HMR thing requests the wrong path for some reason and I can't fix it by changing the "publicPath" option. It requests the "public" folder even though this is the folder I server static files from, so it causes the error. How do I tweak the configuration so HMR starts working? This is the error I see in the console: The error: My Webpack config:

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

const tsRules = {
    test: /\.ts(x?)$/,
    use: [
        {loader: 'react-hot-loader/webpack'},
        {loader: 'awesome-typescript-loader'},
    ]
};

const scssRules = {
    test:/\.scss$/,
    use: ['style-loader', 'css-loader', 'sass-loader']
};

//All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
const jsRules = {
    enforce: "pre",
    test: /\.js$/,
    loader: "source-map-loader"
};

module.exports = {
  entry: [
    './js/App.tsx',
    'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000'
  ],
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'public'),
    publicPath: '.'
  },
  resolve: {
    extensions:['.ts','.tsx','.js', '.json']
  },
  module: {
    rules: [
        tsRules,
        scssRules
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ],
  externals: {
    //"react": "React",
    //"react-dom": "ReactDOM"
  },
  devtool: '#source-map',
}

Server.js:

import http from 'http';
import express from 'express';
import bodyParser from 'body-parser';
import openBrowser from 'react-dev-utils/openBrowser';

var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var config = require('../webpack.config');
var compiler = webpack(config);

const app = express();
const port = process.env.PORT || 3090;

//middleware

app.use(webpackDevMiddleware(compiler, {
    noInfo: true,
    publicPath: config.output.publicPath 
}));
app.use(webpackHotMiddleware(compiler,{
    log: console.log,
    path: '/__webpack_hmr'
}));
app.use(express.static('public'));

const server = http.createServer(app);
server.listen(port, () => {
    console.log('listening on port' + port);
    openBrowser(`http://localhost:${port}/`);
}); 

folder structure:

Umbrella
  • 1,085
  • 1
  • 14
  • 30

1 Answers1

0

I also ran into this problem and here's how I solved it:

1) Inside webpack config, order of the "entry" configs matter, so set 'webpack-hot-middleware/client...' as the first item of the array

2) Define a public path for the middleware like so:

"webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr"

Hope this helps!

Ken Luk
  • 29
  • 3