mcpField
H
hairy

hairy

github.com/hairyf开发26629 次安装2 周前更新
代码仓库

关于 hairy

这是一项面向 TypeScript 和 JavaScript 工具链项目的个人 Web 开发偏好技能,说明常用技术栈、架构指引、依赖维护方式,以及 lint 和 typecheck 等质量检查要求。

主要功能

  1. 01使用 pnpm 管理包
  2. 02Strict TypeScript 与 ESM 偏好
  3. 03使用 @antfu/eslint-config lint
  4. 04Vitest 测试约定
  5. 05架构与依赖指导
  6. 06Lint 和 typecheck 完成门槛

适用场景

  1. 01使 Web 项目符合 Hairyf 的工具偏好
  2. 02为项目或迁移选择架构
  3. 03使用 taze 保持依赖更新
  4. 04配置 lint、测试和文档

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hairyf/skills --skill hairy

安装后在 Claude Code 中输入/hairy确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
antfu-eslint-config.md
app-development.md
core-arch-upkeep-routing.md
core-deps-taze.md
core-lint-typecheck.md
core-unjs-preferences.md

详细介绍

Hairyf 的偏好设置

本 skill 涵盖 Hairyf 在 Web 开发中偏好的工具链、配置和最佳实践。本 skill 带有明确的主观倾向。

快速摘要

类别偏好
包管理器pnpm
语言TypeScript(严格模式)
模块系统ESM("type": "module")
Lint 与格式化@antfu/eslint-config(不使用 Prettier)
测试Vitest
Git Hookssimple-git-hooks + lint-staged
文档VitePress(位于 docs/)

全局偏好

应当尽可能遵循的高层级通用偏好:

“specify” 关键字

当某个任务被标记为 “specify”(例如:“specify this repo according to hairy”)时:

  • 将其视为一个请求:检查当前项目,并在合理可行的范围内对其进行优化,使其尽可能符合这些偏好。
  • 具体来说,这应当触发:
    • 通过 @skills/arch-upkeep 及相关 arch-* skills 进行架构检测和升级规划。
    • 感知偏好的技术栈选型(优先通过 @skills/unjs 选择 unjs 生态)。
    • 通过 @skills/taze 进行依赖新鲜度检查与升级。
    • 在认为 “specify” 任务完成之前,最后执行一遍 lint + typecheck(如有测试也一并运行)。
优先选择 unjs 生态框架
  • 在选择框架或运行时(SSR、API、工具链、开发服务器等)时,优先选择 unjs 生态项目(例如 Nuxt、Nitro、h3、unstorage、unplugin、unocss、ofetch 以及其他由 unjs 维护的工具)。
  • 只有在有明确且合理的理由时(缺少功能、生态限制或历史遗留问题),才退而选择非 unjs 方案。
  • 对于具体选择,委托给 @skills/unjs。
架构必须映射到 arch-* skills

项目的架构应始终映射到某个规范的 arch-* skill(tsdown、CLI、monorepo、webext、vscode)。

  • 当当前形态无法干净地映射到任何目标架构时,将其视为一个 arch-* skill,并规划迁移,而不是继续添加临时结构。
  • 使用 @skills/arch-upkeep 来:
    • 检测当前架构。
    • 推荐目标 arch-* skill。
    • 编排向该架构的增量迁移。
使用 taze 保持依赖新鲜
  • 依赖应当持续保持新鲜,而不仅仅是在大规模重构期间。
  • 优先使用 taze(参见 @skills/taze)来:
    • 审计过时的依赖。
    • 执行受控升级(定期升级 minor/patch;major 需明确审查)。
    • 使用 pnpm workspaces 和 catalogs 在 monorepo 中对齐版本。
  • 避免手动编辑 package.json 中的版本,除非有特定理由不遵循 taze 的建议。
始终以 lint + typecheck 收尾
  • 在实现任何非平凡的更改(功能、重构、配置变更、依赖升级、CI 变更等)之后,在认为任务完成之前,始终运行 lint 和 typecheck。
  • 标准脚本:
    • nr lint → 通过 @antfu/eslint-config 运行 ESLint。
    • nr typecheck → 以严格模式进行 TypeScript 类型检查(全项目范围)。
  • 对于 CI 和 Git Hooks:
    • 确保 pre-commit hooks 至少对暂存文件运行 lint。
    • 确保 GitHub Actions(或其他 CI)在 PR 和 main 推送时同时运行 lint 和 typecheck。

