Skip to content

Commit 8b28fa2

Browse files
os-zhuangclaude
andauthored
refactor(docs): take apps/docs out of the pnpm workspace (#502)
The docs app was the one thing making this a monorepo, and it earned nothing for it: no shared code, no cross-package imports, its own framework, its own deploy target. What it did do was break every pnpm install inside a StackBlitz WebContainer — `ENOENT: apps/docs/.npmrc`, then `ENOENT: apps/docs/node_modules` — because pnpm's workspace layout and the sandbox fs disagree. The escape hatch, `--ignore-workspace`, is incompatible with `--frozen-lockfile` precisely because the lockfile is a workspace lockfile. So: delete pnpm-workspace.yaml, give apps/docs its own pnpm-lock.yaml, its own .npmrc (same settings — the app was relying on the root's `shamefully-hoist`), and pin `packageManager` so Vercel resolves pnpm 10 from the app directory. The root lockfile is regenerated with a single importer. Two things this surfaced, both fixed here: - `build` now runs `fumadocs-mdx` before `next build`. Vercel installs with `--ignore-scripts` (its own vercel.json says so), and a cold standalone install + build failed on `Cannot find module 'fumadocs-mdx:collections/ server'` — the generated `.source` has to exist before Turbopack collects page data. Generating it in `build` makes the cold path deterministic rather than dependent on a previous run's leftovers. - `turbopack.root` stays unset. Pinning it to apps/docs looks right for a standalone app and breaks 231 modules: content lives at the repo root (`../../../content/**`), so the Turbopack root must stay above this app. The resulting two-lockfile warning is expected; there's a comment saying so. Verified locally by rehearsing Vercel's exact sequence in apps/docs: `rm -rf node_modules && pnpm install --ignore-scripts` → `pnpm build` → 329 static pages, exit 0, from a clean tree. Root `pnpm verify` green. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7cc6574 commit 8b28fa2

8 files changed

Lines changed: 4581 additions & 4010 deletions

File tree

.claude/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"name": "docs",
1313
"runtimeExecutable": "pnpm",
14-
"runtimeArgs": ["--filter", "@hotcrm/docs", "dev"],
14+
"runtimeArgs": ["-C", "apps/docs", "dev"],
1515
"port": 3210,
1616
"autoPort": true
1717
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ hotcrm/
136136
│ ├── profiles/, sharing/ # security
137137
│ ├── translations/ # en / zh-CN / es-ES / ja-JP
138138
│ └── data/ # seed data
139-
├── apps/docs/ # Fumadocs app
139+
├── apps/docs/ # Fumadocs site — standalone, own lockfile (not a pnpm workspace member)
140140
└── content/docs/ # Documentation content
141141
```
142142

@@ -146,7 +146,7 @@ Every file follows the **`<entity>.<kind>.ts`** convention. The `crm_` prefix on
146146

147147
## 📚 Documentation
148148

149-
- **Live docs:** start `pnpm --filter @hotcrm/docs dev -- -p 3001`, then open <http://localhost:3001/docs>
149+
- **Live docs:** start `pnpm -C apps/docs install && pnpm -C apps/docs dev -p 3001`, then open <http://localhost:3001/docs>
150150
- **For business users:** Sales, Service, Marketing, Revenue, AI Copilot guides
151151
- **For developers:** Architecture, Customization, API reference, Testing & CI
152152
- **For publishers:** Marketplace publishing guide

apps/docs/.npmrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
auto-install-peers=false
2+
engine-strict=true
3+
node-linker=hoisted
4+
shamefully-hoist=true

apps/docs/next.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ const withMDX = createMDX();
55
/** @type {import('next').NextConfig} */
66
const config = {
77
reactStrictMode: true,
8+
// Docs content lives at the repo root (`content/`), outside this app, so the
9+
// Turbopack root has to stay the repo root — Next infers it from the root
10+
// lockfile. Pinning `turbopack.root` here breaks every `../../../content`
11+
// import, and the two-lockfile warning it silences is expected now that this
12+
// app is not a pnpm workspace member.
813
async rewrites() {
914
return [
1015
{

apps/docs/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
"name": "@hotcrm/docs",
33
"version": "1.0.0",
44
"private": true,
5+
"packageManager": "pnpm@10.33.0",
56
"scripts": {
6-
"build": "next build",
7+
"build": "fumadocs-mdx && next build",
78
"dev": "next dev",
89
"start": "next start",
910
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit"
@@ -29,4 +30,4 @@
2930
"tailwindcss": "^4.3.1",
3031
"typescript": "^5.9.3"
3132
}
32-
}
33+
}

0 commit comments

Comments
 (0)