reactjswebpackreact-router-v4

Webpack and React BrowserRouter


im working on a project that was made in react with hashrouter, i want to change to browserouter but the project already has a webpack config and im kind of new to it, i know i should make webpack to take all calls to index (since im getting Cannot get on all routes) but i cant find any info on this kind of setup:

This is the current webpack config

const path = require('path');
const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');

module.exports = {
    devtool: 'cheap-module-source-map',
    entry: {
        app: [
            'webpack-hot-middleware/client',
            'react-hot-loader/patch',
            './src/app'
        ]
    },
    resolve: {
        modules: ['node_modules'],
        extensions: ['.js', '.jsx', '.scss'],
        alias: {
            'react-native': 'react-native-web'
        }
    },
    output: {
        path: path.join(__dirname, 'public/assets'),
        publicPath: '/assets/',
        filename: '[name].bundle.js'
    },
    module: {
        rules: [{
            test: /\.jsx?$/,
            exclude: /node_modules/,
            use: [{
                loader: 'react-hot-loader/webpack'
            }, {
                loader: 'babel-loader', options: {cacheDirectory: '.babel-cache'}
            }]
        }, {
            // Most react-native libraries include uncompiled ES6 JS.
            test: /\.js$/,
            include: [
                /node_modules\/react-native-/,
                /node_modules\/react-router-native/,
                /node_modules\/@indec/
            ],
            loader: 'babel-loader',
            query: {
                presets: ['react-app'],
                cacheDirectory: '.babel-cache'
            }
        }, {
            test: /\.scss$/,
            loader: [
                'css-hot-loader'
            ].concat(
                ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            )
        }, {
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }, {
            exclude: [
                /\.html$/,
                /\.(js|jsx)$/,
                /\.json$/,
                /\.s?css$/,
                /\.(jpg|png)/
            ],
            loader: 'url-loader',
            options: {name: '[name].[ext]', limit: 10000}
        }, {
            test: /\.(jpg|png)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: 'file-loader',
            options: {name: '[name].[ext]'}
        }]
    },
    plugins: [
        new webpack.DefinePlugin({
            VERSION: JSON.stringify(require('./package.json').version),
            NODE_ENV: JSON.stringify(process.env.NODE_ENV),
            ENDPOINT: JSON.stringify(require('./config.json').endpoint)
        }),
        new webpack.optimize.CommonsChunkPlugin('vendor'),
        new webpack.HotModuleReplacementPlugin(),
        new CaseSensitivePathsPlugin(),
        new FriendlyErrorsWebpackPlugin(),
        new ExtractTextPlugin('[name].bundle.css')
    ],
    node: {
        fs: 'empty',
        net: 'empty',
        tls: 'empty'
    }
};

app gets initiated on this index.js file

    const path = require('path');
    const app = require('connect')();
    const config = require('./config.json');
    const winston = require('winston');

    const PORT = process.env.PORT || config.server.port;

    process.env.NODE_ENV = config.mode;
    app.use(require('morgan')(config.server.morgan));
    app.use(require('compression')());
    app.use(require('serve-static')(path.join(__dirname, config.server.static)));

    if (config.mode === 'development') {
        const config = require('./webpack.config');
        const compiler = require('webpack')(config);

        app.use(require('webpack-dev-middleware')(compiler, {
            publicPath: config.output.publicPath,
        }));
        app.use(require('webpack-hot-middleware')(compiler));
    }

    require('http').createServer(app).listen(
        PORT,
        () => winston.info('Server started at port %s', config.server.port)
    );

and my app js

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Aux from 'react-aux';

import Home from '../Home';
import Admin from '../Admin';
import SignIn from '../SignIn';

import Header from './Header';
import Footer from './Footer';

const App = () => (
    <BrowserRouter>
        <Aux>
            <Header/>
            <main>
                <Switch>
                    <Route path="/" component={Home}/>
                    <Route path="/admin" component={Admin}/>
                    <Route path="/signIn" component={SignIn}/>
                </Switch>
            </main>
        </Aux>
    </BrowserRouter>
);

export default App;

Solution

  • I end up finding a easy solution, just created a express app and handled all 404 to index, didn't find how to do it with connect.

    const path = require('path');
    const express = require('express');
    const app = express();
    const config = require('./config.json');
    const winston = require('winston');
    
    const PORT = process.env.PORT || config.server.port;
    
    process.env.NODE_ENV = config.mode;
    app.use(require('morgan')(config.server.morgan));
    app.use(require('compression')());
    app.use(require('serve-static')(path.join(__dirname, config.server.static)));
    
    
    
    if (config.mode === 'development') {
        const config = require('./webpack.config');
        const compiler = require('webpack')(config);
    
        app.use(require('webpack-dev-middleware')(compiler, {
            publicPath: config.output.publicPath,
        }));
        app.use(require('webpack-hot-middleware')(compiler));
    }
    
    app.get('/*', function(req, res) {
        res.sendFile(path.join(__dirname, './public/index.html'), function(err) {
            if (err) {
                res.status(500).send(err);
            }
        });
    });
    
    app.use((req, res, next) => {
        const err = new Error('Not Found');
        err.status = 404;
        next(err);
    });
    
    require('http').createServer(app).listen(
        PORT,
        () => winston.info('Server started at port %s', config.server.port)
    );