WSL2/Ubuntu22.04下Parcel/Webpack5的HMR热更新不生效问题
问题原因
两个核心问题共同导致该异常:
- 项目配置存在逻辑错误
你的package.json有两处明显问题:一是source字段写为.src/index.html,多余的前缀点会让Parcel错误查找名为.src的隐藏目录作为源码根目录;二是dev脚本使用&&连接parcel ./src/index.html和parcel watch ./src/index.html两个命令,&&仅在前序命令执行退出后才会运行后续命令,而Parcel启动开发服务器是常驻进程,后续的watch命令永远不会触发,还可能引发缓存锁、端口占用冲突。Windows环境下路径解析容错逻辑会绕过部分配置问题,WSL环境路径校验更严格,问题就会暴露。 - WSL2跨文件系统机制限制
如果你把项目存放在Windows挂载盘(即/mnt/c/、/mnt/d/这类9P协议挂载的NTFS路径)下,WSL2默认不会将Windows侧的文件修改事件传递给Linux内的inotify监听接口,Parcel的HMR、自动重编译完全依赖inotify捕获文件变更,自然无法触发更新。同时跨文件系统访问的IO性能损耗极大,就是你体感WSL运行速度远慢于Windows原生环境的核心原因。
另外如果你在WSL环境下直接复用Windows侧安装的node_modules目录,会出现平台原生二进制依赖不兼容的问题,也会导致Parcel运行异常、缓存读取错误,哪怕重启服务也无法加载最新修改的内容。
解决步骤
按顺序操作即可修复:
- 修正项目配置
打开package.json做两处修改:- 将
source字段的值从.src/index.html改为./src/index.html - 将
scripts下的dev命令简化为parcel ./src/index.html,Parcel默认启动开发服务时已自带文件监听、HMR能力,不需要额外叠加watch命令。
修改完成后,在WSL终端内进入项目根目录,删除node_modules、dist、.parcel-cache三个目录,重新执行npm install安装全量依赖,禁止直接复用Windows环境下安装的依赖文件。
- 将
- 将项目迁移到WSL原生文件系统
把项目从/mnt/开头的挂载盘路径,移动到WSL自身的Ext4文件系统路径下,比如~/projects/your-project-name。该操作可以同时解决文件监听事件不触发、运行速度慢两个问题,WSL访问原生文件系统的性能比访问跨系统挂载盘高3~10倍,inotify事件也可以正常上报。迁移完成后重新安装依赖、启动开发服务即可。 - 特殊场景下开启挂载盘文件事件转发
如果因特殊需求必须将项目存放在Windows挂载盘下,按以下步骤修改WSL配置开启跨系统事件传递:- 关闭所有WSL终端,在Windows PowerShell中执行
wsl --shutdown完全终止WSL实例 - 进入对应WSL发行版的
/etc目录,编辑wsl.conf文件,写入以下配置:
[automount] options = "metadata,umask=22,fmask=11" crossDistro = true [boot] systemd = true- 保存配置后重新启动WSL,进入项目目录重启开发服务即可。
- 关闭所有WSL终端,在Windows PowerShell中执行
- 调大inotify监听上限
如果项目文件较多,WSL默认的inotify监听数量上限会导致Parcel无法为全部文件添加变更监听,执行以下命令临时调大上限:
要永久生效的话,将上述两行配置追加到sudo sysctl fs.inotify.max_user_watches=524288 sudo sysctl fs.inotify.max_user_instances=512/etc/sysctl.conf文件末尾,执行sudo sysctl -p加载配置即可。
内容的提问来源于stack exchange,提问作者MFaiqKhan
相关产品推荐
相关产品推荐

