Files
RenewCMS/docs/development.md
T

4.6 KiB

Development

Prerequisites

Tool Version Install
Go 1.27+ (see go.mod)
Node.js 20.19+ or 22.12+ (22 LTS recommended) nvm install 22 — Vite and vue-tsc run on Node
Bun (package manager and script runner) 1.x powershell -c "irm bun.sh/install.ps1 | iex" or curl -fsSL https://bun.sh/install | bash
Task 3.43+ go install github.com/go-task/task/v3/cmd/task@latest
Git any

task setup installs the rest: air for hot reload, gremlins for mutation testing, Go modules and frontend dependencies. Make sure $(go env GOPATH)/bin is on your PATH.

No C compiler is needed. The SQLite driver (glebarez/sqlite, backed by modernc.org/sqlite) is pure Go, and every build runs with CGO_ENABLED=0.

First run

cp .env.example .env     # set at least JWT_SECRET; SMTP is only needed to actually send mail
task setup
task dev

Open http://localhost:5173.

How the dev setup works

browser ──▶ http://localhost:5173   Vite dev server (HMR)          task dev:web
              │  /v1/*, /healthz
              └──proxy──▶ http://localhost:8080   Go API via air   task dev:api
  • Always use the Vite URL (5173). The Vite dev server proxies API calls to Go (see server.proxy in web/vite.config.ts). The browser therefore sees a single origin, so the jwt cookie works and no CORS setup is needed. In the frontend, call the API with relative URLs (/v1/...) and never hardcode localhost:8080.
  • air rebuilds and restarts the API when a .go or .html file (such as a mail template) changes. Its config is in .air.toml.
  • Run the two halves separately with task dev:api and task dev:web if you want their logs in separate terminals.

The nofrontend build tag

The production binary embeds the built SPA from internal/infrastructure/assets/dist/ (the //go:embed in assets_embed.go). That directory only exists after task build:web.

To keep Go work independent of the frontend toolchain, all dev and quality tasks build with -tags nofrontend. That tag compiles assets_stub.go instead of the embed. The resulting binary serves the API normally and answers / with a notice that points to Vite.

Command Tag Needs the frontend built?
task dev:api, test, cover, mutate, lint:go nofrontend no
task build, release, run (none) yes (the task builds it first)
plain go build ./..., go vet ./... (none) yes, so add -tags nofrontend

If your editor reports pattern all:dist: no matching files found, either run task build:web once or set the gopls build flags to -tags=nofrontend. In VS Code, add this to settings.json: "gopls": { "buildFlags": ["-tags=nofrontend"] }.

Everyday commands

task --list          # everything available
task test            # Go tests; extra args pass through: task test -- -run TestCreateArticle -v
task cover           # coverage of the use cases → tmp/coverage.out
task mutate          # gremlins mutation testing → tmp/gremlins.json
task lint            # gofmt check, go vet, eslint --fix, vue-tsc
task fmt             # gofmt -w + prettier
task run             # build the production binary and run it (SPA embedded) on :8080
task clean           # remove bin/, tmp/ and the built SPA

Tests

  • All Go tests live in test/ (package test, black-box). They use in-memory fakes of the domain Repository interfaces, so they need no database, SMTP server or network.
  • HTTP-level tests use net/http/httptest against a chi router. Call validator.InitValidator() before invoking a handler.
  • The frontend has no test runner yet. task lint:web runs eslint and a type check.

Data

With the default configuration, local state lives in ./data/: renewcms.db and uploads/. The directory is gitignored. Delete it to start from scratch.