Webpack缓存没生效,页面还是重新加载了?
我用 Webpack 搭了个 React 项目,明明配置了 cache 缓存,但每次改点代码,整个页面都重新加载,连组件状态都没保住,是不是哪里配错了?
我试过在 webpack.config.js 里加 cache: { type: ‘filesystem’ },也确认 devServer 用了 hot: true,但还是不行。下面是入口组件的写法:
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
export default App;
改完 CSS 或其他模块,这个 count 状态就丢了,感觉根本没走 HMR,缓存好像也没起作用,到底该怎么配才对?
cache: { type: 'filesystem' }其实是为了提升 Webpack 打包构建速度的,比如你第二次启动项目时能快几秒,但它跟你在浏览器里改代码能不能保留状态是两码事。你遇到的“状态丢了”,本质上是浏览器发生了整页刷新,而不是 React 的热更新。React 组件要想在代码改动后还能保持住那个 count 的值,必须得用 React Fast Refresh 机制,光靠 Webpack 原生的
hot: true是不够的,它只是个基础设施,不知道怎么安全地更新 React 组件。咱们得加个插件来解决这个问题,按下面这几步来就行。
第一步,安装依赖
你需要装
react-refresh-webpack-plugin。在项目目录下运行:npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
第二步,修改 webpack.config.js
把插件引入并注册到 plugins 数组里。注意,这个插件最好只在开发环境用。
第三步,配置 Babel Loader
这是最关键的一步,很多人漏了这就导致没效果。你需要告诉 Babel 在编译 React 代码时注入热更新的逻辑。在你的 module.rules 里找到处理 js/jsx 的 loader,加上 reactRefresh 的选项。
原理是这样:当你修改代码时,Webpack 监听到变化,通过
react-refresh-webpack-plugin把新的代码发到浏览器。这个插件配合 Babel 注入的逻辑,会尝试在保持组件实例的情况下更新代码。如果更新逻辑安全,状态就保留;如果不安全(比如你改了组件内部结构或者 hooks 顺序),它才会自动刷新页面。配置完这几步,重启一下
npm start,再去改改 CSS 或者 React 组件里的文字,你会发现那个 count 还是稳稳地停在那儿,不会归零了。至于你之前配的cache: { type: 'filesystem' },留着也没事,反正它只是帮你加快构建速度,不影响这个。