[{"data":1,"prerenderedAt":2862},["ShallowReactive",2],{"navigation":3,"\u002Fpractice\u002Fscaffolding":189,"\u002Fpractice\u002Fscaffolding-surround":2857},[4,35,57,75,101,123,149,171],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":34},"第 1 章：认识 Claude Code","i-lucide-rocket","\u002Fintro","1.intro",[10,14,18,22,26,30],{"title":11,"path":12,"stem":13},"什么是 Claude Code","\u002Fintro\u002Fwhat-is-claude-code","1.intro\u002F1.what-is-claude-code",{"title":15,"path":16,"stem":17},"Claude Code 与 Copilot、Cursor、Windsurf 的本质区别","\u002Fintro\u002Fvs-competitors","1.intro\u002F2.vs-competitors",{"title":19,"path":20,"stem":21},"AI 编程助手生态全景与选型指南","\u002Fintro\u002Fecosystem-guide","1.intro\u002F3.ecosystem-guide",{"title":23,"path":24,"stem":25},"LLM 的概率本质","\u002Fintro\u002Fllm-probability","1.intro\u002F4.llm-probability",{"title":27,"path":28,"stem":29},"从聊天机器人到 Agent","\u002Fintro\u002Ffrom-chatbot-to-agent","1.intro\u002F5.from-chatbot-to-agent",{"title":31,"path":32,"stem":33},"Claude Code 的 Agentic Loop 全拆解","\u002Fintro\u002Fagentic-loop","1.intro\u002F6.agentic-loop",false,{"title":36,"icon":37,"path":38,"stem":39,"children":40,"page":34},"第 2 章：安装与配置","i-lucide-settings","\u002Fsetup","2.setup",[41,45,49,53],{"title":42,"path":43,"stem":44},"系统要求与安装方式","\u002Fsetup\u002Fsystem-requirements","2.setup\u002F1.system-requirements",{"title":46,"path":47,"stem":48},"认证、登录与多账户管理","\u002Fsetup\u002Fauthentication","2.setup\u002F2.authentication",{"title":50,"path":51,"stem":52},"选择你的界面","\u002Fsetup\u002Fchoose-interface","2.setup\u002F3.choose-interface",{"title":54,"path":55,"stem":56},"Coding Plan","\u002Fsetup\u002Fcoding-plan","2.setup\u002F4.coding-plan",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":34},"第 3 章：快速上手","i-lucide-hand","\u002Fquickstart","3.quickstart",[63,67,71],{"title":64,"path":65,"stem":66},"启动、交互模式与基本命令","\u002Fquickstart\u002Fstartup","3.quickstart\u002F1.startup",{"title":68,"path":69,"stem":70},"让 Claude 理解你的项目","\u002Fquickstart\u002Fcodebase-understanding","3.quickstart\u002F2.codebase-understanding",{"title":72,"path":73,"stem":74},"第一次代码变更","\u002Fquickstart\u002Ffirst-change","3.quickstart\u002F3.first-change",{"title":76,"icon":77,"path":78,"stem":79,"children":80,"page":34},"第 4 章：核心功能","i-lucide-laptop","\u002Fcore-features","4.core-features",[81,85,89,93,97],{"title":82,"path":83,"stem":84},"代码库全景扫描与模块关系分析","\u002Fcore-features\u002Fcodebase-scan","4.core-features\u002F1.codebase-scan",{"title":86,"path":87,"stem":88},"代码编辑与生成","\u002Fcore-features\u002Fedit-generate","4.core-features\u002F2.edit-generate",{"title":90,"path":91,"stem":92},"测试与调试","\u002Fcore-features\u002Ftest-debug","4.core-features\u002F3.test-debug",{"title":94,"path":95,"stem":96},"Git 工作流","\u002Fcore-features\u002Fgit-workflow","4.core-features\u002F4.git-workflow",{"title":98,"path":99,"stem":100},"工具链执行","\u002Fcore-features\u002Ftoolchain","4.core-features\u002F5.toolchain",{"title":102,"icon":103,"path":104,"stem":105,"children":106,"page":34},"第 5 章：进阶配置","i-lucide-wrench","\u002Fadvanced","5.advanced",[107,111,115,119],{"title":108,"path":109,"stem":110},"CLAUDE.md","\u002Fadvanced\u002Fclaude-md","5.advanced\u002F1.claude-md",{"title":112,"path":113,"stem":114},"Skills","\u002Fadvanced\u002Fskills","5.advanced\u002F2.skills",{"title":116,"path":117,"stem":118},"MCP","\u002Fadvanced\u002Fmcp","5.advanced\u002F3.mcp",{"title":120,"path":121,"stem":122},"Hooks 与 Plan 模式","\u002Fadvanced\u002Fhooks-plan","5.advanced\u002F4.hooks-plan",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":34},"第 6 章：实战开发","i-lucide-hammer","\u002Fpractice","6.practice",[129,133,137,141,145],{"title":130,"path":131,"stem":132},"需求分析与架构设计","\u002Fpractice\u002Frequirements-architecture","6.practice\u002F1.requirements-architecture",{"title":134,"path":135,"stem":136},"项目脚手架搭建与技术选型","\u002Fpractice\u002Fscaffolding","6.practice\u002F2.scaffolding",{"title":138,"path":139,"stem":140},"核心功能实现","\u002Fpractice\u002Fcore-features","6.practice\u002F3.core-features",{"title":142,"path":143,"stem":144},"测试覆盖、代码审查与质量调优","\u002Fpractice\u002Ftesting-quality","6.practice\u002F4.testing-quality",{"title":146,"path":147,"stem":148},"部署上线与成果分享","\u002Fpractice\u002Fdeployment","6.practice\u002F5.deployment",{"title":150,"icon":151,"path":152,"stem":153,"children":154,"page":34},"第 7 章：心法层","i-lucide-brain","\u002Fmindset","7.mindset",[155,159,163,167],{"title":156,"path":157,"stem":158},"提示词设计原则","\u002Fmindset\u002Fprompt-design","7.mindset\u002F1.prompt-design",{"title":160,"path":161,"stem":162},"上下文管理策略","\u002Fmindset\u002Fcontext-management","7.mindset\u002F2.context-management",{"title":164,"path":165,"stem":166},"安全与权限控制","\u002Fmindset\u002Fsecurity","7.mindset\u002F3.security",{"title":168,"path":169,"stem":170},"Boris Cherny 的 9 条实战心法与团队推广经验","\u002Fmindset\u002Fboris-cherny-tips","7.mindset\u002F4.boris-cherny-tips",{"title":172,"icon":173,"path":174,"stem":175,"children":176,"page":34},"附录","i-lucide-paperclip","\u002Fappendix","8.appendix",[177,181,185],{"title":178,"path":179,"stem":180},"常用命令速查表","\u002Fappendix\u002Fa.command-cheatsheet","8.appendix\u002Fa.command-cheatsheet",{"title":182,"path":183,"stem":184},"AI 核心术语汇编","\u002Fappendix\u002Fb.ai-terminology","8.appendix\u002Fb.ai-terminology",{"title":186,"path":187,"stem":188},"资源链接与延伸阅读","\u002Fappendix\u002Fc.resources","8.appendix\u002Fc.resources",{"id":190,"title":134,"body":191,"description":657,"extension":2851,"links":2852,"meta":2853,"navigation":892,"path":135,"seo":2855,"stem":136,"__hash__":2856},"docs\u002F6.practice\u002F2.scaffolding.md",{"type":192,"value":193,"toc":2818},"minimark",[194,209,216,219,224,229,234,237,264,293,297,304,473,476,479,562,565,569,575,642,645,651,779,790,793,797,802,806,809,817,836,840,843,849,852,983,986,990,993,999,1002,1008,1011,1015,1021,1027,1041,1045,1048,1072,1079,1259,1262,1265,1271,1274,1276,1280,1285,1289,1296,1383,1386,1389,1480,1483,1487,1490,1496,1499,1503,1506,1526,1529,1532,1538,1541,1545,1548,1580,1583,1699,1702,1704,1708,1713,1717,1722,1728,1733,1739,1744,1750,1755,1761,1766,1772,1777,1780,1922,1927,1933,1936,1940,1943,1949,1956,1960,1963,2204,2211,2217,2224,2231,2362,2393,2397,2422,2428,2439,2441,2445,2450,2454,2457,2468,2475,2479,2482,2519,2522,2526,2529,2555,2558,2562,2569,2573,2576,2681,2688,2691,2694,2708,2711,2714,2814],[195,196,197,201],"blockquote",{},[198,199,200],"p",{},"给产品经理：上一节我们把\"想做什么\"翻译成了 SPEC、ARCHITECTURE 与 ROADMAP 三份文档。这一节要回答的问题是——这堆文字怎么变成第一个能跑起来的工程？答案就是脚手架（Scaffolding）。脚手架不是一份\"代码\"，而是一组初始化的目录、依赖、配置文件，它决定了团队接下来几个月每天敲下的每一行代码长什么样。技术选型，则是决定脚手架\"用什么砖\"的过程。",[198,202,203,204,208],{},"给工程师：6.1 输出了 SPEC.md \u002F ARCHITECTURE.md \u002F ROADMAP.md，但从架构图到 ",[205,206,207],"code",{},"pnpm dev"," 跑起来之间有一道鸿沟——脚手架与版本锁定。本章重点拆解 2026 年主流脚手架的演进、Claude Code 在选型与初始化阶段的协作姿势，以及如何把团队规范写成 CLAUDE.md 和 Skills，让\"第一行代码\"开始就长在团队基因里。",[198,210,211,212,215],{},"承接 6.1，需求与架构方案已经躺在 ",[205,213,214],{},"docs\u002F"," 目录里。接下来一周，团队每天会被问到的不是\"做什么\"，而是\"用 Vite 还是 Webpack\"、\"Pinia 还是 Zustand\"、\"PostgreSQL 还是 MySQL\"。这些问题如果在脚手架阶段没想清楚，三个月后会以\"重构\"或\"技术债\"的形式收回利息。本节会把脚手架与技术选型当作一个完整的工程动作来讲，并演示 Claude Code 在每一步如何降低决策成本。",[198,217,218],{},"为了让阅读节奏更明确，本章会按\"演进 → 协作 → 方法论 → 实战 → 风险\"五段递进。前两节铺垫认知，第三节给可复用的判断框架，第四节用一个 30 分钟的真实回放把所有概念串起来，最后一节列出工程师不能让渡的决策与 AI 自动化的反噬。读完本章你应当能独立完成：让 Claude 推荐脚手架候选、用 Plan 模式控制初始化节奏、把团队规范写成可执行的 CLAUDE.md 与 Skills、识别选型阶段的常见陷阱。",[220,221,223],"h2",{"id":222},"一脚手架工具的现代演进","一、脚手架工具的现代演进",[195,225,226],{},[198,227,228],{},"给产品经理：脚手架（Scaffolding）就像装修前师傅按户型图搭的钢架，决定了哪里是承重墙、哪里能改。早些年前端工程师手动写一堆配置，后来出现一键生成命令，再后来连\"一键\"都被 AI 接管。理解这段演进，有助于你判断技术方案是不是\"现代\"。",[230,231,233],"h3",{"id":232},"_11-从-create-react-app-到-viteturborepo","1.1 从 create-react-app 到 Vite\u002FTurborepo",[198,235,236],{},"回溯一下时间线：",[238,239,240,248,255,258,261],"ul",{},[241,242,243,244,247],"li",{},"2016 年，Facebook 推出 ",[205,245,246],{},"create-react-app","（CRA），用一条命令完成 React 项目初始化。它隐藏了 Webpack、Babel 配置，让上手门槛骤降。代价是配置黑箱、构建慢、很难在不\"eject\"的情况下定制。",[241,249,250,251,254],{},"2017 年，Vue 团队推出 ",[205,252,253],{},"vue-cli","，思路相似：模板化项目、可选 preset。",[241,256,257],{},"2020 年，Vite 由尤雨溪发起，利用浏览器原生 ES Module 与 esbuild\u002FRollup，把开发服务器冷启动从十几秒压到几百毫秒。这种数量级的提速直接终结了\"create-react-app 时代\"。React 官方文档此后也不再推荐 CRA，转而引导用户使用 Vite、Next.js、Remix 等元框架。",[241,259,260],{},"2022 年起，Turborepo、Nx、Moon 等 Monorepo 编排工具兴起，把\"脚手架\"从单包扩展到多包，加入远程缓存、增量构建、任务图。",[241,262,263],{},"2024 年起，Bun、Deno、Rolldown、Rspack 等新一代运行时和打包器陆续进入生产，业界普遍认为 esbuild\u002FRollup 仍是当前生态最主流的组合，但 Rust 系工具链增长迅速。",[198,265,266,267,270,271,274,275,274,278,274,281,274,284,274,287,274,289,292],{},"时间走到 2026 年，\"脚手架\"这个词的含义已经从\"生成模板\"扩展为\"项目初始化 + 任务编排 + 缓存策略 + 类型与 Lint 体系 + AI 协作约定\"。一个现代脚手架的产物，往往不只是一个 ",[205,268,269],{},"package.json","，而是一整套包括 ",[205,272,273],{},"pnpm-workspace.yaml","、",[205,276,277],{},"turbo.json",[205,279,280],{},"tsconfig.base.json",[205,282,283],{},".eslintrc",[205,285,286],{},".prettierrc",[205,288,108],{},[205,290,291],{},".claude\u002F"," 在内的\"工程身份证\"。",[230,294,296],{"id":295},"_12-不同领域的主流脚手架前端后端monorepocli","1.2 不同领域的主流脚手架（前端\u002F后端\u002FMonorepo\u002FCLI）",[198,298,299,300,303],{},"下表整理 2026 年常见脚手架（具体版本号在使用前请用 ",[205,301,302],{},"npm view \u003Cpkg> version"," 校验）：",[305,306,307,323],"table",{},[308,309,310],"thead",{},[311,312,313,317,320],"tr",{},[314,315,316],"th",{},"领域",[314,318,319],{},"主流脚手架 \u002F 命令",[314,321,322],{},"适用场景",[324,325,326,346,361,383,397,408,431,442,456],"tbody",{},[311,327,328,332,343],{},[329,330,331],"td",{},"前端 SPA",[329,333,334,274,337,274,340],{},[205,335,336],{},"pnpm create vite",[205,338,339],{},"pnpm create vue",[205,341,342],{},"pnpm create next-app",[329,344,345],{},"单页或多页前端应用",[311,347,348,351,358],{},[329,349,350],{},"前端元框架",[329,352,353,354,357],{},"Nuxt（",[205,355,356],{},"pnpm create nuxt-app","）、Next.js、Remix、Astro、SvelteKit",[329,359,360],{},"含 SSR\u002FSSG\u002F路由约定",[311,362,363,366,380],{},[329,364,365],{},"Node 后端",[329,367,368,274,371,274,374,274,377],{},[205,369,370],{},"pnpm create fastify",[205,372,373],{},"nest new",[205,375,376],{},"pnpm create hono",[205,378,379],{},"express-generator",[329,381,382],{},"API 服务、BFF",[311,384,385,388,394],{},[329,386,387],{},"全栈",[329,389,390,393],{},[205,391,392],{},"create-t3-app","、Nuxt、SvelteKit、Remix、Redwood",[329,395,396],{},"全栈一体化",[311,398,399,402,405],{},[329,400,401],{},"Monorepo",[329,403,404],{},"Turborepo、Nx、Moon、pnpm workspaces、Bun workspaces",[329,406,407],{},"多包项目编排",[311,409,410,413,428],{},[329,411,412],{},"CLI 工具",[329,414,415,274,418,421,422,274,425],{},[205,416,417],{},"oclif",[205,419,420],{},"commander"," 模板、",[205,423,424],{},"citty",[205,426,427],{},"unjs\u002Fc12",[329,429,430],{},"写命令行工具",[311,432,433,436,439],{},[329,434,435],{},"桌面端",[329,437,438],{},"Tauri、Electron Forge、Electron Vite",[329,440,441],{},"桌面应用",[311,443,444,447,453],{},[329,445,446],{},"移动端",[329,448,449,450],{},"Expo、React Native CLI、",[205,451,452],{},"flutter create",[329,454,455],{},"iOS\u002FAndroid",[311,457,458,461,470],{},[329,459,460],{},"AI 应用",[329,462,463,464,274,467],{},"LangChain CLI、",[205,465,466],{},"create-llama",[205,468,469],{},"create-vercel-ai",[329,471,472],{},"LLM 驱动应用",[198,474,475],{},"PM 需要记的不是命令，而是这一层判断：**做的是 SPA 还是需要 SEO？是单包还是多包？团队是 TS\u002FJS 为主还是混合 Python？**这三个问题决定了脚手架的大方向。",[198,477,478],{},"为了便于和工程师沟通，下面给一组\"翻译卡\"，把 PM 常说的需求术语映射到对应的脚手架选项：",[305,480,481,494],{},[308,482,483],{},[311,484,485,488,491],{},[314,486,487],{},"PM 用语",[314,489,490],{},"工程师听到的",[314,492,493],{},"常见脚手架",[324,495,496,507,518,529,540,551],{},[311,497,498,501,504],{},[329,499,500],{},"\"页面要被搜索引擎收录\"",[329,502,503],{},"SSR \u002F SSG",[329,505,506],{},"Nuxt、Next.js、Astro",[311,508,509,512,515],{},[329,510,511],{},"\"用户点开就要看到内容，不能转圈圈\"",[329,513,514],{},"SSR + 流式渲染 \u002F 边缘部署",[329,516,517],{},"Nuxt + Nitro、Next + Edge、Hono",[311,519,520,523,526],{},[329,521,522],{},"\"我们不止一个 App，要复用组件\"",[329,524,525],{},"Monorepo + 共享包",[329,527,528],{},"Turborepo、Nx、pnpm workspaces",[311,530,531,534,537],{},[329,532,533],{},"\"要做一个命令行小工具\"",[329,535,536],{},"CLI 脚手架",[329,538,539],{},"oclif、citty、commander",[311,541,542,545,548],{},[329,543,544],{},"\"要给客户私有化部署\"",[329,546,547],{},"桌面端 \u002F 自托管",[329,549,550],{},"Tauri、Electron、Docker Compose",[311,552,553,556,559],{},[329,554,555],{},"\"要做 AI 助手\"",[329,557,558],{},"LLM 编排 + 流式响应",[329,560,561],{},"create-llama、LangChain、Vercel AI SDK",[198,563,564],{},"这张表本人在和非技术同事开会时会贴白板上，避免大家在术语层面来回打转。",[230,566,568],{"id":567},"_13-脚手架背后的技术选型隐含决策","1.3 脚手架背后的技术选型隐含决策",[198,570,571,572,574],{},"每一个 ",[205,573,336],{}," 的回车，都同时按下了一连串隐含决策：",[576,577,578,585,591,597,603,609,615,636],"ol",{},[241,579,580,584],{},[581,582,583],"strong",{},"包管理器","：pnpm 还是 npm\u002Fyarn\u002Fbun。pnpm 节点链接策略对 Monorepo 友好；bun 速度极快但生态尚在补齐；corepack 在团队全局环境里被本人禁用，原因是它会拦截命令。",[241,586,587,590],{},[581,588,589],{},"打包器","：Vite（基于 Rollup\u002FRolldown）、Webpack、Rspack、Turbopack、Parcel。",[241,592,593,596],{},[581,594,595],{},"运行时","：Node.js、Bun、Deno。Bun 与 Deno 提供更现代的标准库，但生产稳定性需要按业务评估。",[241,598,599,602],{},[581,600,601],{},"TS 编译策略","：tsc、esbuild、SWC、Babel。esbuild\u002FSWC 速度快，但严格类型检查仍需 tsc。",[241,604,605,608],{},[581,606,607],{},"测试框架","：Vitest、Jest、Playwright、Cypress。",[241,610,611,614],{},[581,612,613],{},"Lint\u002FFormat","：ESLint v9 flat config、Biome、Oxlint、Prettier、dprint。Biome 与 Oxlint 把 lint+format 合一并带来数十倍提速。",[241,616,617,620,621,624,625,624,628,631,632,635],{},[581,618,619],{},"目录约定","：",[205,622,623],{},"src\u002F"," vs ",[205,626,627],{},"app\u002F",[205,629,630],{},"pages\u002F","，单包扁平 vs Monorepo ",[205,633,634],{},"packages\u002F*","。",[241,637,638,641],{},[581,639,640],{},"CI\u002FCD 假设","：Turborepo 的 remote cache 默认假设有 Vercel 账号或自建 cache；Nx Cloud 同理。",[198,643,644],{},"工程师常犯的错是把第 1～8 项分别视为独立选择。事实上它们高度耦合：例如 Bun + Vite + Vitest 是一条流畅链路，混用 Bun + Webpack + Jest 则水土不服。脚手架的价值，正是把这些耦合预先收敛成一个可工作的组合。",[198,646,647,648,650],{},"举个具体例子。下面是一份本人脚手架阶段会让 Claude 生成的 ",[205,649,280],{},"，每一行都对应一个隐含决策：",[652,653,658],"pre",{"className":654,"code":655,"language":656,"meta":657,"style":657},"language-jsonc shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F tsconfig.base.json — Monorepo 共享 TS 配置\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",            \u002F\u002F 目标运行时 = Node 20+ \u002F 现代浏览器\n    \"module\": \"ESNext\",            \u002F\u002F 输出 ESM，需配套 package.json 的 \"type\": \"module\"\n    \"moduleResolution\": \"Bundler\", \u002F\u002F 让 TS 与 Vite\u002Fesbuild 的解析行为一致\n    \"strict\": true,                \u002F\u002F 强类型，TEMP-S 中的 M（可维护性）核心保障\n    \"noUncheckedIndexedAccess\": true, \u002F\u002F 数组\u002F对象索引返回 T | undefined，防止运行时炸\n    \"exactOptionalPropertyTypes\": true,\n    \"skipLibCheck\": true,          \u002F\u002F 跳过 node_modules 类型检查，加速 tsc\n    \"verbatimModuleSyntax\": true,  \u002F\u002F 与 isolatedModules 配套，使 import type 不被擦除\n    \"resolveJsonModule\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true\n  }\n}\n","jsonc","",[205,659,660,668,674,680,689,698,707,716,725,731,740,749,755,761,767,773],{"__ignoreMap":657},[661,662,665],"span",{"class":663,"line":664},"line",1,[661,666,667],{},"\u002F\u002F tsconfig.base.json — Monorepo 共享 TS 配置\n",[661,669,671],{"class":663,"line":670},2,[661,672,673],{},"{\n",[661,675,677],{"class":663,"line":676},3,[661,678,679],{},"  \"compilerOptions\": {\n",[661,681,683,686],{"class":663,"line":682},4,[661,684,685],{},"    \"target\": \"ES2022\",",[661,687,688],{},"            \u002F\u002F 目标运行时 = Node 20+ \u002F 现代浏览器\n",[661,690,692,695],{"class":663,"line":691},5,[661,693,694],{},"    \"module\": \"ESNext\",",[661,696,697],{},"            \u002F\u002F 输出 ESM，需配套 package.json 的 \"type\": \"module\"\n",[661,699,701,704],{"class":663,"line":700},6,[661,702,703],{},"    \"moduleResolution\": \"Bundler\",",[661,705,706],{}," \u002F\u002F 让 TS 与 Vite\u002Fesbuild 的解析行为一致\n",[661,708,710,713],{"class":663,"line":709},7,[661,711,712],{},"    \"strict\": true,",[661,714,715],{},"                \u002F\u002F 强类型，TEMP-S 中的 M（可维护性）核心保障\n",[661,717,719,722],{"class":663,"line":718},8,[661,720,721],{},"    \"noUncheckedIndexedAccess\": true,",[661,723,724],{}," \u002F\u002F 数组\u002F对象索引返回 T | undefined，防止运行时炸\n",[661,726,728],{"class":663,"line":727},9,[661,729,730],{},"    \"exactOptionalPropertyTypes\": true,\n",[661,732,734,737],{"class":663,"line":733},10,[661,735,736],{},"    \"skipLibCheck\": true,",[661,738,739],{},"          \u002F\u002F 跳过 node_modules 类型检查，加速 tsc\n",[661,741,743,746],{"class":663,"line":742},11,[661,744,745],{},"    \"verbatimModuleSyntax\": true,",[661,747,748],{},"  \u002F\u002F 与 isolatedModules 配套，使 import type 不被擦除\n",[661,750,752],{"class":663,"line":751},12,[661,753,754],{},"    \"resolveJsonModule\": true,\n",[661,756,758],{"class":663,"line":757},13,[661,759,760],{},"    \"esModuleInterop\": true,\n",[661,762,764],{"class":663,"line":763},14,[661,765,766],{},"    \"allowSyntheticDefaultImports\": true\n",[661,768,770],{"class":663,"line":769},15,[661,771,772],{},"  }\n",[661,774,776],{"class":663,"line":775},16,[661,777,778],{},"}\n",[198,780,781,782,785,786,789],{},"这份配置不是\"复制粘贴模板\"。",[205,783,784],{},"moduleResolution: \"Bundler\""," 决定了下游必须用 Vite\u002Fesbuild\u002FSWC 而不是 ts-node 直跑；",[205,787,788],{},"noUncheckedIndexedAccess"," 会让团队全部代码都被迫处理 undefined，这是一个文化决策。脚手架阶段的每一个 flag，都是给未来三年的工程文化埋一颗钉子。",[791,792],"hr",{},[220,794,796],{"id":795},"二与-claude-协作完成脚手架搭建","二、与 Claude 协作完成脚手架搭建",[195,798,799],{},[198,800,801],{},"给产品经理：这一节展示一个真实场景——你只用一句话告诉 Claude 想做什么，它先反问、再列计划、再敲命令。你不需要懂 npm，但你能从对话里看出 Claude 在做哪些选择，以及哪些选择需要你拍板。",[230,803,805],{"id":804},"_21-用自然语言描述项目需求并让-claude-推荐","2.1 用自然语言描述项目需求并让 Claude 推荐",[198,807,808],{},"打开 Claude Code，最合适的开场不是\"建一个 Vue 项目\"，而是把 6.1 的成果摆出来：",[652,810,815],{"className":811,"code":813,"language":814,"meta":657},[812],"language-text","我把 SPEC.md 和 ARCHITECTURE.md 放在 docs\u002F 下了。\n请基于这两份文档，推荐脚手架与技术栈，要求：\n1. 列出至少两套候选组合，写明各自取舍\n2. 默认偏好 TypeScript + Vue 3 + Vite，但如果你认为不合适请直接说\n3. 暂时不要执行任何命令，先输出对比表\n","text",[205,816,813],{"__ignoreMap":657},[198,818,819,820,823,824,827,828,831,832,835],{},"这条 Prompt 有几个关键动作：",[581,821,822],{},"让 Claude 读已有文档","（它会调用 Read）、",[581,825,826],{},"显式约束输出形式","（对比表）、",[581,829,830],{},"禁止过早执行","（避免它直接 ",[205,833,834],{},"npm create","）。Claude 的回复通常是一张技术栈对比表，列出各自的依赖、CI 假设、学习曲线。",[230,837,839],{"id":838},"_22-plan-模式如何在执行-npxpnpm-create-前展示完整步骤","2.2 Plan 模式如何在执行 npx\u002Fpnpm create 前展示完整步骤",[198,841,842],{},"确认方案后，进入 Plan 模式（Shift+Tab 切换），让 Claude 先给完整计划：",[652,844,847],{"className":845,"code":846,"language":814,"meta":657},[812],"进入 Plan 模式。基于上一步选定的\"TypeScript + Vue 3 + Vite + pnpm + Vitest + ESLint flat config\"组合，\n请给出从空目录到第一次 git commit 的完整步骤计划，包括：\n- 每一步的命令\n- 命令产生的文件清单\n- 中间需要我确认的决策点\n",[205,848,846],{"__ignoreMap":657},[198,850,851],{},"Plan 模式下，Claude 不会直接执行 Bash，而是返回一份分阶段方案，例如：",[652,853,857],{"className":854,"code":855,"language":856,"meta":657,"style":657},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","Phase 1 — 初始化\n  - 步骤 1.1: pnpm create vite@latest my-app --template vue-ts\n  - 步骤 1.2: cd my-app && pnpm install\n  - 决策点: 是否启用 strict mode？是否引入 vue-router\u002Fpinia？\n\nPhase 2 — 工程规范\n  - 步骤 2.1: 安装 eslint@9 + @typescript-eslint + eslint-plugin-vue\n  - 步骤 2.2: 创建 eslint.config.ts (flat config)\n  - 步骤 2.3: 安装 prettier 与 eslint-config-prettier\n\nPhase 3 — 测试与 CI\n  - 步骤 3.1: 安装 vitest + @vue\u002Ftest-utils + jsdom\n  - 步骤 3.2: 配置 vitest.config.ts\n  - 步骤 3.3: 创建首个 smoke test\n\nPhase 4 — 团队协作约定\n  - 步骤 4.1: 撰写 CLAUDE.md\n  - 步骤 4.2: 配置 .claude\u002Fsettings.json\n  - 步骤 4.3: 首次提交\n","markdown",[205,858,859,865,874,881,888,894,899,906,913,920,924,929,936,943,950,954,959,967,975],{"__ignoreMap":657},[661,860,861],{"class":663,"line":664},[661,862,864],{"class":863},"sTEyZ","Phase 1 — 初始化\n",[661,866,867,871],{"class":663,"line":670},[661,868,870],{"class":869},"sMK4o","  -",[661,872,873],{"class":863}," 步骤 1.1: pnpm create vite@latest my-app --template vue-ts\n",[661,875,876,878],{"class":663,"line":676},[661,877,870],{"class":869},[661,879,880],{"class":863}," 步骤 1.2: cd my-app && pnpm install\n",[661,882,883,885],{"class":663,"line":682},[661,884,870],{"class":869},[661,886,887],{"class":863}," 决策点: 是否启用 strict mode？是否引入 vue-router\u002Fpinia？\n",[661,889,890],{"class":663,"line":691},[661,891,893],{"emptyLinePlaceholder":892},true,"\n",[661,895,896],{"class":663,"line":700},[661,897,898],{"class":863},"Phase 2 — 工程规范\n",[661,900,901,903],{"class":663,"line":709},[661,902,870],{"class":869},[661,904,905],{"class":863}," 步骤 2.1: 安装 eslint@9 + @typescript-eslint + eslint-plugin-vue\n",[661,907,908,910],{"class":663,"line":718},[661,909,870],{"class":869},[661,911,912],{"class":863}," 步骤 2.2: 创建 eslint.config.ts (flat config)\n",[661,914,915,917],{"class":663,"line":727},[661,916,870],{"class":869},[661,918,919],{"class":863}," 步骤 2.3: 安装 prettier 与 eslint-config-prettier\n",[661,921,922],{"class":663,"line":733},[661,923,893],{"emptyLinePlaceholder":892},[661,925,926],{"class":663,"line":742},[661,927,928],{"class":863},"Phase 3 — 测试与 CI\n",[661,930,931,933],{"class":663,"line":751},[661,932,870],{"class":869},[661,934,935],{"class":863}," 步骤 3.1: 安装 vitest + @vue\u002Ftest-utils + jsdom\n",[661,937,938,940],{"class":663,"line":757},[661,939,870],{"class":869},[661,941,942],{"class":863}," 步骤 3.2: 配置 vitest.config.ts\n",[661,944,945,947],{"class":663,"line":763},[661,946,870],{"class":869},[661,948,949],{"class":863}," 步骤 3.3: 创建首个 smoke test\n",[661,951,952],{"class":663,"line":769},[661,953,893],{"emptyLinePlaceholder":892},[661,955,956],{"class":663,"line":775},[661,957,958],{"class":863},"Phase 4 — 团队协作约定\n",[661,960,962,964],{"class":663,"line":961},17,[661,963,870],{"class":869},[661,965,966],{"class":863}," 步骤 4.1: 撰写 CLAUDE.md\n",[661,968,970,972],{"class":663,"line":969},18,[661,971,870],{"class":869},[661,973,974],{"class":863}," 步骤 4.2: 配置 .claude\u002Fsettings.json\n",[661,976,978,980],{"class":663,"line":977},19,[661,979,870],{"class":869},[661,981,982],{"class":863}," 步骤 4.3: 首次提交\n",[198,984,985],{},"只要审查这份计划没问题，按 Esc 退出 Plan 模式，再回一句\"按计划执行\"，Claude 会按 ROADMAP 一步步动手并停在每个决策点等你拍板。这种\"先看再做\"的姿势，是脚手架阶段防止 AI 自由发挥的最有效手段。",[230,987,989],{"id":988},"_23-claude-阅读项目结构并撰写-claudemd","2.3 Claude 阅读项目结构并撰写 CLAUDE.md",[198,991,992],{},"脚手架跑完，目录大致长这样：",[652,994,997],{"className":995,"code":996,"language":814,"meta":657},[812],"my-app\u002F\n├── public\u002F\n├── src\u002F\n│   ├── assets\u002F\n│   ├── components\u002F\n│   ├── composables\u002F\n│   ├── router\u002F\n│   ├── stores\u002F\n│   ├── views\u002F\n│   ├── App.vue\n│   └── main.ts\n├── tests\u002F\n├── .claude\u002F\n├── eslint.config.ts\n├── vite.config.ts\n├── vitest.config.ts\n├── tsconfig.json\n└── package.json\n",[205,998,996],{"__ignoreMap":657},[198,1000,1001],{},"接下来让 Claude 自己读完这棵树写 CLAUDE.md：",[652,1003,1006],{"className":1004,"code":1005,"language":814,"meta":657},[812],"请阅读当前目录所有非 node_modules 文件，输出一份 CLAUDE.md。\n要求：\n- 项目概览（1 段）\n- 关键脚本说明（dev\u002Fbuild\u002Ftest\u002Flint）\n- 目录约定（每个一级目录用一句话描述）\n- 编码风格（参考已生成的 eslint.config.ts，不要重复列出规则细节）\n- 与 Claude 协作时必须遵守的禁忌（例如\"不要修改 vite.config.ts 而不解释原因\"）\n",[205,1007,1005],{"__ignoreMap":657},[198,1009,1010],{},"生成的 CLAUDE.md 会成为团队后续每次启动 Claude Code 时自动加载的\"项目记忆\"，其作用相当于第一节里讲的那份\"项目身份证\"。",[230,1012,1014],{"id":1013},"_24-通过-skills-把团队脚手架规范固化","2.4 通过 Skills 把团队脚手架规范固化",[198,1016,1017,1018,1020],{},"CLAUDE.md 适合放静态规范，",[581,1019,112],{}," 适合放可复用工作流。例如团队希望每次新建子包都遵循同一套结构：",[652,1022,1025],{"className":1023,"code":1024,"language":814,"meta":657},[812],".claude\u002Fskills\u002Fnew-subpackage\u002F\n├── SKILL.md\n└── template\u002F\n    ├── package.json.hbs\n    ├── tsconfig.json.hbs\n    └── src\u002Findex.ts.hbs\n",[205,1026,1024],{"__ignoreMap":657},[198,1028,1029,1032,1033,1036,1037,1040],{},[205,1030,1031],{},"SKILL.md"," 描述触发词、参数、步骤；template 目录存模板文件。下次任何成员说\"新建一个名叫 logger 的子包\"，Claude 会按 skill 的步骤复制 template、改 package.json 名称、加入 pnpm-workspace、跑安装。这把\"团队规范\"从口头传承升级为可执行资产。本人项目里类似的做法是：所有 npm script 命名都按 ",[205,1034,1035],{},"dev:\u003Csubpkg-name>"," 而不是 ",[205,1038,1039],{},"\u003Csubpkg-name>:dev","，这条偏好直接写进 skill 模板里，后来者新建子包时不会再写错。",[230,1042,1044],{"id":1043},"_25-mcp-服务器辅助技术选型context7-npm-registry","2.5 MCP 服务器辅助技术选型（context7 \u002F npm registry）",[198,1046,1047],{},"技术选型最大的风险是\"训练数据时间窗口\"。Claude 训练数据的截止日期早于今天，对最新版本号、Breaking Change 不敏感。解决办法是接入 MCP（Model Context Protocol）服务器，把实时信息源当作工具暴露给 Claude：",[238,1049,1050,1056,1066],{},[241,1051,1052,1055],{},[581,1053,1054],{},"context7","：把开源项目文档变成可查询的 MCP 工具。问\"Vite 7 的 environment API 怎么用\"它会查 Vite 仓库官方文档而不是猜。",[241,1057,1058,1061,1062,1065],{},[581,1059,1060],{},"npm registry MCP","：查 ",[205,1063,1064],{},"npm view"," 实时版本与依赖，避免写出已经 deprecated 的依赖。",[241,1067,1068,1071],{},[581,1069,1070],{},"GitHub MCP","：查 issue、PR、release notes，决定要不要追新版本。",[198,1073,1074,1075,1078],{},"接入方式通常在 ",[205,1076,1077],{},".claude\u002Fsettings.json"," 里加一段：",[652,1080,1084],{"className":1081,"code":1082,"language":1083,"meta":657,"style":657},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"mcpServers\": {\n    \"context7\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@upstash\u002Fcontext7-mcp\"]\n    },\n    \"npm-registry\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol\u002Fserver-npm\"]\n    }\n  }\n}\n","json",[205,1085,1086,1090,1108,1122,1147,1181,1186,1199,1217,1246,1251,1255],{"__ignoreMap":657},[661,1087,1088],{"class":663,"line":664},[661,1089,673],{"class":869},[661,1091,1092,1095,1099,1102,1105],{"class":663,"line":670},[661,1093,1094],{"class":869},"  \"",[661,1096,1098],{"class":1097},"spNyl","mcpServers",[661,1100,1101],{"class":869},"\"",[661,1103,1104],{"class":869},":",[661,1106,1107],{"class":869}," {\n",[661,1109,1110,1113,1116,1118,1120],{"class":663,"line":676},[661,1111,1112],{"class":869},"    \"",[661,1114,1054],{"class":1115},"sBMFI",[661,1117,1101],{"class":869},[661,1119,1104],{"class":869},[661,1121,1107],{"class":869},[661,1123,1124,1127,1131,1133,1135,1138,1142,1144],{"class":663,"line":682},[661,1125,1126],{"class":869},"      \"",[661,1128,1130],{"class":1129},"sbssI","command",[661,1132,1101],{"class":869},[661,1134,1104],{"class":869},[661,1136,1137],{"class":869}," \"",[661,1139,1141],{"class":1140},"sfazB","npx",[661,1143,1101],{"class":869},[661,1145,1146],{"class":869},",\n",[661,1148,1149,1151,1154,1156,1158,1161,1163,1166,1168,1171,1173,1176,1178],{"class":663,"line":691},[661,1150,1126],{"class":869},[661,1152,1153],{"class":1129},"args",[661,1155,1101],{"class":869},[661,1157,1104],{"class":869},[661,1159,1160],{"class":869}," [",[661,1162,1101],{"class":869},[661,1164,1165],{"class":1140},"-y",[661,1167,1101],{"class":869},[661,1169,1170],{"class":869},",",[661,1172,1137],{"class":869},[661,1174,1175],{"class":1140},"@upstash\u002Fcontext7-mcp",[661,1177,1101],{"class":869},[661,1179,1180],{"class":869},"]\n",[661,1182,1183],{"class":663,"line":700},[661,1184,1185],{"class":869},"    },\n",[661,1187,1188,1190,1193,1195,1197],{"class":663,"line":709},[661,1189,1112],{"class":869},[661,1191,1192],{"class":1115},"npm-registry",[661,1194,1101],{"class":869},[661,1196,1104],{"class":869},[661,1198,1107],{"class":869},[661,1200,1201,1203,1205,1207,1209,1211,1213,1215],{"class":663,"line":718},[661,1202,1126],{"class":869},[661,1204,1130],{"class":1129},[661,1206,1101],{"class":869},[661,1208,1104],{"class":869},[661,1210,1137],{"class":869},[661,1212,1141],{"class":1140},[661,1214,1101],{"class":869},[661,1216,1146],{"class":869},[661,1218,1219,1221,1223,1225,1227,1229,1231,1233,1235,1237,1239,1242,1244],{"class":663,"line":727},[661,1220,1126],{"class":869},[661,1222,1153],{"class":1129},[661,1224,1101],{"class":869},[661,1226,1104],{"class":869},[661,1228,1160],{"class":869},[661,1230,1101],{"class":869},[661,1232,1165],{"class":1140},[661,1234,1101],{"class":869},[661,1236,1170],{"class":869},[661,1238,1137],{"class":869},[661,1240,1241],{"class":1140},"@modelcontextprotocol\u002Fserver-npm",[661,1243,1101],{"class":869},[661,1245,1180],{"class":869},[661,1247,1248],{"class":663,"line":733},[661,1249,1250],{"class":869},"    }\n",[661,1252,1253],{"class":663,"line":742},[661,1254,772],{"class":869},[661,1256,1257],{"class":663,"line":751},[661,1258,778],{"class":869},[198,1260,1261],{},"接好之后，对话里说\"查 vite 最新稳定版与对应的 @vitejs\u002Fplugin-vue 版本\"，Claude 会真的去查而不是脑补。MCP 是 Anthropic 在 2024 年底开源的协议，2026 年生态已相当丰富，凡是涉及外部数据源的选型都建议先接 MCP 再让 AI 推理。",[198,1263,1264],{},"下面给一段\"接入 MCP 后选型\"的对话片段，体现 MCP 的实际价值：",[652,1266,1269],{"className":1267,"code":1268,"language":814,"meta":657},[812],"PM:    我们要做一个 PDF 在线签批工具，前端用 Vue 3，后端 Node。\n       签批要支持手写签名图层。给我前端 PDF 渲染库的候选。\n\nClaude(无 MCP): 推荐 pdf.js（Mozilla 维护）或 react-pdf。\n                注意：react-pdf 是 React 生态，与 Vue 不直接兼容。\n\nClaude(有 npm-registry MCP): 已查询：\n  - pdfjs-dist：周下载约百万级，活跃维护，体积较大\n  - @vue-pdf\u002F* 系列：周下载较低，最近一次发布 6 个月前，需要谨慎\n  - mupdf-js：商用许可证，请法务确认\n  推荐：pdfjs-dist + 自封装 Vue 组件层。理由：唯一同时满足\"维护活跃 + 许可证宽松 + 框架无关\"的选项。\n",[205,1270,1268],{"__ignoreMap":657},[198,1272,1273],{},"差别非常直接：没有 MCP 的回答更像\"猜测 + 安全话术\"，接了 MCP 之后回答带数据、带许可证提醒、带候选淘汰理由。技术选型的对话里，每多一个数据点，就少一个三个月后才暴露的雷。",[791,1275],{},[220,1277,1279],{"id":1278},"三技术选型方法论","三、技术选型方法论",[195,1281,1282],{},[198,1283,1284],{},"给产品经理：选型不是技术品味问题，是风险管理问题。这一节给一个可以印在 A4 纸上的判断框架，帮你和工程师一起讨论时不至于被术语淹没。",[230,1286,1288],{"id":1287},"_31-选型决策框架团队熟悉度生态成熟度可维护性性能成本","3.1 选型决策框架（团队熟悉度\u002F生态成熟度\u002F可维护性\u002F性能成本）",[198,1290,1291,1292,1295],{},"本人采用的简化框架是 ",[581,1293,1294],{},"TEMP-S"," 五维：",[305,1297,1298,1311],{},[308,1299,1300],{},[311,1301,1302,1305,1308],{},[314,1303,1304],{},"维度",[314,1306,1307],{},"含义",[314,1309,1310],{},"评估问题",[324,1312,1313,1327,1341,1355,1369],{},[311,1314,1315,1321,1324],{},[329,1316,1317,1320],{},[581,1318,1319],{},"T","eam",[329,1322,1323],{},"团队熟悉度",[329,1325,1326],{},"80% 的人能在一周内独立产出吗？",[311,1328,1329,1335,1338],{},[329,1330,1331,1334],{},[581,1332,1333],{},"E","cosystem",[329,1336,1337],{},"生态成熟度",[329,1339,1340],{},"npm 周下载、GitHub Star、商业公司背书、Stack Overflow 问答密度",[311,1342,1343,1349,1352],{},[329,1344,1345,1348],{},[581,1346,1347],{},"M","aintainability",[329,1350,1351],{},"可维护性",[329,1353,1354],{},"文档完整度、Breaking Change 频率、长期路线图清晰吗？",[311,1356,1357,1363,1366],{},[329,1358,1359,1362],{},[581,1360,1361],{},"P","erformance",[329,1364,1365],{},"性能成本",[329,1367,1368],{},"冷启动、构建时长、运行时内存、Bundle Size",[311,1370,1371,1377,1380],{},[329,1372,1373,1376],{},[581,1374,1375],{},"S","ecurity",[329,1378,1379],{},"安全合规",[329,1381,1382],{},"已知 CVE、依赖链深度、是否被供应链攻击命中过",[198,1384,1385],{},"每一维打 1～5 分，做雷达图。雷达图未必精确，但能逼团队把直觉量化。",[198,1387,1388],{},"下面用 TEMP-S 评估\"前端打包器\"这个槽位作为示意（只是演示形式，具体分数按团队实际填）：",[305,1390,1391,1409],{},[308,1392,1393],{},[311,1394,1395,1397,1400,1403,1406],{},[314,1396,1304],{},[314,1398,1399],{},"Vite 7",[314,1401,1402],{},"Webpack 5",[314,1404,1405],{},"Rspack",[314,1407,1408],{},"Turbopack",[324,1410,1411,1427,1441,1454,1467],{},[311,1412,1413,1416,1419,1421,1424],{},[329,1414,1415],{},"Team 团队熟悉度",[329,1417,1418],{},"5",[329,1420,1418],{},[329,1422,1423],{},"3",[329,1425,1426],{},"2",[311,1428,1429,1432,1434,1436,1439],{},[329,1430,1431],{},"Ecosystem 生态成熟度",[329,1433,1418],{},[329,1435,1418],{},[329,1437,1438],{},"4",[329,1440,1423],{},[311,1442,1443,1446,1448,1450,1452],{},[329,1444,1445],{},"Maintainability 可维护性",[329,1447,1418],{},[329,1449,1438],{},[329,1451,1438],{},[329,1453,1438],{},[311,1455,1456,1459,1461,1463,1465],{},[329,1457,1458],{},"Performance 性能成本",[329,1460,1438],{},[329,1462,1426],{},[329,1464,1418],{},[329,1466,1418],{},[311,1468,1469,1472,1474,1476,1478],{},[329,1470,1471],{},"Security 安全合规",[329,1473,1438],{},[329,1475,1438],{},[329,1477,1438],{},[329,1479,1438],{},[198,1481,1482],{},"雷达图能直观告诉 PM：\"Vite 是当下平衡得最好的，但 Rspack 在性能维度有可见优势——如果项目规模超过 500 个组件，半年后值得评估迁移。\"这种\"今天选 A、什么时候考虑 B\"的话语，比\"用 Vite 因为它快\"更有决策价值。",[230,1484,1486],{"id":1485},"_32-与-claude-对话式选型让-ai-罗列候选并比对优劣","3.2 与 Claude 对话式选型——让 AI 罗列候选并比对优劣",[198,1488,1489],{},"把 TEMP-S 表喂给 Claude 是更聪明的用法：",[652,1491,1494],{"className":1492,"code":1493,"language":814,"meta":657},[812],"请用 TEMP-S 框架评估\"前端状态管理\"这个槽位，候选：\n1) Pinia\n2) Zustand（搭配 Vue 适配层）\n3) 自研 reactive store\n\n约束：\n- 团队是 Vue 3 + TypeScript\n- 生态成熟度只看 2025 年至今的数据\n- 输出 markdown 表格，最后一行是推荐项与理由\n\n引用任何数据时，请通过 context7 \u002F npm-registry MCP 查询，\n没有可靠数据来源就明确写\"无数据\"，不要捏造数字。\n",[205,1495,1493],{"__ignoreMap":657},[198,1497,1498],{},"这条 Prompt 同时启用了 MCP 工具与\"无数据就写无数据\"的反幻觉护栏。Claude 会输出一张可审查的对比表，工程师在表上批注，最终落到 ARCHITECTURE.md 的\"技术选型记录\"小节。",[230,1500,1502],{"id":1501},"_33-真实案例对照vue-vs-reactexpress-vs-fastifysql-vs-nosql","3.3 真实案例对照（Vue vs React、Express vs Fastify、SQL vs NoSQL）",[198,1504,1505],{},"以下案例不引用具体数字，只展示决策路径：",[238,1507,1508,1514,1520],{},[241,1509,1510,1513],{},[581,1511,1512],{},"Vue vs React","：团队熟悉度决定一切。组合式 API 与 React Hooks 心智模型相近，但 SFC 的样式作用域与模板语法对设计师友好。如果团队曾用 React 三年以上，没必要为了\"看起来更新\"切到 Vue。",[241,1515,1516,1519],{},[581,1517,1518],{},"Express vs Fastify vs Hono","：Express 生态最广但性能最低；Fastify 在 Node 生态里性能与生态平衡较好；Hono 跨运行时（Cloudflare Workers \u002F Bun \u002F Node），适合边缘部署优先的项目。",[241,1521,1522,1525],{},[581,1523,1524],{},"SQL vs NoSQL","：业务能用主键 + 索引解决就用 PostgreSQL，需要灵活模式的领域（用户行为日志、IM 消息）再考虑 MongoDB \u002F DynamoDB。一刀切\"用 NoSQL 才现代\"是反模式。",[198,1527,1528],{},"再举一个本人遇到的真实案例。某项目早期选型把\"实时通知\"映射到 Redis Pub\u002FSub + WebSocket，理由是\"性能最强\"。三个月后做多端同步时发现 Pub\u002FSub 没有\"未读计数\"语义，团队又叠了一层 Redis Sorted Set 维护已读偏移，再叠一层 MySQL 做持久化。最终架构图里有 3 套存储、2 条消息通路。回头看，第一性问题其实是\"我们要的是消息流还是事件总线\"——如果是消息流，从一开始就该选有持久化与游标的 Kafka \u002F NATS JetStream \u002F Redis Streams，而不是 Pub\u002FSub。这种\"在错误抽象上叠层\"的代价，远高于第一天多花两天选型。让 Claude 在 Plan 模式下显式列出\"这个方案不适合什么场景\"，能拦住相当一部分类似失误。",[198,1530,1531],{},"下面是本人沉淀的\"AI 选型对话四问\"，按顺序问完，幻觉率会显著下降：",[652,1533,1536],{"className":1534,"code":1535,"language":814,"meta":657},[812],"1. \"请列出至少 3 个候选方案，并按 TEMP-S 五维打分\"\n2. \"请列出每个候选方案‘最不擅长的场景’\"\n3. \"请列出推荐方案在未来 12 个月可能踩到的 3 个坑\"\n4. \"如果团队 6 个月后想替换该方案，迁移成本最高的部分是什么？\"\n",[205,1537,1535],{"__ignoreMap":657},[198,1539,1540],{},"这四问的核心思想是：让 AI 不仅回答\"选什么\"，还回答\"什么时候不该选\"和\"换走的代价\"。AI 在第一种问题上容易表现得过分自信，在后三种问题上反而能给出相当中肯的答案。",[230,1542,1544],{"id":1543},"_34-选型反模式过早抽象过度工程跟风新框架","3.4 选型反模式（过早抽象\u002F过度工程\u002F跟风新框架）",[198,1546,1547],{},"业界普遍认为以下几类是技术选型的高频陷阱：",[576,1549,1550,1556,1562,1568,1574],{},[241,1551,1552,1555],{},[581,1553,1554],{},"过早抽象","：MVP 阶段就搭 Monorepo + 微前端 + 微服务。结果三个月后第一个用户都没有，团队却在维护 8 个子包。",[241,1557,1558,1561],{},[581,1559,1560],{},"跟风新框架","：每出一个 X.js 就重写一次。每次重写都吃掉团队 2～3 周窗口期，业务停滞。",[241,1563,1564,1567],{},[581,1565,1566],{},"简历驱动开发（Resume-Driven Development）","：选型理由是\"我想学\"，不是\"项目需要\"。",[241,1569,1570,1573],{},[581,1571,1572],{},"零配置幻觉","：以为脚手架\"零配置\"就不需要懂底层。事实是黑箱配置一旦出问题，调试成本远高于自己写一份。",[241,1575,1576,1579],{},[581,1577,1578],{},"AI 推荐照单全收","：Claude 经常因为训练数据偏好推荐 Next.js、TailwindCSS——它们确实是好工具，但未必匹配当前业务。AI 给的推荐永远要过 TEMP-S。",[198,1581,1582],{},"为了把\"反模式\"变成可观测信号，本人在脚手架阶段会做一份\"选型决策记录\"（ADR，Architecture Decision Record），每个决策一份独立 markdown，模板如下：",[652,1584,1586],{"className":854,"code":1585,"language":856,"meta":657,"style":657},"# ADR-002 选用 Pinia 作为状态管理\n\n- 日期：2026-04-26\n- 状态：Accepted\n- 背景：团队是 Vue 3 + TS，需要全局共享当前用户、未读消息、主题设置\n- 候选：\n  - Pinia（Vue 官方）\n  - Zustand + Vue 适配（社区方案）\n  - 自研 reactive store\n- 评估（TEMP-S）：\n  - Pinia: T5 E5 M5 P4 S4\n  - Zustand+Vue: T2 E3 M3 P5 S4\n  - 自研: T3 E1 M2 P5 S3\n- 决策：Pinia\n- 取舍：放弃 Zustand 的极简 API；放弃自研的灵活性\n- 退出条件：当 Pinia 维护活跃度连续 6 个月低于阈值，或 Vue 官方推荐换栈时重新评估\n",[205,1587,1588,1596,1600,1608,1615,1622,1629,1636,1643,1650,1657,1664,1671,1678,1685,1692],{"__ignoreMap":657},[661,1589,1590,1593],{"class":663,"line":664},[661,1591,1592],{"class":869},"# ",[661,1594,1595],{"class":1115},"ADR-002 选用 Pinia 作为状态管理\n",[661,1597,1598],{"class":663,"line":670},[661,1599,893],{"emptyLinePlaceholder":892},[661,1601,1602,1605],{"class":663,"line":676},[661,1603,1604],{"class":869},"-",[661,1606,1607],{"class":863}," 日期：2026-04-26\n",[661,1609,1610,1612],{"class":663,"line":682},[661,1611,1604],{"class":869},[661,1613,1614],{"class":863}," 状态：Accepted\n",[661,1616,1617,1619],{"class":663,"line":691},[661,1618,1604],{"class":869},[661,1620,1621],{"class":863}," 背景：团队是 Vue 3 + TS，需要全局共享当前用户、未读消息、主题设置\n",[661,1623,1624,1626],{"class":663,"line":700},[661,1625,1604],{"class":869},[661,1627,1628],{"class":863}," 候选：\n",[661,1630,1631,1633],{"class":663,"line":709},[661,1632,870],{"class":869},[661,1634,1635],{"class":863}," Pinia（Vue 官方）\n",[661,1637,1638,1640],{"class":663,"line":718},[661,1639,870],{"class":869},[661,1641,1642],{"class":863}," Zustand + Vue 适配（社区方案）\n",[661,1644,1645,1647],{"class":663,"line":727},[661,1646,870],{"class":869},[661,1648,1649],{"class":863}," 自研 reactive store\n",[661,1651,1652,1654],{"class":663,"line":733},[661,1653,1604],{"class":869},[661,1655,1656],{"class":863}," 评估（TEMP-S）：\n",[661,1658,1659,1661],{"class":663,"line":742},[661,1660,870],{"class":869},[661,1662,1663],{"class":863}," Pinia: T5 E5 M5 P4 S4\n",[661,1665,1666,1668],{"class":663,"line":751},[661,1667,870],{"class":869},[661,1669,1670],{"class":863}," Zustand+Vue: T2 E3 M3 P5 S4\n",[661,1672,1673,1675],{"class":663,"line":757},[661,1674,870],{"class":869},[661,1676,1677],{"class":863}," 自研: T3 E1 M2 P5 S3\n",[661,1679,1680,1682],{"class":663,"line":763},[661,1681,1604],{"class":869},[661,1683,1684],{"class":863}," 决策：Pinia\n",[661,1686,1687,1689],{"class":663,"line":769},[661,1688,1604],{"class":869},[661,1690,1691],{"class":863}," 取舍：放弃 Zustand 的极简 API；放弃自研的灵活性\n",[661,1693,1694,1696],{"class":663,"line":775},[661,1695,1604],{"class":869},[661,1697,1698],{"class":863}," 退出条件：当 Pinia 维护活跃度连续 6 个月低于阈值，或 Vue 官方推荐换栈时重新评估\n",[198,1700,1701],{},"ADR 看起来很重，但它是技术债的前哨。每写一份 ADR 大约花 20 分钟，节约的是半年后\"为什么当时选这个\"的考古时间。让 Claude 在每个选型对话结束时主动生成 ADR 草稿，是脚手架阶段最划算的协作姿势之一。",[791,1703],{},[220,1705,1707],{"id":1706},"四实战-demotypescript-vue-3-vite","四、实战 Demo——TypeScript + Vue 3 + Vite",[195,1709,1710],{},[198,1711,1712],{},"给产品经理：本节是一段\"对话回放\"，演示一个新项目从一句话到第一次 commit 的全过程。你不需要复现命令，只看 PM 视角的发言节奏与决策点即可。",[230,1714,1716],{"id":1715},"_41-一句话需求到第一次-commit-的完整对话流程","4.1 一句话需求到第一次 commit 的完整对话流程",[198,1718,1719],{},[581,1720,1721],{},"第 1 轮 — PM 给需求：",[652,1723,1726],{"className":1724,"code":1725,"language":814,"meta":657},[812],"PM: 我们要做一个团队周报工具，员工每周五写日报，老板看汇总。\n    技术栈优先 TS + Vue 3 + Vite，部署放 Vercel。\n    请进入 Plan 模式，先给我搭脚手架的完整步骤。\n",[205,1727,1725],{"__ignoreMap":657},[198,1729,1730],{},[581,1731,1732],{},"第 2 轮 — Claude 反问澄清：",[652,1734,1737],{"className":1735,"code":1736,"language":814,"meta":657},[812],"Claude: 进入 Plan 模式前我需要确认 4 件事：\n  1) 是否需要服务端？日报数据存哪里——本地 LocalStorage、Supabase、还是自建后端？\n  2) 老板视图与员工视图差异大吗？要不要做权限？\n  3) 部署目标是 Vercel，前端纯静态还是需要 Edge Function？\n  4) 团队规模与技术背景，影响是否引入 Pinia\u002FVue Router 等。\n请逐条回答。\n",[205,1738,1736],{"__ignoreMap":657},[198,1740,1741],{},[581,1742,1743],{},"第 3 轮 — PM 回答：",[652,1745,1748],{"className":1746,"code":1747,"language":814,"meta":657},[812],"PM: 1) Supabase  2) 老板看汇总，员工只看自己的，需要权限  \n    3) 可以用 Vercel Edge Function  4) 4 人团队，都熟悉 Vue 3\n",[205,1749,1747],{"__ignoreMap":657},[198,1751,1752],{},[581,1753,1754],{},"第 4 轮 — Claude 出 Plan：",[652,1756,1759],{"className":1757,"code":1758,"language":814,"meta":657},[812],"Claude: 已生成 ROADMAP-scaffold.md，主要阶段：\n  Phase 1 - pnpm create vite + 基础依赖\n  Phase 2 - 接入 vue-router + pinia + supabase-js\n  Phase 3 - 配置 eslint flat + prettier + vitest\n  Phase 4 - 编写 CLAUDE.md + 配置 .claude\u002Fskills\n  Phase 5 - 配置 Vercel 部署预设\n  Phase 6 - 首次 commit + 推送 main\n请审查并回复\"按计划执行\"。\n",[205,1760,1758],{"__ignoreMap":657},[198,1762,1763],{},[581,1764,1765],{},"第 5 轮 — PM 同意：",[652,1767,1770],{"className":1768,"code":1769,"language":814,"meta":657},[812],"PM: 按计划执行，但 Phase 5 暂缓，我们今天先到 Phase 4。\n",[205,1771,1769],{"__ignoreMap":657},[198,1773,1774],{},[581,1775,1776],{},"第 6 轮 — Claude 执行：",[198,1778,1779],{},"Claude 依次执行下面的命令（Plan 模式退出后），每一步都先打印命令、等用户确认后再跑：",[652,1781,1785],{"className":1782,"code":1783,"language":1784,"meta":657,"style":657},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Phase 1 — 项目骨架\npnpm create vite@latest weekly-report --template vue-ts\ncd weekly-report\npnpm install\n\n# Phase 2 — 路由 \u002F 状态 \u002F 后端 SDK\npnpm add vue-router@4 pinia @supabase\u002Fsupabase-js\n\n# Phase 3 — 工程规范\npnpm add -D eslint@9 @typescript-eslint\u002Feslint-plugin \\\n  @typescript-eslint\u002Fparser eslint-plugin-vue \\\n  prettier eslint-config-prettier vitest @vue\u002Ftest-utils jsdom\n\n# Phase 4 — 写入 CLAUDE.md\n# (Claude 调用 Write 工具)\n","bash",[205,1786,1787,1793,1813,1822,1829,1833,1838,1854,1858,1863,1881,1891,1908,1912,1917],{"__ignoreMap":657},[661,1788,1789],{"class":663,"line":664},[661,1790,1792],{"class":1791},"sHwdD","# Phase 1 — 项目骨架\n",[661,1794,1795,1798,1801,1804,1807,1810],{"class":663,"line":670},[661,1796,1797],{"class":1115},"pnpm",[661,1799,1800],{"class":1140}," create",[661,1802,1803],{"class":1140}," vite@latest",[661,1805,1806],{"class":1140}," weekly-report",[661,1808,1809],{"class":1140}," --template",[661,1811,1812],{"class":1140}," vue-ts\n",[661,1814,1815,1819],{"class":663,"line":676},[661,1816,1818],{"class":1817},"s2Zo4","cd",[661,1820,1821],{"class":1140}," weekly-report\n",[661,1823,1824,1826],{"class":663,"line":682},[661,1825,1797],{"class":1115},[661,1827,1828],{"class":1140}," install\n",[661,1830,1831],{"class":663,"line":691},[661,1832,893],{"emptyLinePlaceholder":892},[661,1834,1835],{"class":663,"line":700},[661,1836,1837],{"class":1791},"# Phase 2 — 路由 \u002F 状态 \u002F 后端 SDK\n",[661,1839,1840,1842,1845,1848,1851],{"class":663,"line":709},[661,1841,1797],{"class":1115},[661,1843,1844],{"class":1140}," add",[661,1846,1847],{"class":1140}," vue-router@4",[661,1849,1850],{"class":1140}," pinia",[661,1852,1853],{"class":1140}," @supabase\u002Fsupabase-js\n",[661,1855,1856],{"class":663,"line":718},[661,1857,893],{"emptyLinePlaceholder":892},[661,1859,1860],{"class":663,"line":727},[661,1861,1862],{"class":1791},"# Phase 3 — 工程规范\n",[661,1864,1865,1867,1869,1872,1875,1878],{"class":663,"line":733},[661,1866,1797],{"class":1115},[661,1868,1844],{"class":1140},[661,1870,1871],{"class":1140}," -D",[661,1873,1874],{"class":1140}," eslint@9",[661,1876,1877],{"class":1140}," @typescript-eslint\u002Feslint-plugin",[661,1879,1880],{"class":863}," \\\n",[661,1882,1883,1886,1889],{"class":663,"line":742},[661,1884,1885],{"class":1140},"  @typescript-eslint\u002Fparser",[661,1887,1888],{"class":1140}," eslint-plugin-vue",[661,1890,1880],{"class":863},[661,1892,1893,1896,1899,1902,1905],{"class":663,"line":751},[661,1894,1895],{"class":1140},"  prettier",[661,1897,1898],{"class":1140}," eslint-config-prettier",[661,1900,1901],{"class":1140}," vitest",[661,1903,1904],{"class":1140}," @vue\u002Ftest-utils",[661,1906,1907],{"class":1140}," jsdom\n",[661,1909,1910],{"class":663,"line":757},[661,1911,893],{"emptyLinePlaceholder":892},[661,1913,1914],{"class":663,"line":763},[661,1915,1916],{"class":1791},"# Phase 4 — 写入 CLAUDE.md\n",[661,1918,1919],{"class":663,"line":769},[661,1920,1921],{"class":1791},"# (Claude 调用 Write 工具)\n",[198,1923,1924],{},[581,1925,1926],{},"第 7 轮 — PM 收尾：",[652,1928,1931],{"className":1929,"code":1930,"language":814,"meta":657},[812],"PM: 帮我做第一次提交，commit message 中文。\nClaude: 已生成 commit「chore: 初始化周报工具脚手架（vue3 + vite + supabase）」，是否提交？\nPM: 是。\n",[205,1932,1930],{"__ignoreMap":657},[198,1934,1935],{},"整段对话花费约 12 分钟，背后跑了 50 多条命令、写了 30 多个文件。PM 只做了 7 次决策。",[230,1937,1939],{"id":1938},"_42-claude-主动询问的好问题模板","4.2 Claude 主动询问的好问题模板",[198,1941,1942],{},"观察上面的回放，Claude 的\"反问\"是高质量协作的核心。本人沉淀的好问题模板：",[652,1944,1947],{"className":1945,"code":1946,"language":814,"meta":657},[812],"1. 数据 \u002F 状态：数据存在哪里？要不要持久化？\n2. 边界 \u002F 权限：用户分几类？谁能看到什么？\n3. 部署 \u002F 运行环境：跑在浏览器、Node、Edge、Worker？\n4. 团队 \u002F 时间预算：人数？经验？deadline？\n5. 演化 \u002F 退出条件：MVP 结束后下一阶段做什么？\n",[205,1948,1946],{"__ignoreMap":657},[198,1950,1951,1952,1955],{},"如果 Claude 没主动问，说明它在\"猜\"。这时不要回答它的方案，而是回一句\"在出方案前，请用上面 5 类问题先 interview 我\"。这条提示词本身可以固化到 ",[205,1953,1954],{},"~\u002F.claude\u002FCLAUDE.md"," 里，全局生效。",[230,1957,1959],{"id":1958},"_43-团队规范固化为-claudemd-与-skills","4.3 团队规范固化为 CLAUDE.md 与 Skills",[198,1961,1962],{},"最终生成的 CLAUDE.md 关键片段：",[652,1964,1966],{"className":854,"code":1965,"language":856,"meta":657,"style":657},"# Weekly Report\n\n## 项目概览\n4 人团队周报工具，前端 Vue 3 + Vite，后端 Supabase + Vercel Edge。\n\n## 关键脚本\n- `pnpm dev` 本地开发，端口 5173\n- `pnpm build` 生产构建\n- `pnpm test` Vitest 单测\n- `pnpm lint` ESLint flat + Prettier\n\n## 目录约定\n- `src\u002Fviews\u002F` 路由级页面\n- `src\u002Fcomponents\u002F` 通用组件，超过 300 行考虑拆分\n- `src\u002Fcomposables\u002F` 组合式函数，文件名以 `use` 开头\n- `src\u002Fstores\u002F` Pinia store，按业务领域分文件\n- `src\u002Fapi\u002F` Supabase 调用，按表分文件\n\n## 与 Claude 协作约定\n- 涉及 vite.config.ts \u002F supabase schema 的修改必须先进 Plan 模式\n- 任何新依赖必须用 npm-registry MCP 查最新稳定版\n- 提交信息统一中文，前缀使用 conventional commits\n- 禁止 `git push --force` 到 main\n",[205,1967,1968,1975,1979,1987,1992,1996,2003,2018,2032,2046,2060,2064,2071,2085,2099,2123,2137,2151,2155,2162,2170,2178,2186],{"__ignoreMap":657},[661,1969,1970,1972],{"class":663,"line":664},[661,1971,1592],{"class":869},[661,1973,1974],{"class":1115},"Weekly Report\n",[661,1976,1977],{"class":663,"line":670},[661,1978,893],{"emptyLinePlaceholder":892},[661,1980,1981,1984],{"class":663,"line":676},[661,1982,1983],{"class":869},"## ",[661,1985,1986],{"class":1115},"项目概览\n",[661,1988,1989],{"class":663,"line":682},[661,1990,1991],{"class":863},"4 人团队周报工具，前端 Vue 3 + Vite，后端 Supabase + Vercel Edge。\n",[661,1993,1994],{"class":663,"line":691},[661,1995,893],{"emptyLinePlaceholder":892},[661,1997,1998,2000],{"class":663,"line":700},[661,1999,1983],{"class":869},[661,2001,2002],{"class":1115},"关键脚本\n",[661,2004,2005,2007,2010,2012,2015],{"class":663,"line":709},[661,2006,1604],{"class":869},[661,2008,2009],{"class":869}," `",[661,2011,207],{"class":1140},[661,2013,2014],{"class":869},"`",[661,2016,2017],{"class":863}," 本地开发，端口 5173\n",[661,2019,2020,2022,2024,2027,2029],{"class":663,"line":718},[661,2021,1604],{"class":869},[661,2023,2009],{"class":869},[661,2025,2026],{"class":1140},"pnpm build",[661,2028,2014],{"class":869},[661,2030,2031],{"class":863}," 生产构建\n",[661,2033,2034,2036,2038,2041,2043],{"class":663,"line":727},[661,2035,1604],{"class":869},[661,2037,2009],{"class":869},[661,2039,2040],{"class":1140},"pnpm test",[661,2042,2014],{"class":869},[661,2044,2045],{"class":863}," Vitest 单测\n",[661,2047,2048,2050,2052,2055,2057],{"class":663,"line":733},[661,2049,1604],{"class":869},[661,2051,2009],{"class":869},[661,2053,2054],{"class":1140},"pnpm lint",[661,2056,2014],{"class":869},[661,2058,2059],{"class":863}," ESLint flat + Prettier\n",[661,2061,2062],{"class":663,"line":742},[661,2063,893],{"emptyLinePlaceholder":892},[661,2065,2066,2068],{"class":663,"line":751},[661,2067,1983],{"class":869},[661,2069,2070],{"class":1115},"目录约定\n",[661,2072,2073,2075,2077,2080,2082],{"class":663,"line":757},[661,2074,1604],{"class":869},[661,2076,2009],{"class":869},[661,2078,2079],{"class":1140},"src\u002Fviews\u002F",[661,2081,2014],{"class":869},[661,2083,2084],{"class":863}," 路由级页面\n",[661,2086,2087,2089,2091,2094,2096],{"class":663,"line":763},[661,2088,1604],{"class":869},[661,2090,2009],{"class":869},[661,2092,2093],{"class":1140},"src\u002Fcomponents\u002F",[661,2095,2014],{"class":869},[661,2097,2098],{"class":863}," 通用组件，超过 300 行考虑拆分\n",[661,2100,2101,2103,2105,2108,2110,2113,2115,2118,2120],{"class":663,"line":769},[661,2102,1604],{"class":869},[661,2104,2009],{"class":869},[661,2106,2107],{"class":1140},"src\u002Fcomposables\u002F",[661,2109,2014],{"class":869},[661,2111,2112],{"class":863}," 组合式函数，文件名以 ",[661,2114,2014],{"class":869},[661,2116,2117],{"class":1140},"use",[661,2119,2014],{"class":869},[661,2121,2122],{"class":863}," 开头\n",[661,2124,2125,2127,2129,2132,2134],{"class":663,"line":775},[661,2126,1604],{"class":869},[661,2128,2009],{"class":869},[661,2130,2131],{"class":1140},"src\u002Fstores\u002F",[661,2133,2014],{"class":869},[661,2135,2136],{"class":863}," Pinia store，按业务领域分文件\n",[661,2138,2139,2141,2143,2146,2148],{"class":663,"line":961},[661,2140,1604],{"class":869},[661,2142,2009],{"class":869},[661,2144,2145],{"class":1140},"src\u002Fapi\u002F",[661,2147,2014],{"class":869},[661,2149,2150],{"class":863}," Supabase 调用，按表分文件\n",[661,2152,2153],{"class":663,"line":969},[661,2154,893],{"emptyLinePlaceholder":892},[661,2156,2157,2159],{"class":663,"line":977},[661,2158,1983],{"class":869},[661,2160,2161],{"class":1115},"与 Claude 协作约定\n",[661,2163,2165,2167],{"class":663,"line":2164},20,[661,2166,1604],{"class":869},[661,2168,2169],{"class":863}," 涉及 vite.config.ts \u002F supabase schema 的修改必须先进 Plan 模式\n",[661,2171,2173,2175],{"class":663,"line":2172},21,[661,2174,1604],{"class":869},[661,2176,2177],{"class":863}," 任何新依赖必须用 npm-registry MCP 查最新稳定版\n",[661,2179,2181,2183],{"class":663,"line":2180},22,[661,2182,1604],{"class":869},[661,2184,2185],{"class":863}," 提交信息统一中文，前缀使用 conventional commits\n",[661,2187,2189,2191,2194,2196,2199,2201],{"class":663,"line":2188},23,[661,2190,1604],{"class":869},[661,2192,2193],{"class":863}," 禁止 ",[661,2195,2014],{"class":869},[661,2197,2198],{"class":1140},"git push --force",[661,2200,2014],{"class":869},[661,2202,2203],{"class":863}," 到 main\n",[198,2205,2206,2207,2210],{},"同时在 ",[205,2208,2209],{},".claude\u002Fskills\u002F"," 下放：",[652,2212,2215],{"className":2213,"code":2214,"language":814,"meta":657},[812],".claude\u002Fskills\u002F\n├── new-view\u002FSKILL.md          # 新建视图（生成 vue 文件 + 路由 + 测试样板）\n├── new-store\u002FSKILL.md         # 新建 Pinia store\n├── add-supabase-table\u002FSKILL.md # 加表 + 生成 TS 类型 + API 文件\n└── release\u002FSKILL.md           # 发版流程\n",[205,2216,2214],{"__ignoreMap":657},[198,2218,2219,2220,2223],{},"这些 Skills 是团队最值钱的资产之一——它们不是\"AI 提示词\"，而是把团队工作流变成可执行代码。新人入职第一天 ",[205,2221,2222],{},"pnpm install + 启动 Claude Code","，团队规范就已经在他终端里跑起来了。",[198,2225,2226,2227,2230],{},"为了让读者有一个具体的 Skill 文件参照，下面给出 ",[205,2228,2229],{},"new-view\u002FSKILL.md"," 的精简实现：",[652,2232,2234],{"className":854,"code":2233,"language":856,"meta":657,"style":657},"---\nname: new-view\ndescription: 在 src\u002Fviews 下新建路由级页面，附路由表注册与冒烟测试\ntrigger: 当用户说\"新建一个页面\u002F视图\u002F路由\"时启用\n---\n\n# 步骤\n1. 询问用户：页面名称（PascalCase）、URL 路径、是否需要鉴权\n2. 在 `src\u002Fviews\u002F\u003CName>.vue` 写入模板：\n   ```vue\n   \u003Cscript setup lang=\"ts\">\n   \u002F\u002F {{Name}} 视图：{{description}}\n   \u003C\u002Fscript>\n   \u003Ctemplate>\n     \u003Csection class=\"{{kebabName}}\">\n       \u003Ch1>{{Name}}\u003C\u002Fh1>\n     \u003C\u002Fsection>\n   \u003C\u002Ftemplate>\n",[205,2235,2236,2241,2252,2262,2272,2276,2280,2287,2295,2313,2322,2327,2332,2337,2342,2347,2352,2357],{"__ignoreMap":657},[661,2237,2238],{"class":663,"line":664},[661,2239,2240],{"class":869},"---\n",[661,2242,2243,2247,2249],{"class":663,"line":670},[661,2244,2246],{"class":2245},"swJcz","name",[661,2248,1104],{"class":869},[661,2250,2251],{"class":1140}," new-view\n",[661,2253,2254,2257,2259],{"class":663,"line":676},[661,2255,2256],{"class":2245},"description",[661,2258,1104],{"class":869},[661,2260,2261],{"class":1140}," 在 src\u002Fviews 下新建路由级页面，附路由表注册与冒烟测试\n",[661,2263,2264,2267,2269],{"class":663,"line":682},[661,2265,2266],{"class":2245},"trigger",[661,2268,1104],{"class":869},[661,2270,2271],{"class":1140}," 当用户说\"新建一个页面\u002F视图\u002F路由\"时启用\n",[661,2273,2274],{"class":663,"line":691},[661,2275,2240],{"class":869},[661,2277,2278],{"class":663,"line":700},[661,2279,893],{"emptyLinePlaceholder":892},[661,2281,2282,2284],{"class":663,"line":709},[661,2283,1592],{"class":869},[661,2285,2286],{"class":1115},"步骤\n",[661,2288,2289,2292],{"class":663,"line":718},[661,2290,2291],{"class":869},"1.",[661,2293,2294],{"class":863}," 询问用户：页面名称（PascalCase）、URL 路径、是否需要鉴权\n",[661,2296,2297,2300,2303,2305,2308,2310],{"class":663,"line":727},[661,2298,2299],{"class":869},"2.",[661,2301,2302],{"class":863}," 在 ",[661,2304,2014],{"class":869},[661,2306,2307],{"class":1140},"src\u002Fviews\u002F\u003CName>.vue",[661,2309,2014],{"class":869},[661,2311,2312],{"class":863}," 写入模板：\n",[661,2314,2315,2318],{"class":663,"line":733},[661,2316,2317],{"class":1140},"   ```",[661,2319,2321],{"class":2320},"sJsPd","vue\n",[661,2323,2324],{"class":663,"line":742},[661,2325,2326],{"class":2320},"   \u003Cscript setup lang=\"ts\">\n",[661,2328,2329],{"class":663,"line":751},[661,2330,2331],{"class":2320},"   \u002F\u002F {{Name}} 视图：{{description}}\n",[661,2333,2334],{"class":663,"line":757},[661,2335,2336],{"class":2320},"   \u003C\u002Fscript>\n",[661,2338,2339],{"class":663,"line":763},[661,2340,2341],{"class":2320},"   \u003Ctemplate>\n",[661,2343,2344],{"class":663,"line":769},[661,2345,2346],{"class":2320},"     \u003Csection class=\"{{kebabName}}\">\n",[661,2348,2349],{"class":663,"line":775},[661,2350,2351],{"class":2320},"       \u003Ch1>{{Name}}\u003C\u002Fh1>\n",[661,2353,2354],{"class":663,"line":961},[661,2355,2356],{"class":2320},"     \u003C\u002Fsection>\n",[661,2358,2359],{"class":663,"line":969},[661,2360,2361],{"class":2320},"   \u003C\u002Ftemplate>\n",[576,2363,2364,2371,2378,2385],{"start":676},[241,2365,2366,2367,2370],{},"修改 ",[205,2368,2369],{},"src\u002Frouter\u002Findex.ts","，按字母顺序插入路由",[241,2372,2373,2374,2377],{},"在 ",[205,2375,2376],{},"tests\u002Fviews\u002F\u003CName>.spec.ts"," 写入冒烟测试（mount + toMatchSnapshot）",[241,2379,2380,2381,2384],{},"运行 ",[205,2382,2383],{},"pnpm test -- \u003CName>"," 验证通过",[241,2386,2387,2388,2392],{},"调用 git-commit skill，提交信息中文：「feat(view): 新增 ",[2389,2390],"binding",{"value":2391},"Name"," 页面」",[2394,2395,2396],"h1",{"id":2396},"校验清单",[238,2398,2401,2410,2416],{"className":2399},[2400],"contains-task-list",[241,2402,2405,2409],{"className":2403},[2404],"task-list-item",[2406,2407],"input",{"disabled":892,"type":2408},"checkbox"," 路由表按 path 字典序",[241,2411,2413,2415],{"className":2412},[2404],[2406,2414],{"disabled":892,"type":2408}," 页面注释写明\"做什么\"",[241,2417,2419,2421],{"className":2418},[2404],[2406,2420],{"disabled":892,"type":2408}," 冒烟测试通过",[652,2423,2426],{"className":2424,"code":2425,"language":814},[812],"\n这种把\"团队约定 + 命令 + 测试\"打包到一起的写法，是脚手架阶段最值得投资的事。它意味着无论是 Claude 还是新人，第一天就能写出\"团队风格\"的代码，而不是写完之后被 PR review 改个三轮。\n\n---\n\n## 五、风险与边界\n\n### 5.1 Claude 在选型时的偏见（训练数据时间窗口\u002F流行度倾向）\n\nClaude 的\"偏见\"主要来自三处：\n\n1. **训练数据截止日期**：模型对截止日期之后发布的库一无所知。问\"2026 年 4 月发布的 X 怎么用\"它要么承认不知道，要么编造。这就是为什么 6.2 节反复强调要接 MCP。\n2. **流行度倾向**：训练语料里 React\u002FTailwindCSS\u002FNext.js 出现频率远高于小众方案，模型会无意识偏向它们。即使你说\"用 Vue 3\"，它仍会偶尔写出 JSX 风格的伪代码。\n3. **英文偏见**：英文文档密度高，中文最佳实践会被低估。问\"Vue + Element Plus + 中文 a11y 最佳实践\"时，常需要补充本地资料。\n\n应对手法：在 CLAUDE.md 里明确写\"本项目技术栈是 Vue 3 + Vite + TypeScript，禁止建议 React 替代方案\"；并在系统级 CLAUDE.md 写\"假设用户偏好 TS + Vue\"。\n\n### 5.2 工程师不能让渡的决策点（架构\u002F安全\u002F合规）\n\n下列决策永远必须由人做出，AI 只能提供材料：\n\n- 架构边界（哪些是核心域、哪些可以外包给 SaaS）\n- 数据所有权与隐私合规（PII 是否能上第三方 LLM、跨境数据传输）\n- 鉴权方式与会话生命周期\n- 数据库 schema 的主键策略与索引策略（影响多年）\n- 第三方依赖的许可证审查（GPL \u002F AGPL 在商业项目里的传染性）\n- 关键依赖的供应链安全（package squatting、postinstall 脚本）\n\n这些决策不可逆或代价巨大，让 Claude 列候选可以，但拍板必须是工程师\u002F架构师\u002F法务三方签字。\n\n### 5.3 脚手架自动化的反噬（黑箱配置\u002F升级困境）\n\n脚手架越自动，黑箱越深。常见反噬：\n\n- **升级困境**：CRA 当年也曾是\"开箱即用\"，今天没人维护。任何脚手架的核心维护者活跃度，是必须考察的指标。\n- **配置漂移**：脚手架默认配置与最佳实践随版本变化，老项目越拖越偏离主流。\n- **AI 加速失控**：Claude 可以一夜生成 200 个文件，工程师审不过来就 commit。半年后 bug 来了，没人记得这个文件谁写的、为什么这么写。\n\n对策：\n\n1. 把脚手架当作\"一次性脚手架\"，而不是长期依赖。生成完之后所有配置归项目所有，不再受脚手架版本约束。\n2. 对 AI 大批量生成的代码使用\"先 Plan 再 Apply\"双阶段，并在 commit message 标注 `co-authored-by: claude`，便于追责。\n3. 关键配置文件（vite.config \u002F eslint.config \u002F tsconfig）写注释，解释每一项\"为什么这么配\"。半年后回头才看得懂。\n\n下面是本人 vite.config.ts 的\"带注释版\"，可以直接当作团队模板：\n\n```ts\n\u002F\u002F vite.config.ts — 周报工具前端构建配置\n\u002F\u002F 任何一项变更必须同步更新本文件顶部 CHANGELOG，否则 PR 不予合并\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs\u002Fplugin-vue'\nimport { fileURLToPath, URL } from 'node:url'\n\nexport default defineConfig({\n  plugins: [vue()],\n  resolve: {\n    alias: {\n      \u002F\u002F 统一使用 @\u002F 别名，禁止使用相对路径 ..\u002F..\u002F..\u002F\n      '@': fileURLToPath(new URL('.\u002Fsrc', import.meta.url))\n    }\n  },\n  server: {\n    port: 5173,        \u002F\u002F 与团队约定一致，便于 Cypress 默认配置\n    strictPort: true,  \u002F\u002F 端口被占就直接报错而不是 silently 换端口\n    open: false        \u002F\u002F 禁止自动开浏览器，避免远程开发环境弹窗\n  },\n  build: {\n    target: 'es2022',\n    sourcemap: true,   \u002F\u002F 生产 sourcemap，配合 Sentry 解析栈\n    rollupOptions: {\n      output: {\n        \u002F\u002F 简化 chunk 命名便于线上排错\n        chunkFileNames: 'js\u002F[name]-[hash].js',\n        assetFileNames: 'assets\u002F[name]-[hash][extname]'\n      }\n    }\n  },\n  test: {\n    environment: 'jsdom',\n    globals: true,\n    setupFiles: ['.\u002Ftests\u002Fsetup.ts']\n  }\n})\n",[205,2427,2425],{"__ignoreMap":657},[198,2429,2430,2431,2434,2435,2438],{},"这份文件里每条注释都对应一个\"半年后会忘掉的决策\"。例如 ",[205,2432,2433],{},"strictPort: true"," 是因为本人有过一次端口悄悄漂移导致 nginx 反代到错误端口的事故；",[205,2436,2437],{},"sourcemap: true"," 是因为线上一个 1px 像素错位 bug 排查了两天，最后发现 sourcemap 没传 CDN。把这些教训写在配置注释里，比写在 wiki 里更不容易丢。",[791,2440],{},[220,2442,2444],{"id":2443},"六附录常见问题与速查","六、附录——常见问题与速查",[195,2446,2447],{},[198,2448,2449],{},"给产品经理：脚手架阶段是问题最密集的时期，下面这些问答整理自本人和团队过去两年的实战。读到对应场景时回头查即可。",[230,2451,2453],{"id":2452},"_61-我已经有一个老项目要不要重搭脚手架","6.1 我已经有一个老项目，要不要重搭脚手架？",[198,2455,2456],{},"判断依据三条：",[576,2458,2459,2462,2465],{},[241,2460,2461],{},"当前 dev 启动是否超过 30 秒？超过就值得评估迁移到 Vite 系。",[241,2463,2464],{},"CI 构建是否超过 10 分钟？超过就值得引入 Turborepo \u002F Nx 的远程缓存。",[241,2466,2467],{},"团队是否每次升级依赖都\"心里发虚\"？如果是，先补 ADR 和测试覆盖，再谈脚手架重建。",[198,2469,2470,2471,2474],{},"不要为了\"重新感觉良好\"而重搭。脚手架重建的本质成本不在 ",[205,2472,2473],{},"pnpm create","，而在团队几周内 PR review 的混乱。",[230,2476,2478],{"id":2477},"_62-claude-总是推荐-nextjs-tailwind-怎么办","6.2 Claude 总是推荐 Next.js \u002F Tailwind 怎么办？",[198,2480,2481],{},"在仓库根 CLAUDE.md 顶部写：",[652,2483,2485],{"className":854,"code":2484,"language":856,"meta":657,"style":657},"# Stack Guardrails\n\n- 本项目栈：Vue 3 + Vite + TypeScript + Pinia + UnoCSS\n- 禁止建议：React \u002F Next.js \u002F TailwindCSS（除非用户明确询问）\n- 推荐方案前必须先用 npm-registry MCP 验证版本号\n",[205,2486,2487,2494,2498,2505,2512],{"__ignoreMap":657},[661,2488,2489,2491],{"class":663,"line":664},[661,2490,1592],{"class":869},[661,2492,2493],{"class":1115},"Stack Guardrails\n",[661,2495,2496],{"class":663,"line":670},[661,2497,893],{"emptyLinePlaceholder":892},[661,2499,2500,2502],{"class":663,"line":676},[661,2501,1604],{"class":869},[661,2503,2504],{"class":863}," 本项目栈：Vue 3 + Vite + TypeScript + Pinia + UnoCSS\n",[661,2506,2507,2509],{"class":663,"line":682},[661,2508,1604],{"class":869},[661,2510,2511],{"class":863}," 禁止建议：React \u002F Next.js \u002F TailwindCSS（除非用户明确询问）\n",[661,2513,2514,2516],{"class":663,"line":691},[661,2515,1604],{"class":869},[661,2517,2518],{"class":863}," 推荐方案前必须先用 npm-registry MCP 验证版本号\n",[198,2520,2521],{},"这条 guardrails 在每次会话开始时都会注入，能拦住 80% 的\"AI 偏见\"型推荐。",[230,2523,2525],{"id":2524},"_63-多人协作时claudemd-和个人-settings-怎么分","6.3 多人协作时，CLAUDE.md 和个人 settings 怎么分？",[198,2527,2528],{},"按层级：",[238,2530,2531,2537,2543,2549],{},[241,2532,2533,2534,2536],{},"仓库根 ",[205,2535,108],{},"：团队共识，进 git。",[241,2538,2539,2540,2542],{},"仓库 ",[205,2541,1077],{},"：团队工具配置（MCP、hooks），进 git。",[241,2544,2539,2545,2548],{},[205,2546,2547],{},".claude\u002Fsettings.local.json","：个人偏好（端口、API key），加入 .gitignore。",[241,2550,2551,2552,2554],{},"用户级 ",[205,2553,1954],{},"：个人跨项目偏好，比如\"中文回复\"、\"祈使语气\"。",[198,2556,2557],{},"四层叠加，互不污染。本人的全局 CLAUDE.md 里只放偏好和绝对约束，把项目细节留给仓库级文件。",[230,2559,2561],{"id":2560},"_64-什么时候该把脚手架沉淀为内部模板","6.4 什么时候该把脚手架沉淀为内部模板？",[198,2563,2564,2565,2568],{},"经验阈值：当团队连续启动第 3 个相似项目时，把前两个项目的\"共性\"抽出来做成 ",[205,2566,2567],{},"create-\u003Cteam-name>-app","。低于 3 个就抽象，往往是过早抽象，每个项目的差异会迅速吃掉模板的复用价值。抽象时只保留\"几乎所有项目都要的\"内容（lint、tsconfig、CI、CLAUDE.md 模板），把\"业务相关\"的东西留给项目自己。",[230,2570,2572],{"id":2571},"_65-脚手架阶段如何评估-ai-协作的投入产出","6.5 脚手架阶段如何评估 AI 协作的投入产出？",[198,2574,2575],{},"本人会用一份简单的\"AI 协作账单\"表格记录：",[305,2577,2578,2597],{},[308,2579,2580],{},[311,2581,2582,2585,2588,2591,2594],{},[314,2583,2584],{},"任务",[314,2586,2587],{},"人工预估（分钟）",[314,2589,2590],{},"AI 协作实际（分钟）",[314,2592,2593],{},"节省",[314,2595,2596],{},"AI 错误次数",[324,2598,2599,2616,2633,2649,2665],{},[311,2600,2601,2604,2607,2610,2613],{},[329,2602,2603],{},"初始化 Vite + Vue 工程",[329,2605,2606],{},"30",[329,2608,2609],{},"8",[329,2611,2612],{},"73%",[329,2614,2615],{},"0",[311,2617,2618,2621,2624,2627,2630],{},[329,2619,2620],{},"写 ESLint flat config",[329,2622,2623],{},"60",[329,2625,2626],{},"25",[329,2628,2629],{},"58%",[329,2631,2632],{},"1（漏装 plugin）",[311,2634,2635,2638,2641,2644,2647],{},[329,2636,2637],{},"撰写 CLAUDE.md",[329,2639,2640],{},"90",[329,2642,2643],{},"35",[329,2645,2646],{},"61%",[329,2648,2615],{},[311,2650,2651,2654,2657,2659,2662],{},[329,2652,2653],{},"接 Supabase 鉴权",[329,2655,2656],{},"120",[329,2658,2640],{},[329,2660,2661],{},"25%",[329,2663,2664],{},"3（API 已变）",[311,2666,2667,2670,2673,2675,2678],{},[329,2668,2669],{},"配 Vercel 部署",[329,2671,2672],{},"45",[329,2674,2606],{},[329,2676,2677],{},"33%",[329,2679,2680],{},"1",[198,2682,2683,2684,2687],{},"这张表的价值不是\"证明 AI 能省多少时间\"，而是定位\"哪些场景 AI 价值高、哪些场景需要人工兜底\"。从本人的统计看：",[581,2685,2686],{},"纯模板\u002F配置型任务 AI 节省最多，涉及外部 API 实时变化的部分 AI 反而容易拖慢节奏","——这正是 MCP 要解决的问题。把账单坚持记三个月，团队会自然形成\"这件事让 AI 做、那件事自己来\"的肌肉记忆。",[198,2689,2690],{},"脚手架不是一次性动作，而是\"项目身份证\"的初次签发。这一节我们做了三件事：把脚手架的演进与现状串成时间线、把 Claude Code 在选型与初始化阶段的协作姿势固化为可执行步骤、给出一份避坑清单。完成 6.2 之后，团队应该已经拥有可跑的工程骨架、CLAUDE.md、若干 Skills，以及一份选型记录。下一节 6.3 将进入\"核心功能多轮迭代\"——脚手架立起来之后，怎么用 Claude 一周内推出可用 MVP、并保证迭代过程不破坏现有约定。",[198,2692,2693],{},"最后留给读者两个习题，可以在自己项目里立即落地：",[576,2695,2696,2699],{},[241,2697,2698],{},"为当前项目写一份 ADR-001，回答\"为什么用现在这套技术栈\"。如果写不出三条理由，说明选型基础不牢，是时候补课。",[241,2700,2373,2701,2703,2704,2707],{},[205,2702,2209],{}," 下加一个 ",[205,2705,2706],{},"release\u002F"," skill，把\"打 tag → 改 CHANGELOG → 推送\"流程固化下来。下一次发版让 Claude 跑这条 skill，看节省了多少分钟。",[198,2709,2710],{},"这两个习题做完，本章的内容才真正变成你团队的肌肉记忆。脚手架不是\"一次搭好就结束\"的工程动作，而是会随着团队对工具与 Claude Code 协作模式的理解持续演化的\"活文档\"——下一次 PR review 时，回头审视一下今天的 CLAUDE.md，看看还有哪些隐性约定值得显式化，把它们一条条搬到文档里。",[220,2712,2713],{"id":2713},"延伸阅读",[238,2715,2716,2726,2734,2742,2750,2758,2766,2774,2782,2790,2798,2806],{},[241,2717,2718,2725],{},[2719,2720,2724],"a",{"href":2721,"rel":2722},"https:\u002F\u002Fvite.dev\u002Fguide\u002F",[2723],"nofollow","Vite 官方文档"," — 现代前端构建工具的事实标准",[241,2727,2728,2733],{},[2719,2729,2732],{"href":2730,"rel":2731},"https:\u002F\u002Fturborepo.com\u002Fdocs",[2723],"Turborepo 官方文档"," — Monorepo 任务编排与远程缓存",[241,2735,2736,2741],{},[2719,2737,2740],{"href":2738,"rel":2739},"https:\u002F\u002Fwww.typescriptlang.org\u002Fdocs\u002Fhandbook\u002Fintro.html",[2723],"TypeScript Handbook"," — TS 官方教程，配置 tsconfig 必读",[241,2743,2744,2749],{},[2719,2745,2748],{"href":2746,"rel":2747},"https:\u002F\u002Fcn.vuejs.org\u002Fguide\u002Fintroduction.html",[2723],"Vue 3 官方指南"," — Composition API、SFC、生态总览（中文）",[241,2751,2752,2757],{},[2719,2753,2756],{"href":2754,"rel":2755},"https:\u002F\u002Freact.dev\u002Flearn",[2723],"React 官方文档"," — 含官方推荐脚手架与元框架建议",[241,2759,2760,2765],{},[2719,2761,2764],{"href":2762,"rel":2763},"https:\u002F\u002Fpnpm.io\u002Fzh\u002Fmotivation",[2723],"pnpm 文档"," — 包管理与 workspace 设计哲学",[241,2767,2768,2773],{},[2719,2769,2772],{"href":2770,"rel":2771},"https:\u002F\u002Fcode.claude.com\u002Fdocs",[2723],"Anthropic Claude Code 官方文档"," — Claude Code 安装、Plan 模式、Skills、Hooks 全览",[241,2775,2776,2781],{},[2719,2777,2780],{"href":2778,"rel":2779},"https:\u002F\u002Fmodelcontextprotocol.io\u002Fintroduction",[2723],"Model Context Protocol 规范"," — MCP 协议本身与生态服务器列表",[241,2783,2784,2789],{},[2719,2785,2788],{"href":2786,"rel":2787},"https:\u002F\u002Fcontext7.com\u002F",[2723],"context7 项目主页"," — 实时文档 MCP 服务，缓解 LLM 训练数据过时问题",[241,2791,2792,2797],{},[2719,2793,2796],{"href":2794,"rel":2795},"https:\u002F\u002F12factor.net\u002Fzh_cn\u002F",[2723],"The Twelve-Factor App"," — 现代应用架构经典原则，选型时的\"对照基线\"",[241,2799,2800,2805],{},[2719,2801,2804],{"href":2802,"rel":2803},"https:\u002F\u002Fgithub.com\u002Fhesreallyhim\u002Fawesome-claude-code",[2723],"Awesome Claude Code"," — 社区维护的 Claude Code 资源集",[241,2807,2808,2813],{},[2719,2809,2812],{"href":2810,"rel":2811},"https:\u002F\u002F2024.stateofjs.com\u002F",[2723],"State of JS 2024"," — 前端生态年度调查，选型参考数据来源之一",[2815,2816,2817],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sJsPd, html code.shiki .sJsPd{--shiki-light:#90A4AE90;--shiki-default:#EEFFFF90;--shiki-dark:#BABED890}",{"title":657,"searchDepth":664,"depth":670,"links":2819},[2820,2825,2832,2838,2843,2850],{"id":222,"depth":670,"text":223,"children":2821},[2822,2823,2824],{"id":232,"depth":676,"text":233},{"id":295,"depth":676,"text":296},{"id":567,"depth":676,"text":568},{"id":795,"depth":670,"text":796,"children":2826},[2827,2828,2829,2830,2831],{"id":804,"depth":676,"text":805},{"id":838,"depth":676,"text":839},{"id":988,"depth":676,"text":989},{"id":1013,"depth":676,"text":1014},{"id":1043,"depth":676,"text":1044},{"id":1278,"depth":670,"text":1279,"children":2833},[2834,2835,2836,2837],{"id":1287,"depth":676,"text":1288},{"id":1485,"depth":676,"text":1486},{"id":1501,"depth":676,"text":1502},{"id":1543,"depth":676,"text":1544},{"id":1706,"depth":670,"text":1707,"children":2839},[2840,2841,2842],{"id":1715,"depth":676,"text":1716},{"id":1938,"depth":676,"text":1939},{"id":1958,"depth":676,"text":1959},{"id":2443,"depth":670,"text":2444,"children":2844},[2845,2846,2847,2848,2849],{"id":2452,"depth":676,"text":2453},{"id":2477,"depth":676,"text":2478},{"id":2524,"depth":676,"text":2525},{"id":2560,"depth":676,"text":2561},{"id":2571,"depth":676,"text":2572},{"id":2713,"depth":670,"text":2713},"md",null,{"date":2854},"2026-04-26",{"title":134,"description":657},"9n_JqB-7NVt-eS2h2bPmE5zaLrIjkRzMd4RWZeChRQU",[2858,2860],{"title":130,"path":131,"stem":132,"description":2859,"children":-1},"与 Claude 协作完成",{"title":138,"path":139,"stem":140,"description":2861,"children":-1},"多轮迭代开发",1777395309977]