From ce4fc9621250c508b1d2bc94e98a9eaaca064fa7 Mon Sep 17 00:00:00 2001 From: Phillip Barta Date: Fri, 2 Dec 2022 01:26:52 +0100 Subject: [PATCH] feat(graph): use daemon file watcher instead of chokidar --- packages/nx/package.json | 1 - packages/nx/src/command-line/dep-graph.ts | 75 +++++++++++------------ 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/nx/package.json b/packages/nx/package.json index 31d9161fad4be8..5680860eff169d 100644 --- a/packages/nx/package.json +++ b/packages/nx/package.json @@ -38,7 +38,6 @@ "@zkochan/js-yaml": "0.0.6", "axios": "^1.0.0", "chalk": "4.1.0", - "chokidar": "^3.5.1", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^7.0.2", diff --git a/packages/nx/src/command-line/dep-graph.ts b/packages/nx/src/command-line/dep-graph.ts index 010baf7e60a1ec..70ec274417f72c 100644 --- a/packages/nx/src/command-line/dep-graph.ts +++ b/packages/nx/src/command-line/dep-graph.ts @@ -1,5 +1,4 @@ import { workspaceRoot } from '../utils/workspace-root'; -import { watch } from 'chokidar'; import { createHash } from 'crypto'; import { existsSync, readFileSync, statSync, writeFileSync } from 'fs'; import { copySync, ensureDirSync } from 'fs-extra'; @@ -13,7 +12,6 @@ import { readNxJson, workspaceLayout } from '../config/configuration'; import { defaultFileHasher } from '../hasher/file-hasher'; import { output } from '../utils/output'; import { writeJsonFile } from '../utils/fileutils'; -import { joinPathFragments } from '../utils/path'; import { ProjectGraph, ProjectGraphDependency, @@ -24,6 +22,7 @@ import { createProjectGraphAsync } from '../project-graph/project-graph'; import { createTaskGraph } from '../tasks-runner/create-task-graph'; import { TargetDefaults, TargetDependencies } from '../config/nx-json'; import { TaskGraph } from '../config/task-graph'; +import { daemonClient } from '../daemon/client/client'; export interface ProjectGraphClientResponse { hash: string; @@ -326,8 +325,9 @@ async function startServer( exclude: string[] = [], openBrowser: boolean = true ) { + let unregisterFileWatcher: (() => void) | undefined; if (watchForchanges) { - startWatcher(); + unregisterFileWatcher = await createFileWatcher(); } currentDepGraphClientResponse = await createDepGraphClientResponse(affected); @@ -410,6 +410,15 @@ async function startServer( open(`${url}?${params.toString()}`); } + + const handleTermination = async (exitCode: number) => { + if (unregisterFileWatcher) { + unregisterFileWatcher(); + } + process.exit(exitCode); + }; + process.on('SIGINT', () => handleTermination(128 + 2)); + process.on('SIGTERM', () => handleTermination(128 + 15)); } let currentDepGraphClientResponse: ProjectGraphClientResponse = { @@ -437,22 +446,6 @@ function getIgnoredGlobs(root: string) { return ig; } -function startWatcher() { - createFileWatcher(workspaceRoot, async () => { - output.note({ title: 'Recalculating project graph...' }); - - const newGraphClientResponse = await createDepGraphClientResponse(); - - if (newGraphClientResponse.hash !== currentDepGraphClientResponse.hash) { - output.note({ title: 'Graph changes updated.' }); - - currentDepGraphClientResponse = newGraphClientResponse; - } else { - output.note({ title: 'No graph changes found.' }); - } - }); -} - function debounce(fn: (...args) => void, time: number) { let timeout: NodeJS.Timeout; @@ -465,28 +458,32 @@ function debounce(fn: (...args) => void, time: number) { }; } -function createFileWatcher(root: string, changeHandler: () => Promise) { - const ignoredGlobs = getIgnoredGlobs(root); - const layout = workspaceLayout(); - - const watcher = watch( - [ - joinPathFragments(layout.appsDir, '**'), - joinPathFragments(layout.libsDir, '**'), - ], - { - cwd: root, - ignoreInitial: true, - } - ); - watcher.on( - 'all', - debounce(async (event: string, path: string) => { - if (ignoredGlobs.ignores(path)) return; - await changeHandler(); +function createFileWatcher() { + return daemonClient.registerFileWatcher( + { watchProjects: 'all', includeGlobalWorkspaceFiles: true }, + debounce(async (error, { changedFiles }) => { + if (error === 'closed') { + output.error({ title: `Watch error: Daemon closed the connection` }); + process.exit(1); + } else if (error) { + output.error({ title: `Watch error: ${error?.message ?? 'Unknown'}` }); + } else if (changedFiles.length > 0) { + output.note({ title: 'Recalculating project graph...' }); + + const newGraphClientResponse = await createDepGraphClientResponse(); + + if ( + newGraphClientResponse.hash !== currentDepGraphClientResponse.hash + ) { + output.note({ title: 'Graph changes updated.' }); + + currentDepGraphClientResponse = newGraphClientResponse; + } else { + output.note({ title: 'No graph changes found.' }); + } + } }, 500) ); - return { close: () => watcher.close() }; } async function createDepGraphClientResponse(