React Routing with Express, Webpack dev middleware, React router dom

Viewed 945

I have trouble in routing using react-router-dom and custom dev server using express, webpack-dev-middleware, webpack-hot-middleware.

This is my webpack config.

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

module.exports = {
    entry: [
        // 'react-hot-loader/patch',
        'webpack-hot-middleware/client?reload=true',
        './index.js'
    ],
    output: {
        filename: '[name].js',
        path: path.join(__dirname, './dist'),
        publicPath: '/',
        clean: true,
        chunkFilename: '[name].chunk.js',
    },
    mode: 'development',
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.s[ac]ss$/,
                exclude: /node_modules/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|jpe?g|gif)$/,
                type: 'asset/resource'
            },
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            template: path.join(__dirname, "public", "index.html"),
            title: 'Title'
        }),
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
    },
}

This is my custom dev express server.js file

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const path = require('path');
const fs = require('fs');
const app = express();
const config = require("./webpack.dev.config");

const compiler = webpack(config);

//Enable "webpack-dev-middleware"
app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
    stats: {
        chunks: false,
        hash: false,
        modules: false,
        version: false,
        assets: false,
        entrypoints: false,
        builtAt: false,
    }
}));

//Enable "webpack-hot-middleware"
app.use(webpackHotMiddleware(compiler));

app.use(express.static('./public'));


// serve the routes
app.get('*', (req, res) => {
     fs.readFile(path.join(compiler.outputPath, 'index.html'), (err, file) => {
        if (err) {
            res.sendStatus(404);
        } else {
            res.send(file.toString());
        }
    });
});

app.listen(8000, () => console.log('server listening on port 8000\n'))

When I open the application and all the routes are giving 404 not found. But when I add an option of writeToDisk to compiler options then everything is normal. I want the routes to work without writing to the disk. Any help is appreciated. Thanks in advance !!

This is my folder Structure

Folder Structure

1 Answers

A solution to this problem was posted on the Github issue page here.

In order to use webpack-middleware to serve files from memory, without writing them to disk, while also being able to refer to the files explicitely (e.g. in res.render), the proposed solution is to add webpackMiddleware twice, before and after historyApiFallback, like so:

var webpackMiddleware = require("webpack-dev-middleware");
var historyApiFallback = require("connect-history-api-fallback");
var instance = webpackMiddleware(...);
app.use(instance);
app.use(historyApiFallback());
app.use(instance);
Related