Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd: add --notify to generate --watch in cli #656

Closed
jackielii opened this issue Mar 30, 2024 · 3 comments · Fixed by #661
Closed

cmd: add --notify to generate --watch in cli #656

jackielii opened this issue Mar 30, 2024 · 3 comments · Fixed by #661
Labels
cmd enhancement New feature or request good first issue Good for newcomers NeedsImplementation Needs implementation

Comments

@jackielii
Copy link
Contributor

The problem

Templ handles automatic reloading of browser based on SSE when it detects a file change. However, it only watches Templ related files, and rightly so. The community has come up with various methods to watch other files e.g. for Go, there is air and wgo, for tailwindcss, there is tailwindcss cli. For example, this is my solution as an example:

live/templ:
	templ generate --watch --proxy="http://localhost:8080" --open-browser=false -v

live/server:
	go run github.com/cosmtrek/[email protected] \
	--build.cmd "make build" --build.bin "/tmp/bin/${BINARY_NAME}" --build.delay "100" \
	--build.exclude_dir "assets,node_modules,bak" \
	--build.include_ext "go,templ" \
	--misc.clean_on_exit "true"

live/tailwind:
	npx tailwindcss -i ./input.css -o ./assets/styles.css --minify --watch

live: 
	make -j3 live/templ live/server live/tailwind

Here I start 3 watch processes:

  1. templ generate
  2. air for rebuilding and reloading go
  3. tailwindcss watch

However, the reloading of the browser doesn't always work. It sort of works for Go files, take this for an example:

  1. edit and save index.templ
  2. templ watches and re-generates index_templ.txt. Around the same time, air detects templ change and tries to rebuild and reruns the binary
  3. templ send down reload event to the browser via SSE

In this process, go build and restart proces is usually very fast, so the reload usually happens correctly. But for reloading the assets/styles.css when tailwind rebuilds it, there is no right way to do it.

Templ would like to stay simple to only handle its related files, see issue #646 for which I fully support. However templ should provide a way for other process to notify there is a change so that users can progmatically send the reload event when necessary.

Proposal

Add --notify to generate subcommand. An example would look like this:

templ generate --watch --notify

It should send an reload event via SSE and exit immediately. By default, it sends to port 7331, for an alternative port, -proxyport can be specified.

If this is implemented, one can simply add another directive in the makefile like so:

live/reload:
	wgo -dir assets temple generate --watch --notify

live: 
	make -j4 live/templ live/server live/tailwind live/reload

Alternatives

Alternative I considered is browser-sync, however it can't handle templ related generation efficiently.

@a-h
Copy link
Owner

a-h commented Mar 30, 2024

That sounds like a useful feature to add.

In terms of implementation, it feels to me that the proxy should start an additional route (

func (p *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/_templ/reload/script.js" {
// Provides a script that reloads the page.
w.Header().Add("Content-Type", "text/javascript")
_, err := io.WriteString(w, script)
if err != nil {
fmt.Printf("failed to write script: %v\n", err)
}
return
}
if r.URL.Path == "/_templ/reload/events" {
// Provides a list of messages including a reload message.
p.sse.ServeHTTP(w, r)
return
}
p.p.ServeHTTP(w, r)
}
), or the SSE handler should distinguish between POST and GET requests, with GET requests resulting in the current behaviour, and POST requests unpacking a HTTP FORM (and also supporting JSON?) to send a message type type of "message", and data of "reload".

With that in place, curl could be used directly on the templ proxy from the CLI, and a templ generate --watch --notify command wouldn't strictly be required.

I think the name would be less ambiguous if it was --notify-proxy because reading it, it could be interpreted that we're somehow notifying the --watch operation that files have changed.

Other implementation notes would be that it's important to update the hot reload docs to cover this, and ensure we have an integration test added to the hot reload integration test suite.

@a-h a-h added the enhancement New feature or request label Mar 30, 2024
@a-h
Copy link
Owner

a-h commented Mar 30, 2024

@jackielii - if you want to implement this, I'd happily take a PR. If not, just mention it here, and it will be free for someone else to pick up.

I want to focus on a new CSS parser implementation, as well as reviewing other PRs, replying to issues etc.

@a-h a-h added good first issue Good for newcomers NeedsImplementation Needs implementation labels Mar 30, 2024
@joerdav joerdav added the cmd label Apr 2, 2024
@joerdav joerdav changed the title Proposal: add --notify to generate --watch in cli cmd: add --notify to generate --watch in cli Apr 2, 2024
@a-h a-h closed this as completed in #661 Apr 4, 2024
@verheyenkoen
Copy link

I noticed this is document in the live reload docs but not mentioned on the CLI page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmd enhancement New feature or request good first issue Good for newcomers NeedsImplementation Needs implementation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants