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。

相关推荐
孟陬5 分钟前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
BER_c5 分钟前
前端权限校验最佳实践:一个健壮的柯里化工具函数
前端·javascript
兆子龙9 分钟前
别再用 useState / data 管 Tabs 的 activeKey 了:和 URL 绑定才香
前端·架构
sudo_jin9 分钟前
前端包管理器演进史:为什么 npm 之后,Yarn 和 pnpm 成了新宠?
前端·npm
敲敲敲敲暴你脑袋38 分钟前
写个添加注释的vscode插件
javascript·typescript·visual studio code
叁两1 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
golang学习记1 小时前
GitLens 十大神技:彻底改变你在 VS Code 中的 Git 工作流
前端·后端·visual studio code
SuperEugene1 小时前
后台权限与菜单渲染:基于路由和后端返回的几种实现方式
前端·javascript·vue.js
兆子龙1 小时前
WebSocket 入门:是什么、有什么用、脚本能帮你做什么
前端·架构
csdn飘逸飘逸1 小时前
Autojs基础-全局函数与变量(globals)
javascript