Browser Sync+webpack-dev-server异常:点击滚动失效及WebSocket连接失败排查
嘿,我之前也踩过类似的坑!你遇到的WebSocket握手失败,加上点击、滚动这类交互同步失效,核心原因是webpack-dev-server和Browser Sync的WebSocket服务冲突了——俩工具都想通过WebSocket实现页面同步/热重载,结果互相干扰,导致Browser Sync的同步功能罢工;而表单填写正常是因为那是本地DOM操作,不需要依赖WebSocket。
下面是一步步的排查和解决方法:
1. 给webpack-dev-server“降权”,关掉它的WebSocket和热重载
webpack-dev-server自带的热重载(HMR)和WebSocket服务会和Browser Sync抢资源,我们让它只负责编译和提供静态文件就好。在你的webpack.dev.js里修改devServer配置:
module.exports = { // ... 你的其他webpack配置 devServer: { hot: false, // 彻底关闭webpack的热模块替换 liveReload: false, // 关掉自动刷新,交给Browser Sync处理 client: { webSocketURL: 'ws://0.0.0.0:0/ws', // 禁用webpack的WebSocket客户端 overlay: false, // 可选:关掉编译错误的页面浮层,避免和Browser Sync冲突 }, port: 8080, // 给webpack指定一个固定端口,比如8080 static: { directory: path.join(__dirname, 'dist'), // 指向你的编译输出目录 }, }, };
2. 让Browser Sync代理webpack的服务
这是关键!Browser Sync应该作为前端入口,代理webpack-dev-server提供的静态资源,而不是直接监听文件。你可以这么配置:
方法一:用单独的Browser Sync配置文件(比如bs-config.js)
module.exports = { proxy: 'localhost:8080', // 代理到webpack-dev-server的地址 files: [ 'src/**/*.js', 'src/**/*.css', 'src/**/*.html' ], // 监听源码文件变化,触发Browser Sync刷新 open: true, // 自动打开浏览器 notify: false, // 可选:关掉右上角的通知提示,更清爽 port: 3000, // 给Browser Sync指定另一个端口,和webpack不重复 };
方法二:直接在package.json的scripts里配置
"scripts": { "dev": "webpack serve --config webpack.dev.js & browser-sync start --proxy 'localhost:8080' --files 'src/**/*' --port 3000" }
这样启动时,webpack会先编译并在8080提供服务,Browser Sync在3000代理它,所有页面请求都走3000端口,避免冲突。
3. 检查端口占用情况
你错误里提到的4000端口(sockjs-node用的)可能被其他进程占用了,或者你不小心让两个工具用了同一个端口。可以用下面的命令排查:
- Mac/Linux:
lsof -i :4000,找到占用进程后用kill -9 <PID>杀掉 - Windows:打开命令提示符,输入
netstat -ano | findstr :4000,找到PID后在任务管理器里结束对应进程
4. 极端情况:禁用webpack-dev-server的客户端注入
如果上面的方法还不行,直接关掉webpack-dev-server的客户端注入,让它完全只做静态服务:
devServer: { client: false, // 彻底禁用webpack的客户端脚本注入 // ... 其他配置 }
这样调整后,Browser Sync的WebSocket就能正常工作,点击、滚动的同步功能也会恢复,同时webpack负责编译的工作也不受影响。
内容的提问来源于stack exchange,提问作者Chintan Sukhadiya

