UI: fix ui/build --watch

Turns out that Node's builtin fs.watch() doesn't
work on Linux. Everybody else seems to use
node-watch which has an identical API but happens
to work.

Bug: 180028167
Change-Id: I8bb0ddd561505ee02d4a8cbe85aeed5562e8ddf2
diff --git a/ui/build.js b/ui/build.js
index c461324..cc4c5e6 100644
--- a/ui/build.js
+++ b/ui/build.js
@@ -25,11 +25,11 @@
 // and the rollup bundler in --watch mode. Any other attempt, leads to O(10s)
 // incremental-build times.
 // This script allows mixing build tools that support --watch mode (tsc and
-// rollup) and auto-triggering-on-file-change rules via fs.watch().
+// rollup) and auto-triggering-on-file-change rules via node-watch.
 // When invoked without any argument (e.g., for production builds), this script
 // just runs all the build tasks serially. It doesn't to do any mtime-based
 // check, it always re-runs all the tasks.
-// When invoked with --watch, it mounts a pipeline of tasks based on fs.watch()
+// When invoked with --watch, it mounts a pipeline of tasks based on node-watch
 // and runs them together with tsc --watch and rollup --watch.
 // The output directory structure is carefully crafted so that any change to UI
 // sources causes cascading triggers of the next steps.
@@ -69,6 +69,7 @@
 const fs = require('fs');
 const http = require('http');
 const path = require('path');
+const fswatch = require('node-watch');  // Like fs.watch(), but works on Linux.
 const pjoin = path.join;
 
 const ROOT_DIR = path.dirname(__dirname);  // The repo root.
@@ -478,14 +479,14 @@
 }
 
 // Walks the passed |dir| recursively and, for each file, invokes the matching
-// RULES. If --watch is used, it also installs a fs.watch() and re-triggers the
+// RULES. If --watch is used, it also installs a fswatch() and re-triggers the
 // matching RULES on each file change.
 function scanDir(dir, regex) {
   const filterFn = regex ? absPath => regex.test(absPath) : () => true;
   const absDir = path.isAbsolute(dir) ? dir : pjoin(ROOT_DIR, dir);
   // Add a fs watch if in watch mode.
   if (cfg.watch) {
-    fs.watch(absDir, {recursive: true}, (_eventType, fileName) => {
+    fswatch(absDir, {recursive: true}, (_eventType, fileName) => {
       const filePath = pjoin(absDir, fileName);
       if (!filterFn(filePath)) return;
       if (cfg.verbose) {