如何在Node.js的fs.watch()中使用通配符监听文件变化?
关于Node.js fs.watch() 通配符与递归监听的问题
首先直接给结论:Node.js 原生的 fs.watch() 本身并不支持通配符(比如 src/**/*.* 这种写法),也不会默认递归监听子目录——这就是你一开始用通配符调用时出错的原因。
如果你坚持要只用原生 fs.watch() 实现需求,需要自己手动编写递归遍历和动态监听的逻辑,具体可以这么做:
- 第一步:递归遍历
src目录下的所有子目录,为每个目录单独创建fs.watch实例 - 第二步:监听目录的变化事件,当有新的子目录被创建时,自动为新目录添加监听(否则新增的子目录里的文件变化不会被捕获)
- 第三步:如果需要过滤特定文件类型(对应通配符的作用),可以在文件变化事件里手动判断文件名是否符合规则
这里给你一个简单的实现示例:
const fs = require('fs'); const path = require('path'); // 递归监听目录及子目录 function watchDirectory(dir) { // 监听当前目录 fs.watch(dir, (eventType, filename) => { if (!filename) return; const fullPath = path.join(dir, filename); // 判断是否是新创建的目录,如果是则递归监听 fs.stat(fullPath, (err, stats) => { if (!err && stats.isDirectory()) { watchDirectory(fullPath); } // 这里可以添加文件类型过滤逻辑,比如只处理.css/.js等文件 if (stats?.isFile() && /\.(css|js|html)$/.test(filename)) { console.log(`文件变化: ${fullPath}`); // 这里执行你的处理逻辑 } }); }); // 初始遍历子目录,添加监听 fs.readdir(dir, (err, files) => { if (err) throw err; files.forEach(file => { const fullPath = path.join(dir, file); fs.stat(fullPath, (err, stats) => { if (!err && stats.isDirectory()) { watchDirectory(fullPath); } }); }); }); } // 启动监听 watchDirectory('./src');
不过要注意,原生 fs.watch() 有不少跨平台的兼容性问题(比如不同系统触发的 eventType 不一致、有时会重复触发事件),而且自己实现的逻辑需要处理很多边缘情况(比如文件重命名、临时文件生成等)。
而你已经在用的 gaze 或者类似的 chokidar,它们已经封装好了这些复杂逻辑,不仅支持通配符、递归监听,还能处理各种异常情况,跨平台表现更一致——如果不是必须用原生API,这类第三方工具其实是更省心的选择。
内容的提问来源于stack exchange,提问作者Ole
相关产品推荐
相关产品推荐

