关于 antfu
基于 antfu/starter-ts 的 TypeScript 项目实践指南,为开发者和编码 Agent 提供项目结构、工具、检查及发布约定。
主要功能
- 01starter-ts 脚手架约定
- 02文件职责划分与类型分离
- 03同构运行时代码建议
- 04TypeScript 与 ESLint 配置
- 05CI 检查与 Git 钩子
- 06依赖目录与发布指南
适用场景
- 01搭建 TypeScript 项目
- 02组织源文件与类型
- 03配置 lint、测试和 CI
- 04准备 npm 包发布
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ antfu/ skills --skill antfu安装后在 Claude Code 中输入/antfu确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/antfu-eslint-config.mdapp-development.mdlibrary-development.mdmonorepo.mdsetting-up.md详细介绍
参考模板:antfu/starter-ts。搭建新的 TypeScript 项目时,应参考其中的
package.json脚本、eslint.config.js、knip.json、tsdown.config.ts和工作流,而不是另行设计一套结构。
编码实践
代码组织
- 单一职责:每个源文件都应有明确、专注的范围/用途
- 拆分大型文件:文件变得庞大或涉及过多关注点时,应拆分文件
- 类型分离:始终将类型和接口分离到
types.ts或types/*.ts中 - 提取常量:将常量移至专门的
constants.ts文件
运行时环境
- 优先编写同构代码:尽可能编写与运行时无关、能在 Node、浏览器和 workers 中运行的代码
- 明确标示运行时环境:代码特定于某个环境时,在文件顶部添加注释:
// @env node
// @env browser
TypeScript
- 明确声明返回类型:尽可能显式声明返回类型
- 避免复杂的内联类型:将复杂类型提取为专门的
type或interface声明
明确性
优先编写明确、可追溯的代码,而不是依赖隐式“魔法”。读者(无论是人还是 Agent)都应能追踪每个名称的来源,而无需运行工具。
- 显式导入:优先使用显式的
import语句。避免自动导入——如果框架提供了自动导入(例如 Nuxt/Nitro),新项目应将其关闭(参见 app-development)。 - 默认不使用路径别名:使用相对导入(
./foo、../bar)。只有在项目中已经配置了路径别名(@/、~/、#imports等)时才使用;不要为全新代码引入路径别名。
注释
- 避免不必要的注释:代码应能自我说明
- 解释“为什么”,而不是“怎么做”:注释应描述原因或意图,而非代码的具体操作
测试(Vitest)
- 测试文件:
foo.ts→foo.test.ts(位于同一目录) - 使用
describe/itAPI(不要使用test) - 对复杂输出使用
toMatchSnapshot - 对特定语言的快照,使用带显式路径的
toMatchFileSnapshot
工具选择
@antfu/ni 命令
| 命令 | 描述 |
|---|---|
ni | 安装依赖 |
ni <pkg> / ni -D <pkg> | 添加依赖/开发依赖 |
nr <script> | 运行脚本 |
nu | 升级依赖 |
nun <pkg> | 卸载依赖 |
nci | 清洁安装(pnpm i --frozen-lockfile) |
nlx <pkg> | 执行软件包(npx) |
检查 npm 软件包版本
使用 fast-npm-meta 查询软件包的最新版本——它会查询一个小型元数据端点,而不是下载完整的 registry 负载(每个软件包可能有数 MB)。
nlx fast-npm-meta version vite # 7.3.1
nlx fast-npm-meta version "nuxt@^3.5" # 3.5.22 — range-aware
nlx fast-npm-meta version vite nuxt vue # multiple at once
nlx fast-npm-meta version vite --json # JSON for scripting
nlx fast-npm-meta full vite # full version list + dist-tags
如果只需要查询最新版本,优先使用它,而不是 npm view <pkg> version,也不要直接从 registry 读取 package.json。
TypeScript 配置
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
}
}
ESLint 设置
// eslint.config.js
import antfu from '@antfu/eslint-config'
export default antfu({
type: 'lib', // or 'app' (default)
pnpm: true, // enforce pnpm catalogs in package.json
antislop: true, // flag redundant/duplicated AI-style code, ban explicit `any`
})
始终启用 antislop: true。这需要将 eslint-plugin-slop 和 eslint-plugin-sonarjs 作为开发依赖。
详细配置选项请参阅:antfu-eslint-config
Knip
使用 Knip 检查未使用的文件、导出和依赖——linter 一次只能检查一个文件。
// knip.json
{
"$schema": "https://unpkg.com/knip@6/schema.json",
"project": ["src/**/*.ts"],
"ignoreDependencies": []
}
删除 Knip 报告的内容来修复问题;只有对在 package.json 脚本之外调用的工具(例如 taze),才添加到 ignoreDependencies。
脚本和 ci 门禁
每个项目都应提供一个 ci 脚本,通过一条命令运行所有检查:
{
"scripts": {
"build": "tsdown",
"lint": "eslint --cache",
"typecheck": "tsc",
"knip": "knip",
"test": "pnpm run build && vitest",
"ci": "pnpm run lint && pnpm run typecheck && pnpm run knip && pnpm run test --run"
}
}
每次提交前,运行 nr lint --fix 进行格式化,然后运行 nr ci 并确保通过。 不要在 ci 未通过时提交;应修复根本原因,而不是屏蔽规则或添加忽略项。
Git Hooks
simple-git-hooks + nano-staged。pre-commit hook 会运行完整的 ci 检查;prepare 还会通过 skills-npm 安装 Agent 技能:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks && simple-git-hooks && skills-npm"
},
"simple-git-hooks": {
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && pnpm run ci && pnpx nano-staged"
},
"nano-staged": {
"*": "eslint --fix --no-warn-ignored"
}
}
将 .githooks 添加到 .gitignore,并在 pnpm-workspace.yaml 的 allowBuilds 下添加 simple-git-hooks: true。
skills-npm
skills-npm 会将已安装 npm 包中附带的 Agent 技能创建符号链接(并获取 skills 字段中声明的技能),在每次安装时将其放入 Agent 的技能目录。将其安装为开发依赖,并按上文所述将其接入 prepare;将 skills/npm-* 添加到 .gitignore。提交生成的 skills-npm-lock.json。
发布
优先使用 npm Trusted Publishing(OIDC),而不是 NPM_TOKEN 密钥:发布会在 CI 中通过 v* 标签运行 release.yml,并设置 id-token: write;nr release(bumpp)只负责递增版本号、创建标签并推送。详情:setting-up。
pnpm Catalogs
在 pnpm-workspace.yaml 中使用命名 catalog 管理版本:
| Catalog | 用途 |
|---|---|
prod | 生产依赖 |
inlined | 由打包器内联的依赖 |
dev | 开发工具(linter、打包器、测试) |
frontend | 前端库 |
避免使用默认 catalog。可根据项目需求调整 catalog 名称。
参考
| 主题 | 描述 | 参考 |
|---|---|---|
| ESLint 配置 | 框架支持、antislop、格式化工具、规则覆盖、VS Code 设置 | antfu-eslint-config |
| 项目设置 | .gitignore、GitHub Actions、OIDC Trusted Publishing、VS Code 扩展 | setting-up |
| 应用开发 | Vue/Nuxt/UnoCSS 规范、自动导入控制、Storybook 组件测试 | app-development |
| 库开发 | tsdown 打包、纯 ESM 发布、publint、API 快照 | library-development |
| Monorepo | pnpm 工作区、集中式别名、Turborepo | monorepo |