目录

vue-cli开发时无法模块热重载(HMR)问题

vue-cli是vue官方出的Vue.js 开发的标准工具,参见文档vue-cli-service serve 命令会启动一个开发服务器 (基于 webpack-dev-server) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。

就是说默认带模块热重载(HMR),但不是总会起作用。

所用环境:

@vue/cli 4.1.1

vagrant

docker

devServer.host

测试环境稍复杂,为了兼容各种系统,使用的是vagrant创建虚拟机,虚拟机里面装了docker,自己构建了一个vue-cli的镜像,因为代码是这样到docker镜像中的:

开发电脑代码目录 -> vagrant 创建的虚拟机 -> docker

vagrant 创建的虚拟机分配一个固定IP,192.168.33.14vue-cli-service serve使用的端口为8080,将其映射到虚拟机的8080,在docker中启动vue-cli创建的vue项目,可以正常启动,访问:http://192.168.33.14:8080就是访问到docker镜像的8080端口。

打开控制台:

https://assets.cooldev.cn/2019-12-25_114719.png@!p

http://localhost:8080/sockjs-node/info?t=1577245576606这个链接报错,无法访问,因为它访问的是localhost而不是192.168.33.14,在项目根目录的vue.config.js修改 devServer.host

vue.config.js

1
2
3
4
5
6
7
8
module.exports = {
    // 其他配置省略...
    
    devServer: {
        host: '0.0.0.0'
        //hot: true 这个选项可以不加,默认
    }
};

重启服务,观察也可以正常访问http://192.168.33.14:8080/sockjs-node/info?t=1577246248829

https://assets.cooldev.cn/2019-12-25_115818.png@!p

说明修改生效,但是试着改一下文件依然不会自动热重载。

devServer.watchOptions🔑

按道理来说这时应该可以热更新了,但是依然不行,就要考虑到我们的环境是比较复杂的,使用了vagrant,使用了docker,开发电脑是win10系统,查阅webpack文档,找到了devServer.watchOptions

webpack uses the file system to get notified of file changes. In some cases this does not work. For example, when using Network File System (NFS). Vagrant also has a lot of problems with this. In these cases, use polling:

webpack使用文件系统来通知文件更改。在某些情况下,这不起作用。例如,使用网络文件系统(NFS)时。vagrant对此也有很多问题。在这些情况下,请使用轮询:

webpack.config.js

1
2
3
4
5
6
7
8
module.exports = {
  //...
  devServer: {
    watchOptions: {
      poll: true
    }
  }
};

更多watchOptions选项:

watchOptions.aggregateTimeout 指定一个延时,单位毫秒,可以将短时间内修改聚合到一次重建中,减少重建次数

watchOptions.ignored 指定要忽略监视的文件或文件夹

watchOptions.poll 轮询设置,可以设置为true或者指定一个轮询间隔,单位毫秒

因此我们可以修改vue.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
module.exports = {
    // 其他配置省略...
    
    devServer: {
        host: '0.0.0.0',
        //hot: true 这个选项可以不加,默认
        watchOptions: {
            //忽略监视的文件或目录
            ignored: ['node_modules'],
            // 轮询,设置为true或者毫秒(这里指定为1秒监测一次)
            poll: 1000,
            // 重建之前添加一个延时,可以将短时间内修改聚合到一次重建中,减少重建次数。单位毫秒
            aggregateTimeout: 600
        }
    }
};

重启服务,尝试修改一下文件,模块热重载(HMR)生效。

其他情况解决方法

  1. webpack文档还给出了一些其他可能导致不能热重载的原因,可以参阅 Troubleshooting
  2. vue-cli issue #2501 ,有很多人遇到了这个问题,可以看下里面讨论的解决方法。
  3. vue-cli issue #1559