lib/watcher.js
function watchFile(path, onChange) {
  try {
    var oldStats = fs.statSync(path);
    var watcher = fs.watch(path, {persistent: false});
    watcher.on('error', watchError);

    watcher.on('change', function(event) {
      fs.stat(path, function(err, stats) {
        if (err) {
          /* istanbul ignore next: not easy to repro this error in tests */
          watchError(err);
        }
        else if (stats.mtime > oldStats.mtime) {
          oldStats = stats;
          onChange(event, path);
        }
        else {
          util.debug('Ignoring %s event for "%s" because %j <= %j', event, path, stats.mtime, oldStats.mtime);
        }
      });
    });

    return watcher;
  }
  catch (e) {
    watchError(e);
  }

  function watchError(e) {
    util.warn('Error watching file "%s": %s', path, e.stack);
  }
}
function watchFile(path, onChange) {
  try {
    var oldStats = fs.statSync(path);
    var watcher = fs.watch(path, {persistent: false});
    watcher.on('error', watchError);

    watcher.on('change', function(event) {
      fs.stat(path, function(err, stats) {
        if (err) {
          /* istanbul ignore next: not easy to repro this error in tests */
          watchError(err);
        }
        else if (stats.mtime > oldStats.mtime) {
          oldStats = stats;
          onChange(event, path);
        }
        else {
          util.debug('Ignoring %s event for "%s" because %j <= %j', event, path, stats.mtime, oldStats.mtime);
        }
      });
    });

    return watcher;
  }
  catch (e) {
    watchError(e);
  }

  function watchError(e) {
    util.warn('Error watching file "%s": %s', path, e.stack);
  }
}
function watchFile ( path , onChange ) { try { var oldStats = fs . statSync ( path ) ; var watcher = fs . watch ( path , { persistent : false } ) ; watcher . on ( 'error' , watchError ) ; watcher . on ( 'change' , function ( event ) { fs . stat ( path , function ( err , stats ) { if ( err ) { /* istanbul ignore next: not easy to repro this error in tests */ watchError ( err ) ; } else if ( stats . mtime > oldStats . mtime ) { oldStats = stats ; onChange ( event , path ) ; } else { util . debug ( 'Ignoring %s event for "%s" because %j <= %j' , event , path , stats . mtime , oldStats . mtime ) ; } } ) ; } ) ; return watcher ; } catch ( e ) { watchError ( e ) ; } function watchError ( e ) { util . warn ( 'Error watching file "%s": %s' , path , e . stack ) ; } }
Watches a file, and calls the given callback whenever the file changes.

@param {string} path
The full path of the file.

@param {function} onChange
Callback signature is `function(event, filename)`. The event param will be "change", "delete", "move", etc.
The filename param is the full path of the file, and it is guaranteed to be present (unlike Node's FSWatcher).

@returns {FSWatcher|undefined}
Returns the file watcher, unless the path does not exist.
Watches a file and calls the given callback whenever the file changes .