code: function print_changed_files(webpack_compiler) {
      const mem = {
          startTime: Date.now(),
          prevTimestamps: {},
      };
      webpack_compiler.hooks.emit.tap('weDontNeedToNameThis_aapmcjbzbzeldj', (compilation, cb) => {
          const fileTs = {};
          [...compilation.fileTimestamps.keys()].forEach(key => {
              fileTs[key] = compilation.fileTimestamps.get(key);
              assert_internal(key);
              assert_internal(fileTs[key]);
          });
          var changedFiles = Object.keys(fileTs).filter(function(watchfile) {
              const ts = fileTs[watchfile];
              return (mem.prevTimestamps[watchfile] || mem.startTime) < (fileTs[watchfile] || Infinity);
          });
  
          if( changedFiles.length > 0 ) {
              console.log('\nFiles with new timestamps:\n', changedFiles);
          }
  
          mem.prevTimestamps = compilation.fileTimestamps;
      });
  }
docs: /* Doesn't work when doing `watching.close()`
  function catch_webpack_not_terminating(webpack_compiler, {timeout_seconds, compilationName}) {
  let is_compiling;
  webpack_compiler.hooks.compile.tap('weDontNeedToNameThis_pamffwblasa', () => {
  is_compiling = true;
  setTimeout(() => {
  assert_warning(
  !is_compiling,
  "Webpack compilation still not finished after "+timeout_seconds+" seconds.",
  "Compilation name: "+compilationName,
  "It likely means that webpack ran into a bug and hang.",
  "You need to manually restart the building."
  );
  }, timeout_seconds*1000)
  });
  
  webpack_compiler.hooks.done.tap('weDontNeedToNameThis_uihaowczb', () => {
  is_compiling = false;
  });
  }
   Adapated from https://webpack.js.org/contribute/plugin-patterns/#monitoring-the-watch-graph