chore(docker,ci): Dockerfile 与 CI 切换 pnpm workspace,docs 同步
Dockerfile: - Node 22 安装段追加 corepack enable + pnpm 11.8.0 - 缓存层从'只 tiptap 的 package.json'扩展为整个 workspace (libs/package.json + pnpm-workspace.yaml + pnpm-lock.yaml + 4 lib manifest), npm ci 改为 pnpm install --frozen-lockfile,覆盖全部 4 个 lib 的 Docker 层缓存 - 构建步骤 make build-editor 改为 make build-libs Gitea CI: - check job 的 Install Node 步骤加装 pnpm,新增 Biome lint 步骤 (cd libs && pnpm install --frozen-lockfile && pnpm exec biome check .) - build job 同步装 pnpm,make build 不变(Makefile 已改用 workspace) .dockerignore: 补齐其余 3 个 lib 的 public 产物 + workspace node_modules 模式 AGENTS.md: Development Commands 删 make clippy、新增 make lint/make fix 说明; Prerequisites 补 Biome;libs 段改为 pnpm workspace 模型;修正文档漂移 (tt-reveal→tt-expand,eval→Reflect::get)
This commit is contained in:
parent
a47e1e6027
commit
2a7f7be738
@ -3,12 +3,16 @@ target/
|
||||
dist/
|
||||
.dioxus/
|
||||
node_modules/
|
||||
libs/tiptap-editor/node_modules/
|
||||
libs/node_modules/
|
||||
libs/*/node_modules/
|
||||
|
||||
# Generated assets are rebuilt inside the container.
|
||||
public/style.css
|
||||
public/highlight.css
|
||||
public/tiptap/
|
||||
public/codemirror/
|
||||
public/lightbox/
|
||||
public/yggdrasil-core/
|
||||
|
||||
# Uploads directory is created at runtime; only keep the gitkeep marker.
|
||||
uploads/*
|
||||
|
||||
@ -35,10 +35,11 @@ jobs:
|
||||
done
|
||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Install Node.js
|
||||
- name: Install Node.js & pnpm
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y nodejs npm
|
||||
npm install -g pnpm
|
||||
|
||||
- name: Install Rust target
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
@ -55,6 +56,9 @@ jobs:
|
||||
- name: Run Clippy
|
||||
run: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
- name: Biome lint (libs)
|
||||
run: cd libs && pnpm install --frozen-lockfile && pnpm exec biome check .
|
||||
|
||||
- name: Run tests
|
||||
run: cargo test --all-features
|
||||
|
||||
@ -89,10 +93,11 @@ jobs:
|
||||
done
|
||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Install Node.js
|
||||
- name: Install Node.js & pnpm
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y nodejs npm
|
||||
npm install -g pnpm
|
||||
|
||||
- name: Install Rust target
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
|
||||
34
AGENTS.md
34
AGENTS.md
@ -14,35 +14,37 @@
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
make dev # 增量构建 4 个 libs + tailwindcss watch + dx serve (needs PostgreSQL, SSR_CACHE_SECS=0)
|
||||
make build # build-editor → build-lightbox → build-core → build-codemirror → highlight-css → tailwindcss → doc → dx build --release → restore-webp
|
||||
make dev # 增量构建 4 个 libs (pnpm -r run build) + tailwindcss watch + dx serve (needs PostgreSQL, SSR_CACHE_SECS=0)
|
||||
make build # pnpm install → build-libs → highlight-css → tailwindcss → doc → dx build --release → restore-webp
|
||||
make build-linux # 客户端 + 服务端分离构建,target x86_64-unknown-linux-musl
|
||||
make build-freebsd # cross-compile FreeBSD x86_64 server binary (clang + lld + sysroot, via cargo, not dx)
|
||||
make freebsd-sysroot # download/extract FreeBSD base.txz → .freebsd-sysroot/ (idempotent)
|
||||
make css # one-shot Tailwind build
|
||||
make css-watch # Tailwind watch mode
|
||||
make test # cargo test + pnpm test in all 4 libs (tiptap-editor / lightbox / yggdrasil-core / codemirror-editor)
|
||||
make test # cargo test + pnpm -r run test (all 4 libs: tiptap-editor / lightbox / yggdrasil-core / codemirror-editor)
|
||||
make doc # cargo doc (ayu 主题) → 拷贝到 public/doc/,随 build 发布
|
||||
make doc-open # 同 doc,生成后自动用浏览器打开(本地预览,不拷贝)
|
||||
make clippy # cargo clippy --all-targets --all-features -- -D warnings (严格模式,warning 即失败)
|
||||
make fix # cargo fix --allow-dirty
|
||||
make clean # cargo clean + rm public/{style.css,highlight.css,doc} + rm -rf uploads/.cache
|
||||
make lint # Biome check (libs) + cargo clippy (严格模式,warning 即失败)
|
||||
make fix # biome format --write (libs) + cargo fix --allow-dirty
|
||||
make clean # cargo clean + rm public/{style.css,highlight.css,doc} + rm -rf uploads/.cache + rm -rf libs/node_modules libs/*/node_modules
|
||||
```
|
||||
|
||||
**Build order matters**: `make build` runs all 4 lib builds → `highlight-css` (`cargo run --bin generate_highlight_css`) → `tailwindcss --minify` → `doc` → `dx build --release` → `restore-webp`. Do not run `dx build --release` alone.
|
||||
**Build order matters**: `make build` runs `pnpm install --frozen-lockfile` (in `libs/`) → `build-libs` (`pnpm -r run build`, all 4 libs in parallel) → `highlight-css` (`cargo run --bin generate_highlight_css`) → `tailwindcss --minify` → `doc` → `dx build --release` → `restore-webp`. Do not run `dx build --release` alone.
|
||||
|
||||
**`restore-webp` workaround**: dx build 0.7.9 re-encodes `public/*.webp` into VP8L lossless stills (drops animation frames, 7-8× larger), contradicting the "verbatim copy" promise. `restore-webp` overwrites `.webp` in `target/dx/**/web/public/` from source `public/`. SVG/ICO are unaffected. Remove once upstream fixes it.
|
||||
|
||||
**Libs use pnpm, not npm**: every lib has `pnpm-lock.yaml`; Makefile recipes use `pnpm ci`/`pnpm install`/`pnpm run`. The `*-incremental` targets skip install (assume `node_modules` present) for faster `make dev`.
|
||||
**JS workspace lives under `libs/`**: `libs/` is a pnpm workspace — root `libs/package.json` hoists the 4 shared devDeps (`happy-dom`/`typescript`/`vite`/`vitest`) + Biome; `libs/pnpm-workspace.yaml` lists `libs/*` packages; `libs/pnpm-lock.yaml` is the single lockfile. First-time setup: `cd libs && pnpm install`. All Makefile recipes `cd libs && pnpm ...`. Build a single lib: `make build-editor` (≈ `cd libs && pnpm --filter @yggdrasil/tiptap-editor run build`).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Rust 1.95+ with `wasm32-unknown-unknown` target
|
||||
- `dx` CLI (`cargo install dioxus-cli`)
|
||||
- `tailwindcss` CLI v4 — install via `npm install -g @tailwindcss/cli` (v4 splits the CLI into its own package; the `tailwindcss` core package has no `bin`), or use the standalone binary
|
||||
- `pnpm` (all 4 `libs/` subprojects use it)
|
||||
- `pnpm` 11+ (`libs/` is a pnpm workspace; vendored as a `devDependency` via corepack, but a global install is convenient)
|
||||
- PostgreSQL running locally
|
||||
|
||||
**Biome** (linter + formatter for `libs/`) is a `devDependency` in `libs/package.json` — no separate install. `make lint` runs `biome check` + `cargo clippy`; `make fix` runs `biome format --write` + `cargo fix`. Config in `libs/biome.json`.
|
||||
|
||||
## Environment
|
||||
|
||||
Create `.env` (not committed):
|
||||
@ -152,16 +154,16 @@ src/codemirror_bridge.rs — wasm-bindgen bindings for CodeMirror editor (mirror
|
||||
|
||||
## Frontend Lib Subprojects
|
||||
|
||||
Four Vite-built IIFE libraries under `libs/`, each with `pnpm-lock.yaml`. Built artifacts go to `public/<name>/` — **do not edit `public/<name>/` files; they are build artifacts**. Each `build` script is `tsc --noEmit && vite build` (type-check before bundle). Output is IIFE because Dioxus `[web.resource] script` injects bare `<script src>` without `type="module"` support. Registered globally in `Dioxus.toml` `script`/`style` arrays.
|
||||
Four Vite-built IIFE libraries under `libs/`, managed as a **pnpm workspace** (single `libs/pnpm-lock.yaml`, shared `libs/tsconfig.base.json` + `libs/biome.json`, hoisted devDeps). Built artifacts go to `public/<name>/` — **do not edit `public/<name>/` files; they are build artifacts**. Each `build` script is `tsc --noEmit && vite build` (type-check before bundle). Output is IIFE because Dioxus `[web.resource] script` injects bare `<script src>` without `type="module"` support. Registered globally in `Dioxus.toml` `script`/`style` arrays.
|
||||
|
||||
| Lib | Output dir | Exposes | Wiring |
|
||||
| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `libs/tiptap-editor/` | `public/tiptap/` (`editor.js`/`.css`/`.map`) | `window.TiptapEditor` | wasm-bindgen via `src/tiptap_bridge.rs` — injects `Closure` callbacks (`onUpdate`/`onReady`/`onUploadEvent`/`onImageUpload`) into `TiptapEditor.create`, holds instance + closures in `EditorHandle` (Drop → `destroy()`). No `js_sys::eval`, no `window` globals, no polling. |
|
||||
| `libs/codemirror-editor/` | `public/codemirror/` (`editor.js`/`.map`, **no CSS**) | `window.CodeMirrorEditor` (object literal `{ create }`) + `window.EditorOptions` (class, survives TS erasure) | `src/codemirror_bridge.rs` mirrors tiptap — `get_module()` uses `Reflect::get` + `unchecked_into` (object literal, NOT a constructor extern). Themes are JS `Extension`s from `@catppuccin/codemirror` (Latte/Mocha), hot-swapped via `Compartment.reconfigure`. |
|
||||
| `libs/lightbox/` | `public/lightbox/` (`lightbox.js`/`.css`/`.map`) | self-initializing IIFE | **Not** wasm-bindgen. `src/components/post/post_content.rs` sets `window.__lightboxSelectors` before load; IIFE tail reads it and self-initializes. Direct fallback call if already loaded. |
|
||||
| `libs/yggdrasil-core/` | `public/yggdrasil-core/` (`yggdrasil-core.js`/`.css`/`.map`) | `window.__initPostContent`, `window.__startThemeTransition` | Designated home for all new core JS — add here, not to `public/js/`. Rust calls entry points via `js_sys::eval("window.__xxx(...)")` guarded by `if (window.__xxx)`. Theme reveal uses View Transitions API (`startViewTransition` + `@keyframes tt-reveal` `clip-path` expand); falls back to instant switch when VT / `prefers-reduced-motion`. |
|
||||
| `libs/yggdrasil-core/` | `public/yggdrasil-core/` (`yggdrasil-core.js`/`.css`/`.map`) | `window.__initPostContent`, `window.__startThemeTransition` | Designated home for all new core JS — add here, not to `public/js/`. Rust calls entry points via `js_sys::Reflect::get` + `Function::apply` (no `js_sys::eval`), silently no-oping if undefined. Theme reveal uses View Transitions API (`startViewTransition` + `@keyframes tt-expand` `clip-path` expand); falls back to instant switch when VT / `prefers-reduced-motion`. |
|
||||
|
||||
Run a single lib's tests: `cd libs/<name> && pnpm test` (Vitest + happy-dom). Watch mode: `pnpm test:watch`.
|
||||
Run a single lib's tests: `cd libs && pnpm --filter @yggdrasil/<name> test` (Vitest + happy-dom). Watch mode: append `-- test:watch`.
|
||||
|
||||
## Database Management (`/admin/system`)
|
||||
|
||||
@ -195,9 +197,9 @@ Admin area at `/admin/system` (menu "系统") with 5 tabs: 数据库状态 / 服
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
make test # cargo test (Rust) + pnpm test in all 4 libs
|
||||
make clippy # cargo clippy --all-targets --all-features -- -D warnings
|
||||
dx check # Dioxus type-check (catches component/Router issues)
|
||||
make test # cargo test (Rust) + pnpm -r run test in all 4 libs
|
||||
make lint # Biome check (libs) + cargo clippy --all-targets --all-features -- -D warnings
|
||||
dx check # Dioxus type-check (catches component/Router issues)
|
||||
```
|
||||
|
||||
**Must verify both targets**: This is a fullstack project — the server binary and the WASM frontend are two separate compilation targets with different features (`--all-features` enables `web`+`server`; the WASM bundle uses `--no-default-features --features web`). A change that compiles on one target can fail on the other. **`cargo build --all-features` alone is NOT sufficient** — it only builds the server binary. Before considering work done, compile the WASM target too:
|
||||
@ -230,7 +232,7 @@ Most Rust tests use `#[cfg(all(test, feature = "server"))]` — they only run wh
|
||||
- `public/{tiptap,codemirror,lightbox,yggdrasil-core}/` — Vite build outputs
|
||||
- `public/doc/` — cargo doc output (copied by `make doc`)
|
||||
- `/dist`, `/.dioxus`, `/target`, `/static`
|
||||
- `node_modules` (inside each `libs/` subproject)
|
||||
- `libs/node_modules/` + `libs/*/node_modules/` — pnpm workspace store + symlinks
|
||||
- `uploads/.cache/` — image processing disk cache
|
||||
- `backups/` — admin DB backup files
|
||||
- `.freebsd-sysroot/` — FreeBSD cross-compile sysroot (machine-local)
|
||||
|
||||
22
Dockerfile
22
Dockerfile
@ -24,7 +24,7 @@ RUN apt-get update \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js 22 (required by Tailwind CSS v4 and the Tiptap editor build).
|
||||
# Install Node.js 22 (required by Tailwind CSS v4 and the JS libs build) + pnpm.
|
||||
RUN mkdir -p /etc/apt/keyrings \
|
||||
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
|
||||
@ -32,7 +32,9 @@ RUN mkdir -p /etc/apt/keyrings \
|
||||
> /etc/apt/sources.list.d/nodesource.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& corepack enable \
|
||||
&& corepack prepare pnpm@11.8.0 --activate
|
||||
|
||||
# Add the targets used by Dioxus fullstack builds.
|
||||
RUN rustup target add wasm32-unknown-unknown x86_64-unknown-linux-musl
|
||||
@ -48,16 +50,22 @@ RUN curl -fsSL "https://github.com/tailwindlabs/tailwindcss/releases/download/v$
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# Cache the Tiptap editor's node_modules by copying only package manifests first.
|
||||
COPY libs/tiptap-editor/package*.json libs/tiptap-editor/
|
||||
RUN cd libs/tiptap-editor && npm ci --include=dev
|
||||
# Cache the pnpm workspace node_modules by copying only package manifests first.
|
||||
# Copying all 4 libs' manifests + the workspace root lets pnpm install everything
|
||||
# in one shot; this layer is reused as long as the manifests don't change.
|
||||
COPY libs/package.json libs/pnpm-workspace.yaml libs/pnpm-lock.yaml libs/
|
||||
COPY libs/tiptap-editor/package.json libs/tiptap-editor/
|
||||
COPY libs/codemirror-editor/package.json libs/codemirror-editor/
|
||||
COPY libs/lightbox/package.json libs/lightbox/
|
||||
COPY libs/yggdrasil-core/package.json libs/yggdrasil-core/
|
||||
RUN cd libs && pnpm install --frozen-lockfile
|
||||
|
||||
# Copy the rest of the source tree and build everything.
|
||||
COPY . .
|
||||
|
||||
# Build the Tiptap editor, syntax-highlight CSS and Tailwind stylesheet.
|
||||
# Build all 4 JS libs, syntax-highlight CSS and Tailwind stylesheet.
|
||||
# These steps produce the contents of the public/ directory.
|
||||
RUN make build-editor && make highlight-css && tailwindcss -i input.css -o public/style.css --minify
|
||||
RUN make build-libs && make highlight-css && tailwindcss -i input.css -o public/style.css --minify
|
||||
|
||||
# Build the client-side Dioxus WASM bundle. We use dx only for the client assets;
|
||||
# dx's linker wrapper is incompatible with a raw static linker, so the server
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user