[E00-S01-T06] Document local non-container developer path #373
@@ -6,7 +6,8 @@
|
||||
"description": "EPPP public server application. Bootstrap placeholder — the Fastify 5 application shell lands in a later story.",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"start": "node dist/index.js"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
# Local non-container development
|
||||
|
||||
This guide documents the **local, non-container developer path** for the EPPP
|
||||
workspace: how to install, build and run the project on your machine **without
|
||||
Docker**. The containerised path (Docker Compose baseline, container smoke
|
||||
tests) is tracked separately as story [E00-S02] Docker Compose baseline and is
|
||||
**not** covered here.
|
||||
|
||||
> Status: this document tracks the E00-S01 workspace bootstrap state. Commands
|
||||
> and expected outputs below were verified from a clean clone.
|
||||
|
||||
## What you get at bootstrap
|
||||
|
||||
The workspace is a pnpm monorepo with three package groups:
|
||||
|
||||
| Group | Path | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Bootstrap placeholder — the Fastify 5 application shell lands in a later story. |
|
||||
| `packages/` | `packages/core` (`@personal-blog/core`) | Application core (site identity, content primitives). Bootstrap placeholder. |
|
||||
| `extensions/` | `extensions/example` (`@personal-blog/example-extension`) | Example extension exercising the `extensions/` group. Bootstrap placeholder. |
|
||||
|
||||
A dependency-boundary rule (`dependency-boundaries.json`, enforced by
|
||||
`tests/architecture-import.test.mjs`) keeps the groups from collapsing into an
|
||||
accidental dependency graph: no `packages/*` package may import a concrete
|
||||
`extensions/*` package.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Git** — to clone the repository.
|
||||
- **Node.js 24.x** — the CI pipeline runs Node 24 and this is the supported
|
||||
line for the workspace (a hard `engines` restriction is tracked separately as
|
||||
E00-S01-T08). Any Node ≥ 22 is enough for the current bootstrap commands.
|
||||
- **pnpm 11.23.0** — pinned via the `packageManager` field in the root
|
||||
`package.json`. The easiest way to get exactly this version is Corepack,
|
||||
which ships with Node.js (`corepack enable`).
|
||||
|
||||
No database, no runtime services and no Docker daemon are required at this
|
||||
stage.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
# 1. Clone the repository
|
||||
git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git
|
||||
cd PersonalBlog
|
||||
|
||||
# 2. Activate the pinned pnpm (11.23.0) via Corepack
|
||||
corepack enable
|
||||
|
||||
# 3. Install dependencies against the committed lockfile (reproducible)
|
||||
pnpm install --frozen-lockfile
|
||||
```
|
||||
|
||||
- The install is **frozen**: `--frozen-lockfile` refuses to run if
|
||||
`pnpm-lock.yaml` is out of date with the manifests, so every clone gets the
|
||||
exact same dependency tree. CI uses the same flag.
|
||||
- If you are adding or changing dependencies, run `pnpm install` (without the
|
||||
flag) and **commit the resulting `pnpm-lock.yaml`** so the frozen install
|
||||
keeps working for everyone.
|
||||
- `node_modules/` and the pnpm content-addressable store are git-ignored and
|
||||
never committed.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
# Compile every workspace package (apps, packages, extensions) into dist/
|
||||
pnpm build
|
||||
|
||||
# Typecheck every workspace package (no emit)
|
||||
pnpm typecheck
|
||||
```
|
||||
|
||||
`pnpm build` runs `tsc -p tsconfig.json` in each package in topological order
|
||||
and emits `dist/` (JavaScript + type declarations + source maps) per package.
|
||||
Expected result: `apps/server/dist/`, `packages/core/dist/` and
|
||||
`extensions/example/dist/` are produced, all packages report `Done`, exit 0.
|
||||
`dist/` is git-ignored; rebuild whenever you change `src/`.
|
||||
|
||||
## Run
|
||||
|
||||
```sh
|
||||
# Run the compiled public server entrypoint
|
||||
pnpm --filter @personal-blog/server start
|
||||
```
|
||||
|
||||
This runs the `start` script of `apps/server` (`node dist/index.js`), i.e. the
|
||||
compiled application entrypoint. Two things to know at bootstrap:
|
||||
|
||||
1. The command **must follow `pnpm build`** — the `start` script executes the
|
||||
compiled artifact in `dist/`, it does not compile first.
|
||||
2. `apps/server` is currently a **bootstrap placeholder**: its entrypoint is an
|
||||
empty module, so starting it loads the module and exits cleanly (exit 0)
|
||||
without opening an HTTP port yet. The real Fastify 5 application shell —
|
||||
which turns this into a serving process — lands in a later story; the
|
||||
`start` command shape above stays the same once it does.
|
||||
|
||||
To run the compiled output of any other workspace package directly:
|
||||
|
||||
```sh
|
||||
node <package-dir>/dist/index.js # e.g. node packages/core/dist/index.js
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```sh
|
||||
pnpm test
|
||||
```
|
||||
|
||||
`pnpm test` runs the `node:test` suites under `tests/` (currently
|
||||
`tests/architecture-import.test.mjs`, 10 tests) with zero extra dependencies.
|
||||
This is also the suite that enforces the dependency-boundary rule.
|
||||
|
||||
## Smoke check from a clean clone
|
||||
|
||||
```sh
|
||||
git clone https://git.stevanovic.co.uk/Fabrika/PersonalBlog.git && cd PersonalBlog
|
||||
corepack enable
|
||||
pnpm install --frozen-lockfile # exit 0, lockfile untouched
|
||||
pnpm build # 3/3 packages emit dist/, exit 0
|
||||
pnpm typecheck # 3/3 packages pass --noEmit, exit 0
|
||||
pnpm test # 10/10 pass, exit 0
|
||||
pnpm --filter @personal-blog/server start # loads compiled server entrypoint, exit 0
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause / fix |
|
||||
| --- | --- |
|
||||
| `pnpm: command not found` | Corepack shims not activated — run `corepack enable`, or prefix commands with `corepack pnpm ...`. |
|
||||
| `ERR_PNPM_OUTDATED_LOCKFILE` | `pnpm-lock.yaml` is out of date with the manifests. Run `pnpm install` (unfrozen) and commit the lockfile update. |
|
||||
| Node version warnings / unexpected behavior | Use Node 24.x to match CI (e.g. via `nvm`, `fnm` or another version manager). A hard `engines` restriction is tracked as E00-S01-T08. |
|
||||
| `start` exits immediately with no output | Expected at bootstrap — the server entrypoint is a placeholder module; the Fastify 5 shell is a later story (see [Run](#run)). |
|
||||
| `.env` files | `.env`/`.env.*` are git-ignored; a committed `.env.example` template lands with the environment story (E00-S04). |
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Root build/test/typecheck **script wiring** — covered by E00-S01-T05; only
|
||||
usage is documented here.
|
||||
- **Docker Compose baseline** and container smoke tests — E00-S02.
|
||||
- PostgreSQL adapter, migration runner and other runtime services — later E00
|
||||
stories.
|
||||
Reference in New Issue
Block a user