Express客户端的热重装(React + Webpack)

时间:2020-06-07 19:08:52

标签: javascript reactjs express webpack

我有一个React + Webpack + Express设置。 Webpack捆绑了React文件,并将其存储在/dist目录中。在开发模式下,Webpack在监视模式下在后台运行。新更改将在dist目录中更新。 Express服务器与Webpack进程分开运行。 Express服务器根据请求localhost:3000/向客户端发送dist/index.html文件。

我想每次Webpack观察器完成React文件的编译时都启用页面重新加载(前端)。到目前为止,我所看到的是,人们在发生某些变化时立即通过Webpack重新加载Express服务器,但这并没有更新客户端。

当Webpack重新捆绑前端代码时,是否有办法(通过Express?)热重载客户端?

webpack.config.js

const path = require('path');
const Dotenv = require('dotenv-webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    devtool: 'source-map',
    entry: {
        main: './src/index.js',
        vendor: ['semantic-ui-react'],
    },
    output:{
        path: path.join(__dirname, '/dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.scss$/i,
                use: [{
                    loader: "style-loader"
                }, {
                    loader: "css-loader", options: {
                        sourceMap: true
                    }
                }, {
                    loader: "sass-loader", options: {
                        sourceMap: true
                    }
                }]
            },
            {
                test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 100000,
                    },
                },
            },
            {
                test: /\.css$/,
                include: /node_modules/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            // you can specify a publicPath here
                            // by default it uses publicPath in webpackOptions.output
                            publicPath: '../',
                            hmr: process.env.NODE_ENV === 'development',
                        },
                    },
                    'css-loader',
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new Dotenv(),
        new MiniCssExtractPlugin('styles.css')
    ]
};

server.js

const express = require('express');
const axios = require('axios');
const app = express();
const port = 3000;

app.set('view engine', 'ejs');
app.use(express.static('dist'));

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/dist/index.html');
});

app.listen(port, () => console.log('App listening on port 3000!'));

1 个答案:

答案 0 :(得分:0)

这种方式的开发在几种方面都不理想:

1。)您当前开发的方式仅考虑用于生产(这是一种老式的(2015)方法,由于编译时间可能非常长,因此已经主要弃用了)会随着应用程序的增长而消耗大量资源,并且需要手动重启进程)。尽管可以使用nodemon(在保存更改后重新启动该过程),但它会中断HMR。因此,一种更好的方法是使用webpack-dev-server创建一个仅开发的服务器,该服务器不需要Express即可提供已编译资产。相反,这将对保存创建更快的增量更新,然后在HMR事件后将其保留。当应用程序准备好投入生产时,您才可以构建整个应用程序(使用webpack),然后将这些生产资产用于快速服务。

2。)您的整个应用程序代码似乎都捆绑在一个大的JS + CSS文件中。意思是,如果您的应用程序具有多个路由,那么无论用户使用哪个路由,都必须下载整个应用程序。这在整体性能上是非常有害的,并且不必要地浪费带宽。理想情况下,您需要一个PWA(渐进式Web应用程序),该程序将代码分成多个块,并且仅在需要/请求时才下载。唯一的例外是,如果您正在使用Webpack构建UI库,但情况似乎并非如此。

3。)使用devtool: 'source-map'占用大量资源,编译时间更长,并且主要已被'cheap-module-source-map'取代(以加快重新编译的速度)。这不是一个完美的替代品,但是非常接近。

您可以查看已经包含开发服务器设置的react-starter-kit(特别是config directorywebpack.config.js file),而不是一英里长的Webpack配置和注释。与笔记。绝对不需要使用此样板,但它应该提供一个思路,让您知道如何重构Webpack配置以使其更灵活地进行开发。