Skip to content

feat: add --on-watch option to run a command on watched changes - #932

Open
harshilv17 wants to merge 2 commits into
fastify:mainfrom
harshilv17:feat/on-watch
Open

harshilv17 wants to merge 2 commits into
fastify:mainfrom
harshilv17:feat/on-watch

Conversation

@harshilv17

Copy link
Copy Markdown

Closes #569

Adds an --on-watch option (FASTIFY_ON_WATCH env, or onWatch in a config file) to start --watch. On every watched change the command runs through the shell with its output piped through, and the app reloads after the command exits:

fastify start -w --on-watch 'npm run lint' app.js
  • A non-zero exit is logged (on-watch command exited with code N) and the app still reloads, so a lint error doesn't stop the watcher.
  • Changes made while the command is running don't start another run; the reload that follows picks them up. A burst of saves runs the command once.
  • Files the command writes should go in --ignore-watch, otherwise each run triggers the next one. The help text and README say so.
  • After the watcher is stopped, a command that finishes doesn't fork a new child.

Without --on-watch the watcher behaves as before.

I also checked it by hand on a small app: two touch app.js ran the command twice and reloaded the server twice (same restart count as plain --watch), and --on-watch 'exit 3' logged the exit code and kept serving.

Checklist

Closes fastify#569

Signed-off-by: harshilv17 <harshilvalecha@gmail.com>
@SameRainbows

Copy link
Copy Markdown

Tested locally on Node 24. The unit tests in test/watch-unit.test.js cover command execution before restart, debouncing during an active run, non-zero exit logging, and suppression of restarts after stop.

One edge case to consider: if emitter.stop() is called while an on-watch command is still executing, stop() terminates the running application children in childs but does not terminate the spawned child process. Holding a reference to the active spawn process and calling .kill() on it inside emitter.stop() would ensure long-running commands (such as a slow build or type check) do not linger after the watcher halts.

Signed-off-by: harshilv17 <harshilvalecha@gmail.com>
@harshilv17

Copy link
Copy Markdown
Author

@SameRainbows Good catch, thanks. Pushed a fix: stop() now kills a running on-watch command, and the test checks it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Watch commands parameter => run command on watch triggered

2 participants