Embedded the frontend in the binary, and built it in the build script

`npm run sync` in web/ copies the build output (web/dist, from npm run build)
to internal/frontend/dist, which the binary embeds. Go can't embed from
outside the package's directory (web/ is also outside the Go module), hence
the copy. Only dist/.gitkeep is committed, so a fresh clone still compiles,
and a binary built without syncing first serves no frontend.

job-search serve serves server.frontend.dir if it is set, or else the
embedded build, or warns that there is no frontend. scripts/build.sh builds
and syncs the frontend before building, running npm ci first for a release
or when web/node_modules is missing.
This commit is contained in:
bwilliams committed 2026-10-16 16:03:15 +01:00
1 parent 1832ea7437
commit 5e6c011ecb
12 files changed
+104 -11

No files matched your search

+16 -1
View File
@@ -15,11 +15,24 @@ scripts/build.sh # build/job-search-<version>
scripts/build.sh --release # also package release/job-search-<version>-<arch>.tar.gz
```
The build script runs `go generate ./...`, which needs `swag` installed (see
The build script builds the frontend and copies it into place for embedding
(`npm run build` and `npm run sync` in `web/`, which need Node and npm; it
runs `npm ci` first for a release, or when `web/node_modules` is missing). It
then runs `go generate ./...`, which needs `swag` installed (see
[Installation of dev tools](#installation-of-dev-tools)), and stamps the
version from the latest git tag. A build from untagged commits is marked as a development build
and isn't packaged unless `--force` is also given.
The frontend (`web/`) is embedded in the binary. Without the build script,
build it and copy it into place first, or the binary serves no frontend
(`job-search serve` warns):
```bash
cd web && npm ci && npm run build && npm run sync # web/dist -> internal/frontend/dist
```
Setting `server.frontend.dir` serves a build from disk instead.
During development, `go run -tags sqlite_fts5 ./cmd/jobsearch` works as well.
The `sqlite_fts5` tag is needed for the database's title search (see
[Testing](#testing)).
@@ -157,6 +170,8 @@ second one fails with "address already in use".
| `internal/logging` | slog setup and the HTTP access log |
| `internal/mock` | Mock external services |
| `internal/version` | Version information set at build time |
| `internal/frontend` | Serves the frontend's build output; embeds `dist/`, copied there from `web/dist` by `npm run sync` |
| `web` | The frontend (see [web](web/README.md)) |
## Testing