webpack文件监听机制的常见误解

488 阅读4分钟

最近由于工作需要,恶补了一波webpack使用,基本回顾方法是学习视频 + 博客 + 官方文档,发现网上关于webpack的用法介绍其实更新不多,我很多搜到的内容都是2018-2019年的,而且误区也不少。

本着求真的原则,看了很多博客都无法合理的解答我的问题,就去看了官方文档(尽管官方文档正规,不过很多概念比较抽象难懂,看博客更容易理解)

后续的计划是逐个回顾webpack几个常用功能和配置,并且分享使用过程中踩到的坑

今天即将分享的“坑”就是webpack的文件监听机制,如何使用以及常见的“误区”

什么是文件监听机制?简单的说就是如果项目的源码发生变化,webpack就会自动构建,这样就不需要开发人员频繁的输入npm run build去重新打包。

如何实现webpack的文件监听?主要有两种方法,一种是在启动webpack命令时添加--watch参数,第二种方法就比较高级一点,在webpack的配置文件中添加watch选项

module.exports = {
    watch: true,
    // 只有当watch为true时watchOptions才会生效
    watchOptions: {
        // 文件监听忽略的文件(不监听依赖文件可以大大减少对CPU或内存的占用)
        // value采用正则表达式表示
        ignored: /node_modules/,
        // webpack监听到源码改变后触发构建的延时时间
        aggregateTimeout: 300,
        // webpack每次轮询的间隔时间,单位是ms(1000表示每1000毫秒轮询一次)
        poll: 1000
    }
}

下面着重强调一下遇到的“坑”

第一坑,也是我搜了很多博客发现都有的误区 poll指的是每次轮询间隔的时间,而不是每秒轮询多少次,注意 不是 “每秒轮询多少次”,无数个博客都解释poll:1000代表每秒轮询1000次,经过官网认证是错误的,大家一定要记住,poll指的是每次轮询间隔的时间

第二坑,和webpack的文件监听原理有关系,正好具体讲一下webpack是怎么实现文件监听的:其实方法很简单暴力,采用轮询的方式,每隔一段时间去判断每个文件的最后修改时间是否发生变化,如果发生变化,就先缓存起来,等待延时时间结束,期间如果遇到别的文件更改都统一缓存,然后一起重新打包。如果熟悉vue或者react的同学应该都知道虚拟dom,其实这种缓存后整体更新的思路和虚拟dom经过每轮tick后更新到真实dom很相似,都可以增加文件监听的效率,减少cpu或者内存占用

既然原理说了一大堆,接下来就要说到第二个隐藏得很深的“坑”了——aggregate表示监听者延时多长时间后再去更新,有些博主或者网课会形容成“文件发生更改后延时一段时间再告诉监听者”,但这种描述很有问题,我之前看到这部分就有很大的疑问,因为最后的延时执行明明是监听者做的,如果在监听者收到更改反馈之前文件本身又延时了一段时间,那不就成了两倍的aggregateTimeout么?所以最后还是在官网找到了答案,也希望在这里分享出来,避免大家继续踩坑。

判断文件更改和延时更新的操作主体都是监听者,也可以理解为webpack,文件本身只是更新了自己的最后修改时间,然后静静等待监听者的轮训罢了

希望以上分享的两个”踩坑“知识点对大家可以有所帮助

采用上述两种开启webpack文件监听的方法其实都有一个缺点,那就是浏览器不会自动刷新,尽管项目会自动构建,但还是需要开发人员手动刷新浏览器才能看到新的页面效果,本着高效开发的原则,下一节会分享webpack热更新插件的使用:webpack-dev-server(WDS) + HotModuleReplacementPlugin插件