Monday, 17 April 2017

Use React-Router browserHistory, Wepback 2 historyApiFallback and Node

I'm trying to run my React app locally using React, Node, Wepback 2. Whenever I hit a route that isn't / I get a 404. My goal is to be able to run my node server, have webpack-dev-server run, use browserHistory and back my webpack historyApiFallback work.

What currently does work:

  1. If I just run webpack-dev-server and no node server then browserHistory works fine, no 404s.
  2. If I run node with hashHistory it works fine, no 404s.

So that rules out that my routes aren't working. Here is some code:

server.js

const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema');

const app = express();

app.use('/graphql', expressGraphQL({
  schema,
  graphiql: true
}));

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));

app.listen(process.env.PORT || 5000, () => console.log('Listening'));


webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const VENDOR_LIBS = [
  'axios', 'react', 'react-dom', 'react-router', 'react-apollo', 'prop-types'
];

module.exports = {
  entry: {
    bundle: './client/src/index.js',
    vendor: VENDOR_LIBS
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: '[name].[chunkhash].js'
  },
  module: {
    rules: [
      {
        use: 'babel-loader',
        test: /\.js$/,
        exclude: /node_modules/
      },
      {
        test: /\.scss$/,
            use: [{
                loader: "style-loader"
            }, {
                loader: "css-loader"
            }, {
                loader: "sass-loader"
            }]
      },
      {
        test: /\.(jpe?g|png|gif|svg|)$/,
        use: [
          {
            loader: 'url-loader',
            options: {limit: 40000}
          },
          'image-webpack-loader'
        ]
      }
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor', 'manifest']
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    }),
    new HtmlWebpackPlugin({
      template: './client/src/index.html'
    })
  ],
  devServer: {
    historyApiFallback: true
  }
};


routes.js

import React from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';

import App from './components/App';
import Portal from './components/portal/Portal';

const componentRoutes = {
  component: App,
  path: '/',
  indexRoute: { component: Portal },
  childRoutes: [
    {
      path: 'home',
      getComponent(location, cb) {
        System.import('./components/homepage/Home')
          .then(module => cb(null, module.default));
      }
    }
  ]
};

const Routes = () => {
  return <Router history={ browserHistory } routes={ componentRoutes } />
};

export default Routes;

Again, the goal is to be able to locally start up my node server, use browserHistory and not get 404s. I don't want to use hashHistory and I need to use my node server so I can use graphql. I also don't want to revert back to webpack v1. Though here is a link to where people got it working in v1:

historyApiFallback doesn't work in Webpack dev server



via user2465134

No comments:

Post a Comment