Hot Reloading is a feature of Ema’s dev server wherein any changes to your Haskell source or data files (such as Markdown files or HTML templates) propagate instantly to the web browser without requiring any manual intervention like a full browser refresh. In practice, this is a such a delightful feature to work with. Imagine changing CSS style of an element, and see it reflect on your site in a split second.
How Ema implements hot reload
The Ema dev server uses websockets to keep a bi-directional connection open between the web browser and the backend server. When you click on a link or when something changes in the backend, they are communicated via this connection. In a statically generated site, however, no such activity happens - and a link click behaves like a normal link, in that the browser makes a full HTTP request to the linked page.
When switching to a new route or when receiving the new HTML, Ema uses morphdom to patch the existing DOM tree rather than replace it in its entirety. This, in addition to use of websockets, makes it possible to support instant hot reload with nary a delay.
Finally, hot reload on code changes are supported via ghcid. The template repo's `bin/run` script uses ghcid underneath. Any HTML DSL (like
blaze-html) or CSS DSL automatically gets supported for hot-reload. If you choose to use a file-based HTML template language, you can enable hot-reload on template change using the `unionmount` library.
Note that if your application makes use of threads, it is important to setup cleanup handlers so that
ghcid doesn’t leave ghost processes behind. Helpers like
race_ will do this automatically (incidentally it is used by
runEma for running the user IO action).
For anything outside of the Haskell code, your code becomes responsible for monitoring and updating the model LVar. The `unionmount` library already provides utilities to facilitate this for monitoring changes to files and directories.
If your code throws a Haskell exception, they will be gracefully handled and displayed in the browser, allowing you to recover without breaking hot-reload flow.