热更新不生效有很多种可能的原因,在这篇文档中会介绍大部分常见的原因,你可以参照以下内容进行排查。
在开始排查之前,请简单了解一下热更新的原理:
hot-update.(js|json)
请求,从而加载编译后的新模块。了解完热更新的原理后,你可以按照以下步骤来进行基本的排查:
打开浏览器的控制台,查看是否有 [HMR] connected.
日志。
ws://[host]:[port]/rsbuild-hmr
的请求状态,若请求异常,说明热更新失败的原因是 Web Socket 请求没有建立成功。Web Socket 请求没有建立成功的原因可能有很多种,例如开启了网络代理,导致 Web Socket 请求没有正确发送到开发服务器。你可以检查 Web Socket 请求的地址是否为你的开发服务器地址,如果不是,则可以通过 dev.client 来配置 Web Socket 请求的地址。
当你修改一个模块的代码,并触发重新编译后,浏览器会向开发服务器发送若干个 hot-update.json
和 hot-update.js
请求,用于获取更新后的代码。
你可以尝试修改一个模块并检查 hot-update.(js|json)
请求的内容,如果请求的内容是最新的代码,说明热更新的请求正常。
如果请求的内容错误,大概率也是由于开启了网络代理,请检查 hot-update.(js|json)
请求的地址是否为你的开发服务器地址,如果不是,则需要调整代理规则,将 hot-update.(js|json)
请求代理到开发服务器地址。
如果以上两个步骤都没有问题,那么可能是其他原因导致的热更新失败,比如没有符合 React 对热更新的要求,你可以参考下列的问题进行排查。
为了保证热更新生效,我们需要使用 React 和 ReactDOM 的开发模式产物。
当你将 React 通过 externals 排除后,通常会通过 CDN 等方式注入 React 的生产模式产物,所以热更新会不生效。
为了解决该问题,你需要引用 React 的开发模式产物,同时安装 React DevTools,安装完成后即可实现热更新。
如果你不确定当前使用的 React 产物类型,可以参考:React 官方文档 - Use the Production Build。
通常来说,我们只会在生产模式下设置文件名的 hash 值(即 process.env.NODE_ENV === 'production'
时)。
如果你在开发模式下设置了文件名的 hash,那么可能会导致热更新不生效(尤其是 CSS 文件)。这是因为每次文件内容变化时,都会引起 hash 变化,导致 mini-css-extract-plugin 等工具无法读取到最新的文件内容。
当开启 https 时,由于证书的问题,可能会出现 HMR 连接失败的情况,此时打开控制台,会出现 HMR connect failed 的报错。
此问题的解决方法为:点击 Chrome 浏览器问题页面的「高级」->「继续前往 some page(不安全)」。
Tips: 当通过 Localhost 访问页面时,「您的连接不是私密连接」字样可能不会出现,可访问 Network 域名进行处理。