webpack5热更新失效问题排查与修复全记录

背景

公司里有个项目,在开发环境中修改代码后,页面并没有自动刷新或更新,需要手动刷新浏览器才能看到效果。这严重影响了开发效率。经过初步排查,发现热更新功能完全失效,且控制台没有明显的错误信息。

排查过程

检查配置项

首先想到的就是确认 webpack 配置和webpack-dev-server 的运行命令:

js 复制代码
// webpack.config.js
devServer: {
  contentBase: resolve(__dirname, './dist'),
  historyApiFallback: true,
  https: true,
  hot: true,
  port: 3001,
  host: 'xx.com',
  proxy: {
    '/api': {
      target: 'http://xx.com',
      changeOrigin: true
    }
  }
},
json 复制代码
"dev": "webpack serve --progress --hot-only --inline --mode=development"

可以看到配置中确实启用了 hot: true,理论上热更新应该正常工作。

观察日志、终端、网络面板

既然配置项看起来没问题,那么问题有可能出现在运行时。Webpack Dev Server (WDS) 在运行时会在控制台打印多种信息,主要用于反馈开发服务器的状态、热更新进度以及错误提示等。

观察控制台:

实际上,如果热更新功能启用,这里还应该打印 [WDS] Hot Module Replacement enabled.,笔者当时忽略了这一点。

发现客户端有在等待 Webpack Dev Server 发送热更新信号。 此时改动代码,发现终端中打印了

代码改动编译成功了,但是浏览器控制台没有打印出热更新的日志,不难猜测,是客户端与 Webpack Dev Server 的通信出现了问题。

这两者之间是通过 websocket 来通信的,笔者为了求证,找了一个热更新正常的项目对照,发现其在项目启动时建立了 websocket 连接,而这个热更新失效的项目没有该连接。

问题根因探究

笔者排查到这里的时候阻塞了,因为所掌握的知识里想不到什么可以导致无法发起 websocket 请求的。所幸找到了遇到相同问题的记录,得到了一些灵感: zhuanlan.zhihu.com/p/282905500

browserslist 冲突导致热更新失效,解决方案同样可通过版本降级,或者是 target: process.env.NODE_ENV === "development" ? "web" : "browserslist", 来在开发阶段使得 browserslist 失效

browserslist 是一个用于定义目标浏览器范围的工具,它的作用是导工具生成兼容性代码,比如:

  • Babel:根据目标浏览器范围,决定是否需要将现代 JavaScript 语法(如箭头函数、async/await)转换为 ES5 语法。
  • Autoprefixer:根据目标浏览器范围,自动为 CSS 添加浏览器前缀(如 -webkit-、-moz-)。
  • PostCSS:根据目标浏览器范围,优化 CSS 代码,移除不必要的特性或添加兼容性处理。
  • webpack:根据目标浏览器范围,决定是否需要引入 polyfill 或调整代码生成策略。

当我们把 browserslist 删除后,热更新就恢复了正常。但这是为什么呢?

这里还提到了一个 webpack 配置项:target,它的作用是指示 webpack 为特定环境生成运行时代码。文档中提到其默认值为 'web',但 如果 browserslist config 可用,则默认 ,检查我们的项目发现 package.json 中确有此配置:

这个地方 deepseekgpt 都说是因为 browserslist 配置包含了不支持 websocket 的浏览器版本导致编译出的运行时代码移除了 websocket,把笔者坑惨了,在歧途中探索了半天。后面发现他们的回答反复横跳闪烁其词,才意识到不对劲。

于是乎笔者打开了 Google ,搜到了github.com/webpack/web...

这个 Issue 中提到,即使把 browserslist 的配置改为仅包含 Chrome >= 72,问题也是仍然存在的。笔者自己试了一下,确实如此。

github.com/webpack/web... 中提到该bug已在webpack-dev-server 的 v4 版本中修复,但我们的项目中还用的是 v3 版本,所以问题仍然存在。

解决方案

  1. 将 webpack 的 target 显式地配置为 web,或者动态设置 target: process.env.NODE_ENV === 'development' ? 'web' : 'browserslist',
  2. 更新 webpack-dev-server 版本(笔者未尝试,应该有效)。

反思

对于开源项目的问题可以第一时间检索有无相关的 Issue,自己摸索虽然有思考和探索的快乐,但效率太低;不要过分相信 AI 的结论,即使是如日中天的 deepseek。

相关推荐
SomeB1oody7 分钟前
【Rust自学】20.2. 最后的项目:多线程Web服务器
服务器·开发语言·前端·后端·设计模式·rust
垚垚 Securify 前沿站11 分钟前
深入剖析 CSRF 漏洞:原理、危害案例与防护
前端·网络·安全·web安全·网络安全·xss·csrf
TurtleOrange1 小时前
VSCode编辑前端快速开发模板
前端
陪你去流浪_2 小时前
Vue el-input密码输入框 按住显示密码,松开显示*;阻止浏览器密码回填,自写密码输入框;校验输入非汉字内容;文本框聚焦到内容末尾;
前端·javascript·vue.js
星糖曙光2 小时前
基于HTML生成网页有什么优势
前端·经验分享·笔记·html·ai编程
计算机-秋大田2 小时前
云上考场微信小程序的设计与实现(LW+源码+讲解)
java·前端·spring boot·微信小程序·小程序·课程设计
大厂在职_Xbg2 小时前
Dagger2进阶学习
前端·python·学习
m0_748246612 小时前
2024最新版Node.js详细安装教程(含npm配置淘宝最新镜像地址)
前端·npm·node.js
哟哟耶耶3 小时前
npm-npm ERR! missing script: serve
前端·npm·node.js
萌萌哒草头将军3 小时前
2025年了,令人唏嘘的Angular,现在怎么样了🚀🚀🚀
前端·javascript·vue.js