| Three tarballs where a devShell was 5ce66d5 nandi 23h ago | 1 | #!/usr/bin/env bash |
| 2 | # The Flutter web build: one `clojure -M:cljd compile` over `flutter/src` and |
| 3 | # `common/`, then `flutter build web` over what that generated. |
| 4 | # |
| 5 | # A shell script and not a `just` recipe in a devShell, because this is the |
| 6 | # one target that needs nothing from the host — no JDK of the machine's, no |
| 7 | # GTK, no Android SDK, no nix. `tools/toolchain.sh` fetches the three tarballs |
| 8 | # it does need, and everything below runs out of `.toolchain/`. The container |
| Six verbs, and the last of the nix 2e24e64 nandi 16h ago | 9 | # in `.modal/web/` runs this same file; `just build web` is a |
| Three tarballs where a devShell was 5ce66d5 nandi 23h ago | 10 | # wrapper around it. |
| 11 | # |
| 12 | # tools/build-web.sh build build/web |
| 13 | # tools/build-web.sh serve 8080 build it and serve it |
| 14 | # |
| 15 | # The entry point is `frq.main-web`, not `frq.main`: path_provider has no web |
| 16 | # implementation, so the `getApplicationSupportDirectory` that `frq.main` |
| 17 | # awaits throws MissingPluginException before any widget is built. The web |
| 18 | # entry installs `frq.io.web` — localStorage behind the same seam — and awaits |
| 19 | # nothing. |
| 20 | set -euo pipefail |
| 21 | |
| 22 | root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
| 23 | action="${1:-build}" |
| 24 | port="${2:-8080}" |
| 25 | |
| 26 | case "$action" in build|serve) ;; *) |
| 27 | echo "usage: build-web.sh [build|serve] [port]" >&2; exit 1 ;; |
| 28 | esac |
| 29 | |
| 30 | # One build, and it is the release one. There was a `fast` mode here for a |
| 31 | # while — dart2js at -O1, no icon tree-shaking, no service worker — on the |
| 32 | # theory that the edit-compile loop should not pay for the bundle it ships. |
| 33 | # Measured on this program it pays for almost nothing: -O1 came out at 52.5s |
| 34 | # against release's 49.8s on the same source change, because what dart2js |
| 35 | # spends its time on here is reading and linking the whole program, not |
| 36 | # optimising it. A second bundle, twice the surface to reason about and a |
| 37 | # megabyte more to serve, for noise. If a future dart2js changes that, the |
| 38 | # flags to reach for are `--optimization-level=1`, `--no-tree-shake-icons` |
| 39 | # and `--no-source-maps`, and the number to beat is written down above. |
| 40 | # |
| 41 | # `--no-wasm-dry-run` is the one that did pay: 52.0s against 55.7s, about 6%, |
| 42 | # for skipping a dry-run compile of the whole program against the wasm |
| 43 | # backend that can never succeed here. `frq.io.web`, `frq.net.web`, |
| 44 | # `frq.oauth.web` and three more are `dart:html`, which wasm does not |
| 45 | # support and which is the entire reason those namespaces exist. The build |
| 46 | # was being told, at whole-program cost, something the source already says. |
| 47 | build_flags=(--release --no-wasm-dry-run) |
| 48 | |
| 49 | eval "$("$root/tools/toolchain.sh" env)" |
| 50 | cd "$root/flutter" |
| 51 | |
| 52 | # The web target is off in a checkout created for Android and Linux. |
| 53 | # `flutter/web/` itself IS committed, unlike the Android and Linux runners: |
| 54 | # the OAuth client keeps a script of its own beside the bundle (see |
| 55 | # web/frq_dpop.js), and a directory `flutter create` regenerates is no place |
| 56 | # to keep one. |
| 57 | # |
| 58 | # Stamped, because `flutter config` is a Dart VM start and a settings-file |
| 59 | # rewrite for an answer that cannot change under us — this is the only thing |
| 60 | # that sets the flag, and the toolchain directory is already where this build |
| 61 | # remembers what it has done. |
| 62 | if [ ! -e "$FRQ_TOOLCHAIN/.web-enabled" ]; then |
| 63 | flutter config --enable-web >/dev/null || true |
| 64 | touch "$FRQ_TOOLCHAIN/.web-enabled" |
| 65 | fi |
| 66 | |
| 67 | # `frq.main-web` and not `frq.main`: the compile walks out from the namespace |
| 68 | # it is given, which is what keeps `dart:html` in the web build and out of the |
| 69 | # other two. `flutter/lib/main_web.dart` is the one-line export beside the |
| 70 | # generated `main.dart` that -t points at. |
| 71 | # |
| 72 | # `-Sdeps` with an explicit local repo rather than ~/.m2, for GITLIBS' reason: |
| 73 | # the JVM will not look where HOME says. |
| 74 | clojure -Sdeps "{:mvn/local-repo \"$FRQ_M2\"}" -M:cljd compile frq.main-web |
| 75 | |
| 76 | flutter build web -t lib/main_web.dart "${build_flags[@]}" |
| 77 | echo "built $PWD/build/web ($(du -sh build/web | cut -f1))" |
| 78 | |
| 79 | if [ "$action" = serve ]; then |
| 80 | echo "serving $PWD/build/web on :$port" |
| 81 | # Dart's own file server, out of the toolchain, because the toolchain is |
| 82 | # the whole dependency list: reaching for python3 here would put a fourth |
| 83 | # language on the list of things a machine must already have to serve a |
| 84 | # directory. |
| 85 | # |
| 86 | # --bind 0.0.0.0 and not loopback: in the container this is behind a Modal |
| 87 | # tunnel, and a server bound to 127.0.0.1 is one the tunnel cannot reach. |
| 88 | exec dart "$root/tools/serve-dir.dart" build/web "$port" |
| 89 | fi |