3

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

5
  • Where is your index.html coming from? It looks like you rely on Webpack to produce or copy it to the public folder? If so, then you definitely need writeToDisk. Make sure it exists, if you try to read it from disk (which is what you are doing in fs.readFile(path.join(compiler.outputPath, 'index.html')) Commented May 18, 2021 at 9:52
  • Yes, I'm have index.html file in public folder and I'm using it as a template to Htmlwebapckplugin. But the plugin creates a new index.html file right ? That's what is there in documentation. Is there any way to place it somewhere or what config should I use so that I don't need to write it to disk. Commented May 18, 2021 at 14:24
  • 1
    The solution seems to be here: github.com/webpack/webpack-dev-middleware/issues/… Commented May 18, 2021 at 16:02
  • Alternatively, the official documentation suggests using outputFileSystem.readFile*: github.com/webpack/webpack-dev-middleware#server-side-rendering Commented May 18, 2021 at 16:05
  • 1
    @Domi Thanks a lot the app.use(instance) twice worked for me and can you tell me is my config work well with redux as well for development. Commented May 19, 2021 at 15:06

1 Answer 1

3

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);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.