9

文件监听

文件监听是在发现源码发生变化时,自动重新构建出新的输出文件。

webpack官方提供了两大模块,一个是核心的webpack,一个是webpack-dev-server扩展模块。而文件监听功能是webpack模块提供的。

之前介绍过webpack支持文件监听相关的配置项如下:

module.export = {
    //只有开启监听模式时,watchOptions才有意义
    //默认false,也就是不开启
    watch: true,
    wathcOptions: {
        //不监听的文件或者文件夹,支持正则匹配
        //默认为空
        ignored: /node_modules/,
        //监听到变化发生后会等300ms再去执行动作,防止文件更新太快
        //默认为300ms
        aggregateTimeout: 300,
        //判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的
        //默认每秒问1000次
        poll: 1000
    }
}

要让webpack开启监听模式,有两种方式:

在配置webpack.config.js中设置watch: true
在执行启动webpack命令时,带上 --watch 参数, 完整命令时webpack --watch

文件监听工作原理

在webpack中监听一个文件发生变化的原理是定时的去获取这个文件的最后编辑时间,每次都存下最新的最后编辑时间,如果发现当前获取的和最后一次保存的最后编辑时间不一致,就认为该文件发生了变化。配置项中的watchOptions.poll就是用于控制定时检查的周期,具体含义是检查多少次。

当发现某个文件发生了变化,并不会立刻告诉监听者,而是先换成起来,收集一段时间的变化后,再一次性告诉监听者,配置项中的watchOptions.aggregateTimeout就是用于配置这个等待时间。这样做的目的是因为我们在编辑代码的过程中可能会高频的输入文字导致文件变化的事件高频的发生,如果每次都重新执行构建就会让构建卡死。

优化文件监听性能

开启监听模式事,默认情况下会监听配置的Entry文件和所有其递归依赖的文件。在这些文件中会有很多存在node_modules下,因为如今的web项目会依赖大量的第三方模块。在大多数情况下我们都不可能去编辑node_modules下的文件,而是编辑自己建立的源码文件。所以很大的优化点就是忽略node_modules下的文件,不监听他们:

module.export = {
    watchOptions: {
        //不监听的node_modules目录下的文件,
        ignored: /node_modules/
    }
}

采用这种方法优化后,你的webpack消耗的内存和cpu将会大大降低。

有时你可能会觉得 node_modules 目录下的第三方模块有 bug,想修改第三方模块的文件,然后在自己的项目中试试。 在这种情况下如果使用了以上优化方法,我们需要重启构建以看到最新效果。 但这种情况毕竟是非常少见的。

除了忽略掉部分文件的优化外, 还有其他如下两种方法:

watchOptions.aggregateTimeout 值越大性能越好,因为这能降低重新构建的频率。
watchOptions.poll 值越小越好,因为这能降低检查的频率。

自动刷新浏览器

监听到文件更新后的下一步是去刷新浏览器,webpack 模块负责监听文件,webpack-dev-server 模块则负责刷新浏览器。 在使用 webpack-dev-server 模块去启动 webpack 模块时,webpack 模块的监听模式默认会被开启。 webpack 模块会在文件发生变化时告诉 webpack-dev-server 模块。

自动刷新的原理

控制浏览器刷新有三种方法:

1. 借助浏览器扩展去通过浏览器提供的接口刷新,WebStorm IDE 的 LiveEdit 功能就是这样实现的.
2. 往要开发的网页中注入代理客户端代码,通过代理客户端去刷新整个页面。
3. 把要开发的网页装进一个 iframe 中,通过刷新 iframe 去看到最新效果。

DevServer 支持第2、3种方法,第2种是 DevServer 默认采用的刷新方法。

优化自动刷新的性能

devServer: inline配置项,它就是用来控制是否往Chunk中注入代理客户端,默认会注入。事实上,在开启inline时,devServer会为每个输出的chunk中注入代理客户端的代码,当你的项目需要输出的chunk有很多时,这会导致你的构建缓慢。其实要完成自动刷新,一个页面只需要一个代理客户端就行。DevServer之所以粗暴的为每个chunk都注入,是因为它不知道某哥网页依赖哪几个chunk,索性就全部都注入一个代理客户端。网页只要依赖了其中任何一个chunk,代理客户端就被注入到网页中去。

这里优化的思路是关闭还不够优雅的 inline 模式,只注入一个代理客户端。 为了关闭 inline 模式,在启动 DevServer 时,可通过执行命令 webpack-dev-server --inline false(也可以在配置文件中设置)


fsrookie
2.9k 声望256 粉丝

目前很多文章都是摘抄记录其他教程。见谅。