name: antfu description: 安东尼·富的JavaScript/TypeScript项目的工具和惯例。用于设置新项目、配置ESLint/Prettier替代品、monorepos、库发布,或当用户提到安东尼·富的偏好时。 metadata: author: 安东尼·富 version: “2026.02.03”
编码实践
代码组织
- 单一职责: 每个源文件应该有明确、专注的范围/目的
- 拆分大文件: 当文件变得过大或处理太多问题时拆分
- 类型分离: 总是将类型和接口分离到
types.ts或types/*.ts - 常量提取: 将常量移动到专门的
constants.ts文件
运行时环境
- 优先使用同构代码: 编写运行时无关的代码,尽可能在Node、浏览器和工作线程中工作
- 清晰的运行时指示器: 当代码是环境特定时,在文件顶部添加注释:
// @env node
// @env browser
TypeScript
- 显式返回类型: 尽可能显式声明返回类型
- 避免复杂的行内类型: 将复杂类型提取到专门的
type或interface声明中
注释
- 避免不必要的注释: 代码应该是自解释的
- 解释“为什么”而不是“如何”: 注释应该描述推理或意图,而不是代码做什么
测试 (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) |
TypeScript 配置
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
}
}
ESLint 设置
// eslint.config.mjs
import antfu from '@antfu/eslint-config'
export default antfu()
完成任务时,运行 pnpm run lint --fix 来格式化代码并修复编码风格。
详细配置选项: antfu-eslint-config
Git Hooks
{
"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"
}
}
pnpm 目录
在 pnpm-workspace.yaml 中使用命名目录进行版本管理:
| 目录 | 用途 |
|---|---|
prod |
生产依赖 |
inlined |
打包器内联依赖 |
dev |
开发工具 (linter, 打包器, 测试) |
frontend |
前端库 |
避免默认目录。目录名称可以根据项目需求调整。
参考资料
| 主题 | 描述 | 参考 |
|---|---|---|
| ESLint 配置 | 框架支持、格式化器、规则覆盖、VS Code 设置 | antfu-eslint-config |
| 项目设置 | .gitignore、GitHub Actions、VS Code 扩展 | setting-up |
| 应用开发 | Vue/Nuxt/UnoCSS 惯例和模式 | app-development |
| 库开发 | tsdown 打包、纯ESM发布 | library-development |
| Monorepo | pnpm 工作空间、集中化别名、Turborepo | monorepo |