Node.js предоставляет несколько способов отслеживания изменений в файловой системе, каждый со своими особенностями и проблемами.
const fs = require('fs');
fs.watch('./target.txt', (eventType, filename) => {
console.log(`Событие: ${eventType}, файл: ${filename}`);
});
fs.watchFile('./target.txt', { interval: 1000 }, (curr, prev) => {
if (curr.mtime !== prev.mtime) {
console.log('Файл изменен');
}
});
const chokidar = require('chokidar');
const watcher = chokidar.watch('./dir', {
ignored: /(^|[\/\\])\../, // игнорировать скрытые файлы
persistent: true
});
watcher.on('add', path => console.log(`Файл добавлен: ${path}`));
chokidar
или комбинацию fs.watch
+ fs.watchFile
fs.watchFile
fs.watch
// Оптимальные настройки для watchFile
fs.watchFile('./file', { interval: 5000 }, callback);
fs.watch
не поддерживает рекурсивное наблюдение на некоторых платформахchokidar
// Ручная реализация для директорий
function watchDir(dir) {
fs.watch(dir, { recursive: true }, callback);
fs.readdirSync(dir).forEach(item => {
const path = `${dir}/${item}`;
if (fs.statSync(path).isDirectory()) watchDir(path);
});
}
watcher.on('rename', path => {
fs.access(path, fs.constants.F_OK, (err) => {
if (!err) console.log(`Файл переименован в ${path}`);
});
});
let debounceTimer;
watcher.on('change', path => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
console.log(`Реальное изменение: ${path}`);
}, 200);
});
const hashes = new Map();
watcher.on('change', path => {
fs.readFile(path, (err, data) => {
const newHash = crypto.createHash('md5').update(data).digest('hex');
if (hashes.get(path) !== newHash) {
hashes.set(path, newHash);
console.log(`Контент изменился: ${path}`);
}
});
});
fs.watch
, но будьте готовы к особенностям ОСchokidar
Для production-решений рекомендуется использовать проверенные библиотеки типа chokidar
, которые уже решили большинство кросс-платформенных проблем.