# 03 · 项目骨架搭建 ## 做什么 创建 monorepo 骨架: ``` tts-like/ ├── packages/ │ ├── protocol/ 共享类型 │ ├── engine/ boardgame.io 封装 + 游戏定义 │ ├── ui/ React 原语 │ └── server/ 中转服务器 ├── apps/ │ ├── web/ Vite + React SPA │ └── desktop/ Tauri 壳 ├── docs/ └── 配置文件 ``` ## 遇到什么问题 ### 问题 1:pnpm 不在 PATH `which pnpm` 报 NOT FOUND,但 `corepack` 路径下能找到 shim。 **解决**:每次 Bash 命令前先 export PATH: ```bash export PATH="/home/e2hang/.nvm/versions/node/v22.22.2/lib/node_modules/corepack/shims:$PATH" ``` ### 问题 2:boardgame.io 0.50.2 发布的类型导出不全 `Game` / `Ctx` 等类型**只在主 entry**(`boardgame.io`,指向 `dist/types/src/types.d.ts`)里有。子包 `/react` `/server` `/multiplayer` 只导出运行时值。 **解决**: ```ts // ✅ 正确 import type { Game, Ctx } from 'boardgame.io'; // 类型从主 entry import { Client } from 'boardgame.io/react'; // 运行时从子包 ``` ### 问题 3:boardgame.io move 用 Immer 风格 最初写 War 游戏时用 return-style,typecheck 报错。 **解决**:直接 mutate G: ```ts // ✅ 正确 moves: { flip: ({ G, ctx }) => { G.p0Deck = G.p0Deck.slice(0, -1); // Immer 在内部处理 } } ``` ### 问题 4:pnpm workspace exports 模式 子包 `import '@tts-like/engine/games/war'` 解析不到。 **解决**:`engine/package.json` 加 `exports` 字段: ```json "exports": { ".": "./src/index.ts", "./games/*": "./src/games/*.ts" } ``` 注意:wildcard 后缀必须带 `.ts`,否则解析出来没扩展名。 ### 问题 5:Vite 项目需要 `vite-env.d.ts` 否则 `import.meta.env` 报 `Property 'env' does not exist on type 'ImportMeta'`。 **解决**:在 `apps/web/src/vite-env.d.ts` 写: ```ts /// ``` ## 怎么解决 分三步走: 1. **建目录 + 写包结构**(手写 + Write) 2. **`pnpm install`**(312 个依赖,19 秒) 3. **逐包 `tsc --noEmit`**(按 protocol → engine → ui → server → web 顺序) ### 关键决策:engine 用 `import type` 而不是 `export type` ```ts // ❌ 不好用:在严格 TS 配置下 export type 不一定让名字进入本地 scope export type { Game, Ctx } from 'boardgame.io'; // ✅ 工作中 import type { Game as BgGame } from 'boardgame.io'; export type Game = BgGame; ``` ## 成果 - 6 个包全部通过 `tsc --noEmit` - 初始 commit `c5e5515 chore: scaffold monorepo skeleton` - Memory 写入 6 条踩坑记录 ## 关联 - [04-ui-primitive-impl.md](./04-ui-primitive-impl.md) — 骨架就绪后开始填 UI - [lessons-learned.md §1-6](./lessons-learned.md) — 本阶段踩坑详细记录