Monkeytype 前端工程规范实战:SolidJS 渐进迁移、oxlint 类型检查与 Tailwind 样式约定
发布时间:2026/9/20 22:39:04 作者:尧图编辑部 阅读量:1,286

Monkeytype 前端工程规范实战SolidJS 渐进迁移、oxlint 类型检查与 Tailwind 样式约定【免费下载链接】monkeytypeThe most customizable typing website with a minimalistic design and a ton of features. Test yourself in various modes, track your progress and improve your speed.项目地址: https://gitcode.com/gh_mirrors/mon/monkeytype本篇指南围绕 Monkeytype 仓库根目录的 CLAUDE.md 展开它是为 AI 协作开发尤其是 Claude 这类编码 Agent设计的工程约定文件系统规定了 Monkeytype 前端的代码组织、工具链与风格纪律。读完本文你将掌握新老两代代码SolidJS.tsx与原生 TS如何共存演进、如何用pnpm vitest run精确运行单个测试文件、为何用oxlint --type-aware --type-check取代tsc做类型检查以及 Tailwindcn工具函数与Fa图标组件的正确打开方式可直接在 frontend 目录下落地执行。一、CLAUDE.md 的定位一份面向 Agent 的工程契约Monkeytype 是一个以高度可定制、极简设计、功能丰富著称的打字练习网站仓库采用 pnpm workspace 多包结构pnpm-workspace.yaml前端位于 frontend后端位于 backend。根目录的 CLAUDE.md 只有 8 条规则看似简短却是Be extremely concise极度简洁宁牺牲语法也要精简这一总原则的自我践行——它不重复通用知识只记录在这个仓库里必须遵守、且与常规习惯不同的约定。从源码结构看这份文件的读者对象是编码 Agent 与新人开发者它覆盖了前端迁移状态第 2 条、测试命令第 3 条、Lint 与类型检查第 4、5 条、样式与图标第 6、7 条、计划模式工作流第 8 条。下文逐条拆解并给出仓库内的实现证据。二、沟通与注释风格牺牲语法换取信息密度第 1 条 Be extremely concise. Sacrifice grammar for concision. 是整份文档的基调。它意味着在代码评审意见、PR 描述、Agent 生成的注释与回复中优先保证信息量不做客套铺垫。例如能用短语说清的不用完整句子省略冠词、被动语态与修饰性文字每条意见独立成行便于逐条勾选确认。这与仓库 AGENTS 体系根目录另有 AGENTS.md的目标一致让人类与 AI 的协作成本降到最低把注意力留给打字测试引擎、主题系统、成绩统计等真正的业务逻辑。三、前端双轨制SolidJS.tsx新组件与原生 TS 遗留代码共存第 2 条 Frontend is partially migrated from vanilla JS to SolidJS — new components use.tsx, legacy code remains vanilla 揭示了 Monkeytype 前端正处于渐进式重构阶段理解这一点是读懂整个前端目录结构的前提。3.1 新代码SolidJS 组件新组件统一使用.tsx扩展名并引入solid-js集中在 frontend/src/ts/components共 197 个文件其中 191 个.tsx。例如 AnimatedModal.tsx、Button.tsx、User.tsx 等。依赖侧同样完整solid-js1.9.13与vite-plugin-solid2.11.11见 frontend/package.json 的 devDependenciesSolidJS 生态全家桶tanstack/solid-query、tanstack/solid-form、tanstack/solid-hotkeys、tanstack/solid-table、tanstack/solid-db测试配套solidjs/testing-library、solid-devtools/overlay。构建侧由 vite.config.ts 挂载solidPlugin测试侧 vitest.config.ts 同样加载vite-plugin-solidhot: false确保组件测试运行在真实 SolidJS 运行时之上。3.2 旧代码原生 TS 保持不动未迁移的部分继续使用普通.ts与原生 DOM 操作。典型如 commandline.ts其中大量使用element.classList.add/remove这类命令式 API见第 594、606 行附近。这条规则的关键含义是在遗留文件中开发时不要顺手局部现代化保持文件内部风格统一将重构留给专门的迁移任务新功能则一律落到.tsx。四、测试用pnpm vitest run精确运行单个文件第 3 条给出了单测的标准姿势pnpm vitest run path/to/test.ts仓库统一使用 Vitestfrontend/package.json 中test: vitest runvitest4.1.0。测试文件按功能目录镜像放置例如commandline/util.spec.tscomponents/common 下的 6 个组件测试test/funbox.spec.ts、utils/strings.spec.ts 等两个关键实践点务必带runvitest run是一次性执行非 watch 模式适合 CI 与 Agent 自验证交互式 watch 请用pnpm dev-testconcurrently vite dev vitest。路径要精确单文件调试时直接传相对路径例如pnpm vitest run frontend/__tests__/utils/strings.spec.ts避免全量跑测试带来的时间开销。测试环境由 global-setup.ts 与__harness__mock-dom.ts、mock-firebase.ts、mock-env-config.ts等支撑DOM 层同时备有jsdom与happy-dom两套实现。五、Lint 与类型检查oxlint 一肩挑--format agent喂给 Agent第 4、5 两条共同定义了 Monkeytype 的静态检查策略第 4 条运行 oxc lint 时始终加--format agent第 5 条类型检查使用pnpm oxlint --type-aware --type-check而不是tsc。5.1 为什么用 oxlint 替代 tscfrontend/package.json 的脚本给出完整矩阵lint: oxlint . --type-aware --type-check, lint-fast: oxlint ., lint-styles: stylelint \**/*.{scss,css}\oxlint1.77.0由 Rust 编写OXC 项目lint 速度远快于 ESLint/tsc 链路且配合oxlint-tsgolint7.0.2001提供--type-aware --type-check能力将Lint 类型检查合并为一条命令。仓库通过 workspace 包 packages/oxlint-config 统一规则index.jsonc 声明插件typescript、unicorn、oxc、import、node、promiseoverrides.jsonc 按文件类型细分覆盖规则。lint-staged 钩子同样使用oxlint --type-aware --type-check见 frontend/package.json 的lint-staged配置保证提交前自动执行同一套检查。5.2--format agent的用途--format agent会输出面向 AI Agent 的机器可读格式让 Agent 能稳定解析错误位置与规则名并直接修复而不是依赖人类阅读的终端着色输出。这是 Agent 场景的硬性要求在 packages/oxlint-config 的相关脚本与 lint-staged 中保持一致。注仓库仍保留ts-check: tsc --noEmit与tsc: tsc脚本供需要完整类型推导结果的场景使用但日常开发与 CI 以 oxlint 为准。六、样式纪律Tailwind class 属性 cn工具函数第 6 条是前端样式三条铁律使用 Tailwind CSS使用 class 属性与cn工具函数不要用 classList颜色只能用 Tailwind 配置中定义的那些。6.1cn工具函数cn的实现位于 frontend/src/ts/utils/cn.ts仅 6 行import { twMerge } from tailwind-merge; import { ClassValue, clsx } from clsx; export function cn(...input: ClassValue[]): string { return twMerge(clsx(...input)); }它把clsx条件类名合并与tailwind-mergeTailwind 类名冲突去重串起来。典型用法是条件渲染类名并让后者覆盖前者div class{cn(text-sm, isActive text-accent, props.class)} /6.2 为什么禁用 classList遗留代码如 commandline.ts 的element.classList.add(active)是命令式 DOM 操作而 SolidJS 的响应式模型要求类名跟随状态声明式地变化——直接绑定class属性由框架自动 diff。同时tailwind-merge依赖字符串形式的类名输入无法处理classList增量操作。因此新代码一律通过class{...}与cn(...)表达React/Solid 混合心智的开发者也能无缝上手。6.3 受控调色板Tailwind 配置tailwind.css 及tailwindcss/vite4.3.2定义了项目语义色板样式代码只能引用配置内存在的颜色令牌不得随手写十六进制色值或任意外部调色板从而保证 52 套主题见 frontend/static/themes与全局配色的可管理性。七、图标规范遗留代码用i新代码用Fa组件第 7 条 In legacy code, useitags with FontAwesome classes. In new code, useFacomponent. 是图标渲染的统一约定。7.1 遗留代码继续使用 FontAwesome 经典写法i classfas fa-bolt/i仓库依赖fortawesome/fontawesome-free5.15.4并通过fontawesome-subset插件见 vite-plugins按需裁剪图标减小产物体积。7.2 新代码Fa组件Fa组件定义在 frontend/src/ts/components/common/Fa.tsx底层仍渲染i但封装了 FontAwesome 变体选择与常见修饰export function Fa(props: FaProps): JSXElement { const variant (): string props.variant ?? solid; return ( i class{cn( props.icon, { fas: variant() solid, far: variant() regular, fab: variant() brand, fa-fw: props.fixedWidth, fa-spin: props.spin, }, props.class, )} style{{ font-size: props.size ! undefined ? ${props.size}em : undefined, }} /i ); }属性一览属性类型默认值作用iconstringFaObject 必填—FontAwesome 图标类名如fa-circle-notchvariantsolid \| regular \| brandsolid对应fas/far/fab前缀fixedWidthbooleanfalse添加fa-fw固定宽度spinbooleanfalse添加fa-spin旋转动画sizenumber—以 em 为单位的字号font-size: ${size}emclassstring—附加类名经cn合并组件内示例LoadingCircle.tsx、User.tsxFa iconfa-circle-notch fixedWidth spin /新代码不再手写i classfas ...而是通过Fa的 props 表达意图方便类型检查与后续统一替换。八、计划模式工作流先澄清再交付第 8 条规定了 Agent 在计划模式下的行为契约写计划前如有必要先向用户提出澄清问题避免基于臆测做方案计划末尾给出待解答问题清单unresolved questions逐条列明仍需用户拍板的点且保持简洁。这对 Monkeytype 这类大型 monorepo 尤为重要——例如改动涉及 frontend/src/ts 与 backend/src 的跨端契约monkeytype/contracts、monkeytype/schemas等 workspace 包时一次澄清能省下整轮返工。实践上Agent 应在计划正文前完成提问把假设显式化为待确认项而不是把未验证的假设写进最终方案。九、把规范落地一份 Agent 与开发者共用的速查清单场景命令 / 写法跑单个测试pnpm vitest run path/to/test.tsLint 类型检查pnpm oxlint --type-aware --type-checkAgent 场景加--format agent新前端组件SolidJS.tsx用classcn不用 classList新图标Fa iconfa-... /不用手写i遗留文件保持 vanilla 风格使用classList与i classfas ...样式颜色仅使用 Tailwind 配置定义的颜色计划模式先澄清末尾附未解决问题清单上述约定共同服务于一个目标在打字测试网站这个快速迭代的项目里让人类开发者与 AI Agent 遵循同一套可验证的工程标准。仓库以 CLAUDE.md 为入口配合 AGENTS.md、packages/oxlint-config 与 frontend/package.json 中的脚本把规范变成了可直接执行的命令与可静态检查的代码约束。新贡献者只需对照本指南的速查清单即可在 frontend 中写出风格统一、检查通过的代码。【免费下载链接】monkeytypeThe most customizable typing website with a minimalistic design and a ton of features. Test yourself in various modes, track your progress and improve your speed.项目地址: https://gitcode.com/gh_mirrors/mon/monkeytype创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考