Per user request: split the development process into per-topic docs under docs/dev-log/. Each entry follows the same structure: What was asked → Problems → How solved Files: - README.md index - 01-initial-scope-and-design.md - 02-ui-primitives-api-design.md - 03-monorepo-scaffold.md - 04-ui-primitive-impl.md - 05-drag-and-drop.md - 06-three-games.md - 07-bugfixes-round-1.md - lessons-learned.md all gotchas consolidated - decisions.md locked decisions with dates Total: 1071 lines across 10 files.
2.8 KiB
2.8 KiB
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:
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 只导出运行时值。
解决:
// ✅ 正确
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:
// ✅ 正确
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 字段:
"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 写:
/// <reference types="vite/client" />
怎么解决
分三步走:
- 建目录 + 写包结构(手写 + Write)
pnpm install(312 个依赖,19 秒)- 逐包
tsc --noEmit(按 protocol → engine → ui → server → web 顺序)
关键决策:engine 用 import type 而不是 export type
// ❌ 不好用:在严格 TS 配置下 export type 不一定让名字进入本地 scope
export type { Game, Ctx } from 'boardgame.io';
// ✅ 工作中
import type { Game as BgGame } from 'boardgame.io';
export type Game<G = any> = BgGame<G>;
成果
- 6 个包全部通过
tsc --noEmit - 初始 commit
c5e5515 chore: scaffold monorepo skeleton - Memory 写入 6 条踩坑记录
关联
- 04-ui-primitive-impl.md — 骨架就绪后开始填 UI
- lessons-learned.md §1-6 — 本阶段踩坑详细记录