Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't make react-hot-loader and webpack-dev-server work with react-router

I'm trying to use react-hot-loader with webpack-dev-server and react-router, but when I try to access localhost:3000/ I get :

Cannot GET /

Of course, it works when I try to access localhost:8000/. I tried to follow react-hot-boilerplate, without success.

Here's my code:

server.js

const http = require('http');
const express = require('express');
const consolidate = require('consolidate');
const bodyParser = require('body-parser');
const routes = require('./routes');

const app = express();

app.set('views', 'public/pages'); // Set the folder-name from where you serve the html page.
app.set('view engine', 'html');
app.engine('html', consolidate.handlebars);
app.use(express.static('public')); // Set the folder from where you serve all static files
app.use(express.static('public/dist')); // Set the folder from where you serve all static files
app.use(bodyParser.urlencoded({ extended: true }));

const portNumber = 8000;

http.createServer(app).listen(portNumber, () => {
  console.log(`Server listening at port ${portNumber}`);
  routes.initialize(app);
});

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.config');

new WebpackDevServer(webpack(config), {
  colors: true,
  historyApiFallback: true,
  inline: true,
  hot: true,
}).listen(3000, 'localhost', (err) => {
  if (err) {
    console.log(err);
  }
});

routes.js (so all the routes point to the router)

function initialize(app) {
  const routes = [
    '/',
    '/login',
  ];

  routes.forEach((route) => {
    app.get(route, (req, res) => {
      res.render('main-content.html');
    });
  });
}

exports.initialize = initialize;

webpack.config.js

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

const nodeDir = `${__dirname}/node_modules`;

const config = {
  resolve: {
    alias: {
      react: `${nodeDir}/react`,
      'react-dom': `${nodeDir}/react-dom`,
      'react-router': `${nodeDir}/react-router`,
      'react-bootstrap': `${nodeDir}/react-bootstrap`,
      velocity: `${nodeDir}/velocity-animate`,
      moment: `${nodeDir}/moment`,
      slimscroll: `${nodeDir}/slimscroll`,
    },
  },
  entry: {
    routes: [
      'webpack-dev-server/client?http://localhost:3000',
      'webpack/hot/only-dev-server',
      './public/src/routes/js/main',
    ],
    vendors: [
      'react', 'react-dom', 'react-router', 'react-bootstrap',
      'velocity', 'moment', 'slimscroll',
    ],
  },
  output: {
    path: path.join(__dirname, 'public/dist'),
    publicPath: path.join(__dirname, 'public/dist'),
    filename: 'bundles/[name].bundle.js',
    chunkFilename: 'chunks/[name].chunk.js',
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        include: path.join(__dirname, 'public'),
        loader: 'react-hot',
      },
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'public'),
        loader: 'babel',
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'public'),
        loader: 'style!css-loader?modules&importLoaders=1' +
        '&localIdentName=[name]__[local]___[hash:base64:5]',
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.optimize.CommonsChunkPlugin('vendors', './bundles/vendors.js', Infinity),
  ],
};

module.exports = config;

scripts

"scripts": {
    "dev": "webpack --config webpack.config.js",
    "hot": "webpack-dev-server --devtool eval --progress --colors --inline --hot",
    "build": "webpack -p --config webpack.config.prod.js"
  }

main-content.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Brigad Admin Panel</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Customs -->
    <link rel="stylesheet" href="styles/global.css">
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,600,400italic,700,600italic,700italic,800,800italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
  </head>

  <body class="hold-transition">
    <div id="content"></div>

    <!--<script src="dist/bundles/vendors.js"></script>-->
    <!--<script src="dist/bundles/routes.bundle.js"></script>-->

    <script src="http://localhost:8080/public/dist/bundles/vendors.js"></script>
    <script src="http://localhost:8080/public/dist/bundles/routes.bundle.js"></script>
  </body>
</html>

entry point

import React from 'react';
import { render } from 'react-dom';
import { Router, browserHistory } from 'react-router';

import RootRoute from './components/RootRoute';

render(
  <Router history={browserHistory} routes={RootRoute} />,
  document.getElementById('content')
);

How can I make react-hot-loader to work?

Thanks in advance.

like image 913
adrienharnay Avatar asked Apr 26 '16 11:04

adrienharnay


1 Answers

You should provide localhost:3000 for publicPath in webpack.config.

In the dev-server config you maybe need to add contentBase option pointing to your build output (./public/dist).

Take a look at this https://github.com/webpack/docs/wiki/webpack-dev-server#content-base

like image 93
Maxdow Avatar answered Sep 19 '22 18:09

Maxdow