mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
This patch brings hot reloading capabilities to PHP apps: in development, the browser will automatically refresh the page when any source file changes! It's similar to HMR in JavaScript. It is built on top of [the watcher mechanism](https://frankenphp.dev/docs/config/#watching-for-file-changes) and of the [Mercure](https://frankenphp.dev/docs/mercure/) integration. Each time a watched file is modified, a Mercure update is sent, giving the ability to the client to reload the page, or part of the page (assets, images...). Here is an example implementation: ```caddyfile root ./public mercure { subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} anonymous } php_server { hot_reload } ``` ```php <?php header('Content-Type: text/html'); ?> <!DOCTYPE html> <html lang="en"> <head> <title>Test</title> <script> const es = new EventSource('<?=$_SERVER['FRANKENPHP_HOT_RELOAD']?>'); es.onmessage = () => location.reload(); </script> </head> <body> Hello ``` I plan to create a helper JS library to handle more advanced cases (reloading CSS, JS, etc), similar to [HotWire Spark](https://github.com/hotwired/spark). Be sure to attend my SymfonyCon to learn more! There is still room for improvement: - Provide an option to only trigger the update without reloading the worker for some files (ex, images, JS, CSS...) - Support classic mode (currently, only the worker mode is supported) - Don't reload all workers when only the files used by one change However, this PR is working as-is and can be merged as a first step. This patch heavily refactors the watcher module. Maybe it will be possible to extract it as a standalone library at some point (would be useful to add a similar feature but not tight to PHP as a Caddy module). --------- Signed-off-by: Kévin Dunglas <kevin@dunglas.fr> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
70 lines
2.8 KiB
Modula-2
70 lines
2.8 KiB
Modula-2
module github.com/dunglas/frankenphp
|
|
|
|
go 1.25.4
|
|
|
|
retract v1.0.0-rc.1 // Human error
|
|
|
|
require (
|
|
github.com/Masterminds/sprig/v3 v3.3.0
|
|
github.com/dunglas/mercure v0.21.2
|
|
github.com/e-dant/watcher/watcher-go v0.0.0-20251208164151-f88ec3b7e146
|
|
github.com/maypok86/otter/v2 v2.2.1
|
|
github.com/prometheus/client_golang v1.23.2
|
|
github.com/stretchr/testify v1.11.1
|
|
go.uber.org/zap v1.27.1
|
|
go.uber.org/zap/exp v0.3.0
|
|
golang.org/x/net v0.47.0
|
|
)
|
|
|
|
require (
|
|
dario.cat/mergo v1.0.2 // indirect
|
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
|
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
|
github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect
|
|
github.com/RoaringBitmap/roaring/v2 v2.14.4 // indirect
|
|
github.com/beorn7/perks v1.0.1 // indirect
|
|
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
|
github.com/dunglas/skipfilter v1.0.0 // indirect
|
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
|
github.com/gofrs/uuid/v5 v5.4.0 // indirect
|
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
|
github.com/google/uuid v1.6.0 // indirect
|
|
github.com/gorilla/handlers v1.5.2 // indirect
|
|
github.com/gorilla/mux v1.8.1 // indirect
|
|
github.com/huandu/xstrings v1.5.0 // indirect
|
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
|
github.com/mschoch/smat v0.2.0 // indirect
|
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
|
github.com/prometheus/client_model v0.6.2 // indirect
|
|
github.com/prometheus/common v0.67.4 // indirect
|
|
github.com/prometheus/procfs v0.19.2 // indirect
|
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
|
github.com/rs/cors v1.11.1 // indirect
|
|
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
|
github.com/shopspring/decimal v1.4.0 // indirect
|
|
github.com/spf13/afero v1.15.0 // indirect
|
|
github.com/spf13/cast v1.10.0 // indirect
|
|
github.com/spf13/pflag v1.0.10 // indirect
|
|
github.com/spf13/viper v1.21.0 // indirect
|
|
github.com/subosito/gotenv v1.6.0 // indirect
|
|
github.com/unrolled/secure v1.17.0 // indirect
|
|
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
|
go.etcd.io/bbolt v1.4.3 // indirect
|
|
go.uber.org/multierr v1.11.0 // indirect
|
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
|
golang.org/x/crypto v0.45.0 // indirect
|
|
golang.org/x/sys v0.38.0 // indirect
|
|
golang.org/x/text v0.31.0 // indirect
|
|
google.golang.org/protobuf v1.36.10 // indirect
|
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
)
|