0%

使用chokidar监视文件更新

监视文件

使用chokidar,可以监视指定路径下目录、文件的变动。由于我只关注更改,因此监视change事件即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
'use strict';

const fs = require('fs');
const path = require('path');

const chokidar = require('chokidar');

module.exports = watchChange;

/**
* 监听目录或文件变动
* @param {string|array} paths 目录或文件路径
* @param {function} onChange 回调函数
* @return {Promise.<*>}
*/
function watchChange(paths, onChange) {
if (typeof onChange !== 'function') throw Error(`onChange (${onChange}) is not a function`);

if (!Array.isArray(paths)) paths = [paths];

paths.forEach(path => {
if (!(path && fs.existsSync(path))) throw Error(`can't find path ${path}`);
});

chokidar.watch(paths)
// .on('add', filepath => {console.log('you can watch more events by chains')})
.on('change', filepath => {
const filename = path.basename(filepath);
onChange(filename);
});
}

更新缓存

为了避免每次取内容都读文件,使用了lodash.memoize缓存读取结果。

1
2
3
4
5
async function readFile(params) {
return;
}

const getFile = _.memoize(readFile);

要更新这部分缓存,可以使用如下方法。用大文件测试了内存占用,没有泄露产生。

1
getFile.cache.set(file, readFile(file));

完整部分,加上了try catch。

1
2
3
4
5
6
7
8
9
10
11
function watchTpl() {
try {
watchFiles('./test', file => {
getFile.cache.set(file, readFile(file));
});
} catch (err) {
console.error(err);
}
}

watchTpl();

小结

由于使用场景明确,代码实现较简单,没有考虑太多情况,也算不上热更新。但借这种思路,可以完成配置文件甚至功能模块的更新。

References

Node监视文件以实现热更新
Node.js Web应用代码热更新的另类思路