💾 Archived View for log.pfad.fr › 2023 › devf-axe-sharpening captured on 2023-11-04 at 11:06:41. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-09-28)
-=-=-=-=-=-=-
I write quite a lot of software in Go, mostly web-based. This means that I have my code editor and my web browser opened in parallel, to visually check what my code produces. Naively it involves the following manual steps:
Since other developers already had this issue a couple of open-source solutions are already available. Until now I have been using the combo modd+devd, which automates the 2 last steps above (compile and reload):
modd: flexible developer tool that runs processes and responds to filesystem changes
devd: local webserver for developers
Configuration example for modd:
# Exclude all test files of the form *_test.go
The first block launches `go run ./cmd/server` when any (non-test) go file changes.
In the `./cmd/server/main.go`, I start a local web server, which writes an empty `server.is_running` file when the server is ready to accept connections. When modd detects that this file has been updated, it sends a sighup to devd, which reloads the browser (this also happens whenever I update a gohtml template file).
This setup served me well for a time, but I encountered some frustration lately:
Looking at the codebase of devd, I saw no recent push activity (last commit more than 3 years ago) and quite a lot of code (52 files, 12 packages). I then had the idea to develop my own devd.
code.pfad.fr/devf (live-reload web server for developers)
devf attempts to do one thing and do it well: serve as a reverse proxy while injecting some JS to support livereloading.
The reloading must be externally triggered, either by writing to its standard input or sending predefined signals. It can either server local files or proxy to some upstream server.
Since I intentionally skipped many features of devd (throttling, tls, watcher, basic auth, CORS...), it needs to be wired up with other tools (like modd or inotifywait). The `livereload` subpackage exposes an http.Handler that can be imported if one wants to build on top of it.
For this blog, I have the following Makefile:
build: # compile the blog, put it to dist and write the .dist.is_done file @rm -rf dist ./kiln build @touch .dist.is_done dev: build $(MAKE) --no-print-directory -j2 watch serve-html watch: @inotifywait -m -e close_write -r --exclude "(dist|\.git)" . | xargs -I{} -d "\n" $(MAKE) --no-print-directory build serve-html: inotifywait -m -e close_write .dist.is_done | go run code.pfad.fr/devf@latest -addr=:8087 dist/html
When I run `make dev` two tasks are launched in parallel, after an initial build:
Both tasks work by piping the output of `inotifywait` (one line on every file-change event) to other tools. I consider this to be a nice example of composibility in linux.
I found this Makefile much harder to write since it needs to interrupt a long-running process whenever a file changes.
dev: $(MAKE) --no-print-directory -j2 dev-devf dev-backend dev-devf: inotifywait -m -e close_write --include "\.(is_running|gohtml|js|css)$" -r . | \ go run code.pfad.fr/devf -addr localhost:8000 http://localhost:8989 dev-backend: pid="nonexisting" ; \ (echo "initial generation" && inotifywait -m -e close_write --include "\.(go)$" -r .) | \ while read -r path; do \ echo "$path and $(timeout 0.1 cat | wc -l) other changes" ; \ pkill -TERM -P $pid ; \ wait $pid ; \ ( \ go run ./cmd/server \ ) & \ pid=$! ; \ done
When I run `make dev` two tasks are launched in parallel:
The `dev-backend` has a few quirks:
I would be grateful for any tips, if anyone knows how to simplify the `dev-backend` task, to remove some of those quirks!
Rewriting a tool that I use regularly was very interesting and a lot of fun. It allowed me to learn quite a lot about using pipes and inotify on Linux for my various workflows (even if they don't need live reloading).
Thanks to using the commands above, I don't have to leave my editor when coding: the code gets compiled and my browser reloads immediately.
Feel free to try it out and let me know how it works for you!
code.pfad.fr/devf (live-reload web server for developers)
📅 2023-06-26