核心技术栈

包管理器(pnpm)

使用 pnpm 作为包管理器。

对于 monorepo 设置,使用 pnpm workspaces:

# pnpm-workspace.yaml
packages:
  - 'packages/*'

在 pnpm-workspace.yaml 中使用 pnpm 具名 catalogs 来管理依赖版本:

Catalog用途
prod生产依赖
inlined由打包器内联的依赖
dev开发工具(linter、打包器、测试、开发服务器)
frontend打包进前端的前端库

Catalog 名称不限于以上这些,可以根据需要进行调整。避免使用默认 catalog。

@antfu/ni

使用 @antfu/ni 统一包管理器命令。它会根据 lockfile 自动检测包管理器(pnpm/npm/yarn/bun)。

命令描述
ni安装依赖
ni <pkg>添加依赖
ni -D <pkg>添加开发依赖
nr <script>运行脚本
nu升级依赖
nun <pkg>卸载依赖
nci干净安装(类似 pnpm i --frozen-lockfile)
nlx <pkg>执行包(类似 npx)

如果找不到这些命令,请使用 pnpm i -g @antfu/ni 全局安装。

TypeScript(严格模式)

始终使用启用了严格模式的 TypeScript。

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  }
}
ESM(ECMAScript 模块)

始终在 ESM 模式下工作。在 package.json 中设置 "type": "module"。


代码质量

ESLint (@antfu/eslint-config)

使用 @antfu/eslint-config 进行格式化和 lint。这消除了对 Prettier 的需求。

创建 eslint.config.js,并添加 // @ts-check 注释:

// @ts-check
import antfu from '@antfu/eslint-config'

export default antfu()

向 package.json 添加脚本:

{
  "scripts": {
    "lint": "eslint ."
  }
}

当遇到 lint 错误时,尝试使用 nr lint --fix 修复它们。不要添加 lint:fix 脚本。

Git 钩子(simple-git-hooks + lint-staged)

使用 simple-git-hooks 配合 lint-staged 进行提交前 lint:

{
  "simple-git-hooks": {
    "pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && npx lint-staged"
  },
  "lint-staged": {
    "*": "eslint --fix"
  },
  "scripts": {
    "prepare": "npx simple-git-hooks"
  }
}
单元测试(Vitest)

使用 Vitest 进行单元测试。

{
  "scripts": {
    "test": "vitest"
  }
}

约定:

  • 将测试文件放在源文件旁边:foo.ts → foo.test.ts(同一目录)
  • 高级测试放在每个包的 tests/ 目录中
  • 使用 describe 和 it API(而非 test)
  • 使用 expect API 进行断言
  • 仅将 assert 用于 TypeScript 空值断言
  • 使用 toMatchSnapshot 进行复杂输出断言
  • 使用带有显式文件路径和扩展名的 toMatchFileSnapshot 处理特定语言的输出(从 lint 中排除这些文件)

项目设置

发布(库项目)

对于库项目,通过由 bumpp 触发的 GitHub Releases 进行发布:

{
  "scripts": {
    "release": "bumpp -r"
  }
}
文档(VitePress)

使用 VitePress 编写文档。将文档放在 docs/ 目录下。

docs/
├── .vitepress/
│   └── config.ts
├── index.md
└── guide/
    └── getting-started.md

向 package.json 添加脚本:

{
  "scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs"
  }
}

参考

全局偏好
主题描述参考
偏好 unjs 生态优先使用 unjs 生态的框架和工具;委托给 @skills/unjscore-unjs-preferences
通过 arch-* 进行架构将仓库形态映射到规范的 arch-* 技能,并通过 arch-upkeep 升级core-arch-upkeep-routing
使用 taze 保持依赖新鲜使用 taze 和受控升级保持依赖持续新鲜core-deps-taze
Lint + 类型检查作为门槛始终在本地和 CI 中以 lint + 类型检查收尾core-lint-typecheck
项目设置
主题描述参考
@antfu/eslint-config用于格式化和 lint 的 ESLint flat 配置antfu-eslint-config
VS Code 扩展推荐的开发扩展vscode-extensions
开发
主题描述参考
应用开发Vue/Vite/Nuxt/UnoCSS Web 应用的偏好app-development

评论

支持 Markdown