代码变更时自动构建并启用热重载的实现方案咨询
实现React + Express开发环境热重载的两种方案
方案一:基于现有配置的轻量改造(Webpack Watch + Nodemon)
你之前的watch脚本失效是因为监听目标搞反了——应该监听**源码目录(比如src)**的变化来触发构建,而不是监听dist。用Webpack自带的--watch参数就能自动监听源码变更并重新构建,再配合Nodemon监听dist的变化重启服务器,就能实现自动刷新。
步骤:
- 安装Nodemon(开发依赖):
npm i -D nodemon
- 修改
package.json的scripts:
"scripts": { "build": "webpack --mode=development --out-dir dist", "build:watch": "webpack --mode=development --out-dir dist --watch", "server": "node server.js", "server:watch": "nodemon --watch dist server.js", "dev": "npm run build:watch & npm run server:watch" }
注意:Windows系统不支持
&并行运行脚本,需要先安装concurrently:npm i -D concurrently,然后把dev脚本改成:"dev": "concurrently \"npm run build:watch\" \"npm run server:watch\""
- 运行
npm run dev,之后修改源码会自动触发构建,Nodemon会在dist更新后重启服务器,刷新页面就能看到变更。
方案二:Webpack Dev Middleware + HMR(更高效的热重载)
上面的方案需要每次构建后重启服务器,而且页面会全量刷新。用Webpack Dev Middleware可以把构建产物放在内存中,配合React的热模块替换(HMR),能实现组件级的热重载,不用刷新整个页面,开发体验更好。
步骤:
- 安装依赖:
npm i -D webpack-dev-middleware webpack-hot-middleware react-refresh @pmmmwh/react-refresh-webpack-plugin
- 修改
webpack.config.js,配置HMR:
const path = require('path'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const webpack = require('webpack'); module.exports = { mode: 'development', entry: [ 'webpack-hot-middleware/client?reload=true', // HMR客户端,构建失败时自动刷新页面 './src/index.js' // 你的React入口文件路径 ], output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), publicPath: '/' }, plugins: [ new webpack.HotModuleReplacementPlugin(), new ReactRefreshWebpackPlugin() ], module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-react'], // 确保你已安装babel-react预设 plugins: [require.resolve('react-refresh/babel')] } } ] }, // 按需添加css、图片等资源的loader配置 ] }, devtool: 'cheap-module-source-map' };
- 修改
server.js,集成Webpack中间件:
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 config = require('./webpack.config.js'); const app = express(); const compiler = webpack(config); // 启用webpack-dev-middleware,将构建产物存放在内存中 app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath })); // 启用HMR中间件,实现热重载 app.use(webpackHotMiddleware(compiler)); // 处理静态资源(如果有额外的静态文件) app.use(express.static('public')); // 所有请求返回内存中的index.html app.get('*', (req, res) => { const htmlPath = path.resolve(__dirname, 'dist/index.html'); // 从webpack的内存文件系统中读取index.html const html = compiler.outputFileSystem.readFileSync(htmlPath, 'utf8'); res.send(html); }); const PORT = 3000; app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); });
- 修改
package.json的scripts:
"scripts": { "dev": "node server.js" }
- 运行
npm run dev,修改React组件时,页面会自动更新组件,无需全量刷新。
内容的提问来源于stack exchange,提问作者Pratik Wadekar
相关产品推荐
相关产品推荐

