React路由与Express、Webpack开发中间件、React Router DOM的结合

3
我有困难在使用react-router-dom和自定义开发服务器(使用express,webpack-dev-middleware和webpack-hot-middleware)的路由方面。
这是我的webpack配置。
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',
        },
    },
}

这是我的自定义dev express server.js文件

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'))

当我打开应用程序时,所有的路由都显示404未找到。但是当我将writeToDisk选项添加到编译器选项中时,一切正常。我希望路由可以在不写入磁盘的情况下工作。非常感谢任何帮助!谢谢!
这是我的文件夹结构。

Folder Structure


你的 index.html 文件是从哪里来的?看起来你依赖Webpack生成或复制它到 public 文件夹中?如果是这样,那么你肯定需要 writeToDisk。请确保它已经存在,如果你尝试从磁盘读取它(就像你在 fs.readFile(path.join(compiler.outputPath, 'index.html') 中正在做的那样)。 - Domi
是的,我在public文件夹中有index.html文件,并将其用作Htmlwebapckplugin的模板。但是插件会创建一个新的index.html文件,对吧?文档中就是这样写的。有没有什么方法可以将它放在其他地方,或者使用哪个配置项可以使我不需要将其写入磁盘呢? - Hem
1
解决方案似乎在这里:https://github.com/webpack/webpack-dev-middleware/issues/88#issuecomment-252048006 - Domi
另外,官方文档建议使用 outputFileSystem.readFile* :https://github.com/webpack/webpack-dev-middleware#server-side-rendering - Domi
1
@Domi 非常感谢,app.use(instance) 两次对我很有帮助。你能告诉我我的配置在开发中是否适用于redux吗? - Hem
1个回答

3
这个问题的解决方案已经发布在 Github 的问题页面这里
为了使用webpack-middleware从内存中提供文件,而不将它们写入磁盘,并能够明确地引用这些文件(例如在res.render中),建议的解决方案是在historyApiFallback之前和之后分别添加webpackMiddleware,如下所示:
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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接