blog.vldmrkl.com

Node.js File System Method: fs.watch

September 14, 2018

I am going to look into the watch method of Node fs module. This method watches for changes in provided files or directories. Let’s take a look at function definition:

fs.watch(filename[, options][, listener])

It takes three arguments:

  • filename — file/directory to watch
  • options — optional argument, you can specify these parameters there: persistent, recursive, encoding
  • listener — is a callback function with parameters eventType and filename

The watch method returns instance fsWatcher class, which invokes the “change” method of EventEmitter class 🤔

Let’s take a look at my example. I created a text file called “node-desc.txt” with a sample content:
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

I also wrote a small node app to watch for changes of the “node-desc.txt”:

const fs = require('fs');
const WATCH_TARGET = './node-desc.txt';
fs.watch(WATCH_TARGET, (eventType, filename) => {
  console.log('File "' + filename + '" was changed: ' + eventType);
});

I call fs.watch method with WATCH_TARGET (filename argument) and listener callback, where I log occurred “change” event. When I start my app and edit my text file by adding an extra character(don’t forget to save it), I am getting the following output in my console:
File "node-desc.txt" was changed: change
File "node-desc.txt" was changed: change

It’s not a misprint. I have really got two messages, however, I saved my changes one time. I was curious about why it happened, so I did a research and found the answer on GitHub:
a write to a file triggers two kqueue events NOTE_EXTEND and NOTE_WRITE

In the documentation, it is mentioned that:

On macOS, this uses kqueue(2) for files and FSEvents for directories.

and it absolutely makes sense because I’m using macOS.

There is also watchFile method in fs module. It works in a similar way as fs.watch, but it watches only for files, not directories. According to documentation, it is recommended to use fs.watch rather than fs.watchFile which is slower and less reliable.