# 前言

我们平时在开发代码时,很多构建工具在我们保存本地代码时都可以做到实时上传或者实时刷新页面,那么大家有没有想过构建工具是如何做到的?

想做到这一点,就需要实时监听本地文件的增删改,掌握这些时机就可以做到在文件改变时热更新或者实时上传。

下面我们就来聊一聊如何监听本地文件的变动!

# 原理

其实这些构建工具都是在用一个包 chokidar,下面我们来看看如何使用它!

图1

图 1

如图 1,我们引入 chokidar 这个包,并且使用 all 事件监听当前文件夹,下面我们来操作一把!

图2

图 2

从图 2 中我们发现,对 dist 目录下的任何文件或者目录的改动都会被 all 监听到

  • 增加文件时,显示的事件名是 add,并且显示对应的文件名;
  • 修改文件内容时,显示的事件名是 change,并且显示对应的文件名;
  • 增加目录时,显示的事件名是 addDir,并且显示对应的目录名;
  • 删除文件时,显示的事件名是 unlink,并且显示对应的文件名;
  • 删除目录时,显示的事件名是 unlinkDir,并且显示对应的目录名;

all 事件是一个总的事件,在被监听的目录下的任何操作都会触发这个事件,其实我们可以更有针对性的去监听某一项操作!

图3

图 3

如图 3,如果业务中不需要监听所有的事件,我们可以把事件拆开!上图中 ready 事件是在监听程序启动完成后触发,raw 事件和 all 事件一样在每个操作后都会被触发,它主要显示更具体的文件或者目录信息。

图4

图 4

后期还可以通过 add 方法针对性的补充要监听的文件,也可以使用 unwatch 去除不想要监听的文件(不过据我测试 unwatch 没有生效)。

此模块还有一些配置选项,如下:

let watcher = chokidar.watch('.', {
        persistent: false,
        ignoreInitial: false,
        useFsEvents: false,
        usePolling: true,
        followSymlinks: false,
        awaitWriteFinish: {
        stabilityThreshold: 2000,
        pollInterval: 100
    }
});
  • persistent 默认是 true,如果设置成 false,程序就不会一直处于监听状态,运行完就结束;
  • ignoreInitial 默认是 false,如果设置成 true,程序初始化运行时就不会触发 add/addDir 事件;
  • useFsEvents 在 mac 上默认是 true,底层使用 fsevent 接口,轻量且更加高效;
  • usePolling 默认 false,底层使用 fs.watchFile 或者 fs.watch 进行轮询,此方式较慢且不太可靠,有可能占用很大的 cpu;
  • followSymlinks 默认是 true,主要是对软连接做监听,如果设为 false,那么对软连接的源文件修改将不会触发事件;
  • awaitWriteFinish 默认是 false,可以将其设置成一个对象,对象有两个属性,一个是 stabilityThreshold 表示文件操作节流的时间,如果你文件操作比较频繁,每次都触发事件会影响性能,通过节流方式只有在此时间内不存在操作才能触发事件,另外一个属性是 pollInterval,文件大小轮询间隔,它们都是以毫秒为单位。

以上的参数都是我认为比较难理解的,此处我挑出来重点介绍!

# 总结

监听文件是一个很常见的功能,获取到文件变动的事件后我们可以做很多事情,比如有的编辑器可以在文件修改保存后自动格式化,自动做语法校验等等,能力的实际应用需要我们在业务中去寻找!