haskell-wasm-repl/README.md

49 lines
3.1 KiB
Markdown
Raw Permalink Normal View History

2024-10-10 19:12:48 +05:30
# Haskell WASM REPL Template
A template project to create [REPLs](https://en.wikipedia.org/wiki/REPL) with [Haskell](https://haskell.org) that run in the browser using [WASM](https://en.wikipedia.org/wiki/WebAssembly).
## Running
The project is orchestrated using [Nix]. After you enter the Nix shell by running `nix-shell`, you can the following commands:
- `clean`: Cleans the Cabal build directory.
- `compile`: Build the project using Cabal.
- `run`: Builds and run the project using Cabal.
- `build`: Builds the project using Nix. Builds dynamically linked executables.
- `build-static`: Builds the project using Nix. Builds statically linked executables. Requires either to be run on Linux, or to have a Nix [Linux builder](https://nixcademy.com/posts/macos-linux-builder/) configured.
- `build-docker`: Runs the previous step and creates a [Docker](https://en.wikipedia.org/wiki/Docker_(software)) image with the statically linked executables using Nix. Requires Docker to be set up on the build machine. The image will also contain the contents of the `data` directory.
- `build-wasm`: Runs the previous step and converts the Docker image into a WASM binary `out.wasm`, and copies it into the `web` directory.
- `serve`: Serves the contents of the `web` directory over HTTP locally.
The `build-static`, `build-docker`, and `build-wasm` commands take a long time to finish when run for the first time, maybe even hours. The built artifacts are cached so subsequent builds finish in minutes.
## Deploying
You can copy the contents of the `web` directory to your server and serve them as a static website. For the browser to load the WASM file, the server needs to send the following headers:
```http
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```
It is recommended to configure your server to serve pre-compressed assets, and to pre-compress the `out.wasm` file using Brotli or Gzip. This reduces the browser load time of the website by more than half.
It is also recommended to configure cache-control headers for the assets in your server so that browsers cache them. If you change the `out.wasm` file frequently, it is recommended to figure out a cache-busting policy for it.
## Developing
This project uses the following tools/components:
- [Nix] is used to build statically linked executables and Docker images.
- [Niv](https://github.com/nmattia/niv) is used to pin Nix dependencies.
- [container2wasm](https://github.com/ktock/container2wasm) is used to convert Docker images to WASM binaries. The [WASI example](https://github.com/ktock/container2wasm/tree/main/examples/wasi-browser/htdocs) from container2wasm forms the basis of the `web` directory.
- [Xterm.js](https://github.com/xtermjs/xterm.js/) is used to create the web terminal in browsers.
- [Xterm-pty](https://github.com/mame/xterm-pty/) is used to run the WASM binary on Xterm.
- [Xterm-fit-addon](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit) is used to make the web terminal fullscreen.
## Using
For unknown reasons, the WASM REPL does not work on Safari. Please use it in Firefox or Chrome.
[Nix]: https://nixos.org