关于 tech-stack
为 FixMyBerlin/FMC 的地理应用 React 单页应用提供默认技术栈与约定,面向创建或修改应用的开发者,并链接专项技能和配置模板。
主要功能
- 01React 19 与 TypeScript 默认配置
- 02Bun 和 Vite 构建约定
- 03地理与地图库选择
- 04Lint、格式化与浏览器目标
- 05数据、状态与样式方案
- 06脚手架和 CI 模板
适用场景
- 01为新的地理类 React 应用选择技术栈
- 02检查依赖与全局应用约定
- 03配置脚本、TypeScript 和工具
- 04查找地图或测试专项指引
MCP 相关
包含 Claude Code MCP 设置指引,用于检查 Postgres 模式、查询数据库和浏览器探索,并引用配置模板及相关文档。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fixmyberlin/ fixmyskills --skill tech-stack安装后在 Claude Code 中输入/tech-stack确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/bunfig.netlify.toml.templatebunfig.toml.templateci.yml.templatedependabot.yml.templateknip.config.mjs.templatemcp.json.templateoxfmt.config.mjsoxlint.config.mjspackage-json-scripts.md.templatetsconfig.app.jsontsconfig.scripts.jsonvscode.extensions.json.templatevscode.settings.typescript.json.templateexamples/husky/ensure-bun.sh.templatepre-push.templatereferences/agent-browser-mcp.mdbrowser-target.mdbun-install-verify.mdbun-install.mddependabot.mdknip.mdllm-resources.mdoxc-config.mdpackage-json-scripts.mdpostgres-mcp.md详细介绍
FMC 技术栈
FixMyBerlin / FMC 中以地理信息为主的 React SPA 默认技术栈。用于创建或修改应用时的技术决策,而非深入介绍某个库。
请单独安装相关技能:bunx skills add FixMyBerlin/fixmyskills --skill <name> -g -a claude-code -y
何时使用
- 从头搭建应用(依赖项、工具、文件夹布局)
- 添加或重命名
package.json脚本 - 选择库或模式(“我们应该使用 X 吗?”)
- 审查现有应用中的跨领域约定
- 为 Claude Code 配置 MCP,用于检查 Postgres 架构、查询 Agent 数据库或通过 MCP 浏览器进行探索
LLM 资源
仅针对任务涉及的领域加载 references/llm-resources.md。
**地图:**加载技能 react-map-gl(以及该技能指向的上游 React Map GL 文档)。
专项技能
请按名称引用技能;如缺少,请使用上面的命令安装。
| 领域 | 技能 |
|---|---|
| Rust/WASM 地理信息 | rust-wasm-geo |
| 地图(react-map-gl) | react-map-gl |
| React TS 模式、useEffect 使用规范 | react-dev |
| TanStack Router(搜索、加载器、Query) | tanstack-router-conventions(参考:漂亮 URL 使用 params-search-ui-routes.md、router-search-serialization.md,另有 router-and-query.md、devtools.md) |
| TanStack Start(边界、SSR、服务端) | tanstack-start-conventions(文件夹布局参考 app-structure.md) |
| URL 状态(搭配 TanStack Router) | tanstack-router-conventions → params-search-ui-routes.md |
| URL 状态(不使用 Router 的 Vite 应用) | nuqs |
| 客户端全局状态 | zustand-state-management |
| Prisma 架构命名、迁移 | prisma |
| E2E / Playwright | playwright-skill |
运行时和构建
- 运行时 / 包管理器:Bun——安装策略见 bun-install.md(≥ 1.3.14、全局存储、Vite 使用
bun --bun、Prisma/Playwright 使用.nvmrc;Docker 镜像安装和 Netlify 函数打包) - **构建:**最新版本的 Vite(8+)
- **Lint / 格式化:**使用带修复标志的 oxlint 和 oxfmt;兼容 Prettier 的默认设置:
- 类排序、导入排序、
package.json排序 printWidth100、分号asNeeded、单引号'typescript/switch-exhaustiveness-check': 'error'- React Compiler:oxlint
react插件 +'react/unsupported-syntax': 'error';通过viteReact({ compiler: true })+oxc-transform-react使用 Vite(不使用 Babel) - 模板:examples/oxfmt.config.mjs、examples/oxlint.config.mjs
- 设置和各项目调优:references/oxc-config.md
- 类排序、导入排序、
- 客户端浏览器目标:
package.json中的browserslist决定 Vite 客户端的build.target和 oxlint 中的eslint-plugin-compat——references/browser-target.md
React 和 TypeScript
- UI: React 19
- TypeScript(默认):
typescript@^7(原生移植版;7.0 版本发布)。通过bun run type-check使用tsc --noEmit进行类型检查。工作区的typescript包同时提供 CLI(tsc)和编辑器语言服务——不要额外添加单独的编译器二进制文件来进行类型检查。Nightly 版本:typescript@next(而非已弃用的@typescript/native-preview包)。 - 编辑器/CLI 对齐:
js/ts.tsdk.path必须指向与tsc相同的devDependencies.typescript安装位置(包根目录,而非lib/)。若两者不一致,IDE 诊断结果就会与bun run type-check不同。 - 脚手架(TS 7):
package.json—devDependencies.typescript使用^7,脚本为"type-check": "tsc --noEmit"(使用拆分的 tsconfig 时添加-p);当 CI 运行平台与开发平台不同时,在optionalDependencies中以相同版本固定@typescript/typescript-darwin-arm64/@typescript/typescript-linux-x64(typescript包将这些列为可选依赖——按需扩展到其他平台)。bunfig.toml— bun-install.md。提交.vscode/settings.json(模板:examples/vscode.settings.typescript.json.template),并在.vscode/extensions.json中推荐 TypeScript 7 扩展(examples/vscode.extensions.json.template)。 - Monorepo: 当 TypeScript 位于包的子文件夹中时,将
js/ts.tsdk.path指向该包下的node_modules/typescript(例如app/node_modules/typescript— tilda-geo)。 - Cursor / VS Code: 安装 TypeScript 7(
TypeScriptTeam.native-preview— Marketplace ID 不变)。通过命令面板中的 TypeScript: Enable TypeScript 7 或设置模板启用。将 examples/vscode.settings.typescript.json.template 复制到.vscode/settings.json(与 references/oxc-config.md 中的 oxc 配置项合并)。当编辑器插件仍需要 TS 6 时,使用 Disable TypeScript 7 Language Server 切换回去(Vue、Astro、Svelte、Angular 模板——参见发布说明)。 - Claude Code MCP(用户级): 仅使用
claude mcp add --scope user(~/.claude.json)— examples/mcp.json.template。Postgres:references/postgres-mcp.md。浏览器探索:references/agent-browser-mcp.md。 - Claude Code 规则(应用级): 搭建脚手架时,将 examples/package-json-scripts.md.template 复制到
.claude/rules/package-json-scripts.md— references/package-json-scripts.md
验证: 运行 node -e "console.log(require('typescript/package.json').version)"、tsc --version 和 bun run type-check — 结果都应为 7.x。在编辑器中确认已启用 TypeScript 7(状态栏 / 命令面板)。对于没有 TS 源码的仓库(例如此 skills monorepo),不要添加 typescript。
- React Compiler: 默认启用——有关记忆化和类型约定,请参阅技能
react-dev - GeoJSON: 所有 GeoJSON 负载均使用
@types/geojson - 日期 / 时间:
@date-fns/tz - 验证: Zod 4
tsconfig 模板
使用 两个配置——不要将应用和脚本合并到一个配置中。
| 配置 | 模板 | 配置对应项 |
|---|---|---|
| 应用(DOM、TanStack Start) | examples/tsconfig.app.json | total-typescript bundler/dom |
| 脚本(CLI、无 DOM) | examples/tsconfig.scripts.json | total-typescript bundler/no-dom |
必需的类型包:只要 compilerOptions.types 包含 bun-types / web,就必须安装这些类型包——它们是 npm 包,不是内置类型。将它们作为直接 devDependencies 安装(Knip 和 globalStore 不会将传递依赖视为你的依赖——knip.md / bun-install.md):
@types/bun固定为 Bun 最低版本(1.3.14)bun-types作为直接依赖(版本范围为该最低版本的^)——types会查找名为bun-types的包;仅安装@types/bun不够- 如果配置中列出了
"web",则安装@types/web
脚本配置(types: ["bun-types"])即使没有 DOM,也仍然需要 @types/bun 和 bun-types。Bun 脚本应使用 Glob / Bun.file();只有安装这些依赖后,类型检查才安全,否则 Agent 会退回使用 node:fs。
创建脚手架时复制并调整。根据项目布局调整 paths(./src/* 与 ./*)。只有仓库仍包含 .js 文件时,才添加 allowJs: true。
TanStack Start(仅应用): verbatimModuleSyntax: false——仅类型导入可能变成空的运行时导入,导致服务端代码泄漏到客户端 bundle 中。参见 tsconfig.app.json 中的头部注释。
绝不要安装或 extends @total-typescript/tsconfig——将设置内联,并添加偏离默认值的注释。
类型检查:
tsc --noEmit -p tsconfig.app.json && tsc --noEmit -p tsconfig.scripts.json
单配置仓库(例如,一个根目录下的 tsconfig.json 同时涵盖应用和脚本)可以接受;全新 TanStack Start 应用应优先使用拆分配置。
Astro / 单配置: 保留 extends: astro/tsconfigs/strict。将 types 设为 ["bun-types", "web"]。不要添加 vite/client(Astro 客户端类型来自 .astro/types.d.ts)。同一 tsconfig 中的脚本仍需要 Bun 类型(与上面相同的包)。
可选:在根目录的 tsconfig.json 中通过 "references" 引用两个子配置。
ES2025: target 和 lib 保持同步。新的 ES2025 运行时 API:客户端应审慎使用;服务端 / Bun / 脚本中可放心使用。哪些浏览器会获取该客户端 bundle:references/browser-target.md。
组件类型、Compiler、oxlint React 规则以及 useEffect 使用规范:技能 react-dev。地图相机、点击和图层:技能 react-map-gl(不要使用 useEffect + map.on())。
数据与状态
| 需求 | 选择 |
|---|---|
| 服务端 / 异步数据 | TanStack Query — 不使用原始 useEffect 获取数据;路由支持时使用 Suspense |
| 表单(非简单表单) | TanStack Form |
| 路由 | TanStack Router / Start |
| 可分享的 URL 状态(使用 TanStack Router) | 路由的 validateSearch(Zod),绝不使用 nuqs — 参见 tanstack-router-conventions → params-search-ui-routes.md |
| 可分享的 URL 状态(不使用 TanStack Router 的 Vite 应用) | nuqs — 参见技能 nuqs |
| 高频 URL 更新 | @tanstack/react-pacer — 参见 https://tanstack.com/pacer/latest |
| 全局客户端状态 | Zustand(tkdodo 模式)— 技能 zustand-state-management |
| 本地 UI 状态 | useState |
| Prisma 架构 / 迁移 | 技能 prisma — 命名、关系字段、迁移工作流 |
Loader + Query 集成:技能 tanstack-router-conventions → router-and-query.md。
样式与 UI
- CSS: Tailwind CSS、
@tailwindcss/forms、@tailwindcss/typography - 类名合并: 使用
twJoin、twMerge的tailwind-merge - 字体: Fontsource 导入
- 无障碍: 语义化 HTML;支持键盘操作的地图控件
地图与地理信息(JS)
仅列出技术选型——地图组件模式、图层、事件、URL 视口:参阅技能 react-map-gl。
| 选项 | 默认值 |
|---|---|
| 库 | react-map-gl/maplibre(不要在组件中直接使用 MapLibre) |
| 底图 | OpenFreeMap;如有需要,可使用 Maptiler |
| 坐标 | API 边界使用 WGS84;使用 Zod 验证 |
| Turf | 按函数导入 @turf/*,不要使用 import * as turf |
| 要素编辑 | @osm-editor-kit/react-map-gl-draw(受控的 value / onChange,样式采用图层样式);示例:tilda-geo 绘图。之前用过,也仍可作为备选方案:TerraDraw 搭配 maplibre-gl-terradraw |
Rust / WASM 地理信息
Turf 与 WASM 的对比、crate、Vite 接线:参阅技能 rust-wasm-geo。
依赖更新(Dependabot)
- 按项目类型安排计划 — 不确定时使用 AskUserQuestion。FixMyCity:每周一。Private OSS 和 Astro:每月第一个星期五。使用相同模板。详情:dependabot.md。
- 每个生态系统同时只保留一个未关闭的 PR(
open-pull-requests-limit: 1)。 - 模板:examples/dependabot.yml.template
- 审查和合并 PR: 使用技能
review-dependabot(更新日志分流、风险分级、变基合并)
CI(GitHub Actions)
- PR 依赖项审查:使用限制较宽松的
allow-licenses(不要使用已弃用的deny-licenses);如果项目采用 AGPL,请包含AGPL-3.0和AGPL-3.0-or-later— 模板:examples/ci.yml.template
测试与质量
| 需求 | 技能 / 工具 |
|---|---|
| 单元 / 组件测试 | Vitest(始终使用) |
| 跨路由、地图或身份验证流程 | playwright-skill |
| 仅纯逻辑 / 工具函数 | Vitest — 跳过 Playwright |
| 显式依赖 / 无用导出 | knip.md · 验证脚本:package-json-scripts.md |