Ant Design 项目开发指南 - 为 AI 编程助手提供项目上下文和开发规范
这是 ant-design/ant-design(antd)的源代码仓库,是一个 React 组件库,发布为 npm 包 antd。
- 使用 TypeScript 和 React 开发
- 兼容 React 18+ 版本(peerDependencies:
>=18.0.0) - 包含 84+ 个组件,涵盖通用、输入、数据展示、反馈、导航、布局等类型
- 采用完整的 CSS-in-JS 架构(基于
@ant-design/cssinjs) - 支持 Design Token 主题系统和动态主题切换
- 支持国际化(i18n),包含 150+ 语言 locales
- 支持暗色模式和自定义主题
- 支持 RTL(从右到左)布局
- 支持服务端渲染(SSR)
- 提供完整的 TypeScript 类型定义
- Node.js: >= 18.12.0(推荐使用 LTS 版本)
- 包管理器: npm 或 ut(内部包管理器)
- 浏览器兼容性: 现代浏览器(Chrome 80+、Edge、Firefox、Safari)
- 编辑器: VS Code(推荐)或其他支持 TypeScript 的编辑器
npm install
# 或
utoo installnpm start # 启动开发服务器(http://127.0.0.1:8001)
npm run build # 完整构建
npm test # 运行测试
npm run lint # 代码检查
npm run format # 代码格式化
npm run version # 生成版本信息
npm run clean # 清理构建产物ant-design/
├── components/ # 组件源代码(84+ 组件)
│ ├── component-name/ # 单个组件目录
│ │ ├── ComponentName.tsx # 主组件实现
│ │ ├── SubComponent.tsx # 子组件(如有)
│ │ ├── helpers.ts # 辅助函数
│ │ ├── hooks/ # 组件专属 hooks
│ │ ├── demo/ # 演示代码(*.tsx 和 *.md)
│ │ ├── style/ # 样式系统
│ │ │ ├── index.ts # 样式钩子生成器
│ │ │ ├── token.ts # 主题 token 定义
│ │ │ └── variant.ts # 变体样式
│ │ ├── __tests__/ # 单元测试
│ │ ├── index.en-US.md # 英文文档
│ │ ├── index.zh-CN.md # 中文文档
│ │ └── index.tsx # 导出入口
│ ├── _util/ # 社会工具函数库
│ ├── theme/ # 主题系统
│ ├── locale/ # 国际化文本(150+ 文件)
│ └── index.ts # 组件总入口
├── scripts/ # 构建和工具脚本(26+ 脚本)
├── tests/ # 测试文件和工具
│ ├── __mocks__/ # Jest mocks
│ ├── shared/ # 共享测试工具
│ └── setup.ts # 测试环境设置
├── docs/ # 站点文档
├── CHANGELOG.zh-CN.md # 中文更新日志
├── CHANGELOG.en-US.md # 英文更新日志
├── package.json # 项目配置
├── tsconfig.json # TypeScript 配置
├── eslint.config.mjs # ESLint 配置
├── biome.json # Biome 配置
├── .jest.js # Jest 配置
├── .dumirc.ts # Dumi 文档配置
└── webpack.config.js # Webpack 构建配置
- ✅ 使用 TypeScript 和 React 书写
- ✅ 使用函数式组件和 Hooks,避免类组件
- ✅ 使用
forwardRef实现组件 ref 传递 - ✅ 使用提前返回(early returns)提高代码可读性
- ✅ 避免引入新依赖,严控打包体积
- ✅ 兼容现代浏览器
- ✅ 支持服务端渲染(SSR)
- ✅ 保持向下兼容,避免 breaking change
- ✅ 组件名使用大驼峰(PascalCase),如
Button、DatePicker - ✅ 属性名使用小驼峰(camelCase),如
onClick、defaultValue - ✅ 合理使用
useLayoutEffect处理性能敏感操作(如 loading 延迟) - ✅ 合理使用
React.memo、useMemo和useCallback优化性能 - ✅ 使用
clsx处理类名拼接 - ✅ 使用
devUseWarning提供开发时 API 过期警告 - ✅ 使用
displayName设置组件调试名称 - ✅ 支持 Semantic 样式系统(
classNames和styles属性)
| 用途 | 命名规则 | 示例 |
|---|---|---|
| 初始化属性 | default + PropName |
defaultValue、defaultOpen |
| 强制渲染 | forceRender |
forceRender |
| 子组件强制渲染 | force + SubComponentName + Render |
forcePanelRender |
| 子组件渲染 | SubComponentName + Render |
titleRender、footerRender |
| 数据源 | dataSource |
dataSource |
| 面板开启 | 使用 open,避免使用 visible |
open、defaultOpen |
| 显示相关 | show + PropName |
showSearch、showHeader |
| 功能性 | PropName + able |
disabled、readable |
| 禁用 | disabled |
disabled |
| 额外内容 | extra |
extra |
| 图标 | icon |
icon、prefixIcon |
| 触发器 | trigger |
trigger |
| 类名 | className |
className |
| 样式对象 | style |
style |
组件应支持 classNames 和 styles 属性,用于精细化样式定制:
// classNames 属性类型定义
export type ComponentClassNamesType = {
root?: string;
icon?: string;
content?: string;
// ... 其他元素
};
// styles 属性类型定义
export type ComponentStylesType = {
root?: React.CSSProperties;
icon?: React.CSSProperties;
content?: React.CSSProperties;
// ... 其他元素
};
// 使用示例
<Button
classNames={{ root: 'custom-btn', icon: 'custom-icon' }}
styles={{ root: { width: 200 }, icon: { color: 'red' } }}
>
Button
</Button>;| 类型 | 命名规则 | 示例 |
|---|---|---|
| 触发事件 | on + EventName |
onClick、onChange |
| 子组件事件 | on + SubComponentName + EventName |
onPanelChange |
| 前置事件 | before + EventName |
beforeUpload |
| 后置事件 | after + EventName |
afterClose |
| 连续动作完成 | on + EventName + Complete |
onUploadComplete |
组件应提供 ref 属性,结构如下:
interface ComponentRef {
nativeElement: HTMLElement;
focus: VoidFunction;
blur: VoidFunction;
// 其他方法...
}| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| htmlType | Button 原生类型 | string | button |
- |
| type | 按钮类型 | primary | default | dashed | link | text |
default |
- |
| disabled | 是否禁用 | boolean | false | - |
| minLength | 最小长度 | number | 0 | - |
| style | 自定义样式 | CSSProperties | - | - |
| classNames | 自定义类名 | ComponentClassNamesType | - | 5.0.0 |
| styles | 自定义内联样式 | ComponentStylesType | - | 5.0.0 |
- ✅ 字符串类型的默认值使用反引号包裹,如
`button` - ✅ 布尔类型直接使用
true或false - ✅ 数字类型直接使用数字,如
0、100 - ✅ 函数类型使用箭头函数表达式,如
(e: Event) => void - ✅ 无默认值使用
- - ✅ 描述首字母大写,结尾无句号
- ✅ API 按字母顺序排列
- ✅ 新增属性需要声明可用版本号,如
5.0.0
- ✅ 所有组件和函数必须提供准确的类型定义
- ✅ 避免使用
any类型,尽可能精确地定义类型 - ✅ 使用接口(interface)而非类型别名(type)定义对象结构
- ✅ 导出所有公共接口类型,方便用户使用
- ✅ 严格遵循 TypeScript 类型设计原则,确保类型安全
- ✅ 确保编译无任何类型错误或警告
// ✅ 正确:使用 interface 定义 Props
interface ButtonProps {
type?: 'primary' | 'default' | 'dashed';
onClick?: (e: React.MouseEvent) => void;
}
// ❌ 错误:避免使用 type 定义对象结构
type ButtonProps = {
type?: 'primary' | 'default';
};
// ✅ 正确:组件 Props 接口命名
interface ComponentNameProps {
// ...
}
// ✅ 正确:组件状态接口命名
interface ComponentNameState {
// ...
}
// ✅ 正确:使用 ForwardRefRenderFunction 定义 ref
const Component = React.forwardRef<ComponentRef, ComponentProps>((props, ref) => {
// ...
});- ✅ 适当使用泛型增强类型灵活性
- ✅ 使用交叉类型(&)合并多个类型
- ✅ 使用字面量联合类型定义有限的选项集合
- ✅ 避免使用
enum,优先使用联合类型和as const - ✅ 尽可能依赖 TypeScript 的类型推断
- ✅ 只在必要时使用类型断言(
as)
// ✅ 推荐:使用联合类型和 as const
const ButtonTypes = ['primary', 'default', 'dashed'] as const;
type ButtonType = (typeof ButtonTypes)[number];
// ❌ 不推荐:使用 enum
enum ButtonType {
Primary = 'primary',
Default = 'default',
}Ant Design 6.x 采用完整的 CSS-in-JS 架构,基于 @ant-design/cssinjs 实现:
- 使用
@ant-design/cssinjs作为样式解决方案 - 使用
@ant-design/cssinjs-utils提供额外样式工具 - 支持动态样式和主题切换
- 样式独立注入,避免 CSS 污染
- 支持 Server-Side Rendering (SSR)
每个组件的样式应该放在 style/ 目录下,建议结构:
style/
├── index.ts # 样式钩生成器(导出点)
├── token.ts # 组件 token 定义
├── variant.ts # 变体样式(solid/outlined/text 等)
├── compact.ts # 紧凑布局样式(如需要)
└── group.ts | 组合样式(如需要)
// 1. Token 准备函数
const prepareToken = (token: GlobalToken): ComponentToken => {
return mergeToken(token, {
// 组件特定 token
controlHeightLG: 40,
});
};
// 2. Component Token 准备函数
export const prepareComponentToken: GetDefaultToken<'ComponentName'> = (token) => ({
componentBg: token.colorBgContainer,
componentBorder: token.colorBorder,
// ...
});
// 3. 样式生成函数
const genComponentStyle: GenerateStyle<ComponentToken, CSSObject> = (token) => {
const { componentCls } = token;
return {
[componentCls]: {
// 基础样式
},
};
};
// 4. 导出样式钩子(使用 genStyleHooks)
export default genStyleHooks(
'ComponentName', // 组件名称
(token) => [genComponentStyle(token)],
prepareComponentToken, // Component Token 准备函数
{
unitless: {
// 无单位 token
fontWeight: true,
},
},
);使用 Ant Design 的 Design Token 系统:
- 避免硬编码颜色、尺寸、间距等值
- 组件样式应基于全局 Token 和组件级 Token
- 自定义样式应尽可能使用现有的 Token
- 组件级 Token 命名规范:
Component+semantic part+css property - 使用
mergeToken合并 token - 使用
calc处理 CSS 计算值
格式:variant (optional) + semantic part + semantic part variant (optional) + css property + size/disabled (optional)
示例:
buttonPrimaryColor- Button 主色inputPaddingBlock- Input 垂直内边距menuItemActiveBg- Menu 激活项背景色
- ✅ 组件应支持不同屏幕尺寸(使用 CSS 媒体查询)
- ✅ 所有组件必须支持暗色模式
- ✅ 组件应支持 RTL(从右到左)布局
- ✅ 使用 CSS 逻辑属性(如
margin-inline-start)替代方向性属性 - ✅ 支持通过
ConfigProvider进行主题定制 - ✅ 使用 CSS 变量 (
cssVarCls) 支持动态主题切换
- 使用 CSS 过渡实现简单动画
- 复杂动画使用
@rc-component/motion实现 - 尊重用户的减少动画设置(
prefers-reduced-motion) - 动画时长和缓动函数应使用 Token:
motionDurationMid、motionEaseInOut - 动画不应干扰用户的操作和阅读体验
- 样式生成函数应遵循
gen[ComponentName]Style的命名规范 - 样式覆盖应使用类选择器而非标签选择器
- 避免在 render 过程中重复创建样式对象
- 使用
hashId确保样式唯一性 - 使用
cssVarCls支持 CSS 变量
- 遵循 WCAG 2.1 AA 级别标准
- 确保焦点状态有明显的视觉提示
- 提供足够的色彩对比度
- 不依赖颜色来传达信息
- 支持用户放大页面至 200% 时的正常布局
- 避免使用会导致闪烁的动画
项目使用多种代码格式化工具组合使用:
| 工具 | 用途 | 配置文件 |
|---|---|---|
| Biome | 代码检查和格式化(主要) | biome.json |
| ESLint | 代码质量检查 | eslint.config.mjs |
| Prettier | 补充格式化 | .prettierrc |
配置文件:biome.json、.prettierrc
- 缩进: 2 空格
- 行宽: 100 字符
- 引号: JavaScript 使用单引号,JSX 属性使用双引号
- 尾随逗号: 强制添加(
all) - 分号: 不强制使用
# 使用 Biome 格式化
npm run format
# 使用 Biome 检查
npm run lint:biome
# 使用 Prettier 格式化(补充)
npm run prettier使用 @ianvs/prettier-plugin-sort-imports 插件自动排序导入:
// 1. React 导入
import React, { forwardRef, useState } from 'react';
import RcComponent from '@rc-component/component';
// 2. 第三方库导入
import clsx from 'clsx';
// 3. Ant Design 内部导入
import { useToken } from '../theme/internal';
// 4. 相对路径导入
import { helperFunction } from './helpers';
// 5. 类型导入
import type { RefType } from './types';
// 6. 样式导入(如果有)
import './custom.css';- 使用 Jest 30+ 和 React Testing Library 编写单元测试
- 使用 jest-axe 进行可访问性测试
- 使用 jest-image-snapshot 进行视觉回归测试
- 测试覆盖率要求 100%
- 测试文件放在组件目录下的
__tests__/目录
| 测试类型 | 文件名 | 用途 |
|---|---|---|
| 主测试 | index.test.tsx |
组件功能测试 |
| 无障碍测试 | a11y.test.ts |
WCAG 可访问性标准测试 |
| 类型测试 | type.test.tsx |
TypeScript 类型完整性测试 |
| Semantic 测试 | demo-semantic.test.tsx |
Demo 语义化测试 |
| Demo 测试 | demo.test.ts |
Demo 代码测试 |
项目提供了多个测试辅助函数:
// mountTest - 测试组件挂载/卸载
import mountTest from 'tests/shared/mountTest';
// rtlTest - 测试 RTL 布局渲染
import rtlTest from 'tests/shared/rtlTest';
mountTest(Button);
rtlTest(Button);# 运行单元测试
npm test
# 更新测试快照
npm run test:update
# 运行视觉回归测试(需要 Puppeteer/Docker)
npm run test:image
# 运行所有测试套件
npm run test:all
# 运行 Node.js 环境测试
npm run test:node
# 运行站点文档测试
npm run test:site- ✅ 测试用户行为而非实现细节
- ✅ 使用有意义的测试描述(
describe和it) - ✅ 每个测试用例应该独立,不依赖其他测试
- ✅ 测试边界情况和错误处理
- ✅ 组件应同时包含
mountTest和rtlTest - ✅ 新增功能必须有对应的测试用例
- ✅ 使用
toHaveBeenCalledTimes而非toHaveBeenCalledExactTimes
- ✅ demo 代码尽可能简洁
- ✅ 避免冗余代码,方便用户复制到项目直接使用
- ✅ 每个 demo 聚焦展示一个功能点
- ✅ 提供中英文两个版本的说明
- ✅ 遵循展示优先原则,确保视觉效果良好
- ✅ 展示组件的主要使用场景
- ✅ 按照由简到繁的顺序排列 demo
- 每个组件演示包含
.md(说明文档)和.tsx(实际代码)两个文件 - 位置:组件目录下的
demo子目录,如components/button/demo/ - 命名:短横线连接的小写英文单词,如
basic.tsx、custom-filter.tsx - 文件名应简洁地描述示例内容
// ✅ 正确的导入顺序
import React, { useState } from 'react';
import { Button, Space } from 'antd';
import type { ButtonProps } from 'antd';
import './custom.css';
// ✅ 使用函数式组件和 Hooks
const Demo: React.FC = () => {
const [loading, setLoading] = useState(false);
const handleClick = () => {
setLoading(true);
// ...
};
return (
<Space>
<Button loading={loading} onClick={handleClick}>
Click me
</Button>
</Space>
);
};
export default Demo;规范要点:
- 导入顺序:React → 依赖库 → 组件库 → 自定义组件 → 类型 → 样式
- 类型:为复杂数据定义清晰接口,避免
any - 使用函数式组件和 Hooks
- 2 空格缩进,箭头函数,驼峰命名
- 优先使用 antd 内置组件,减少外部依赖
- 性能优化:适当使用
useMemo/useCallback,清理副作用
antd 的本地化配置的类型定义的入口文件是 components/locale/index.tsx,当需要添加新的本地化配置时,需要检查对应组件或全局配置的类型是否存在,如果不存在,则需要增加相应的类型描述。
- 本地化配置文件命名规则:
*_*.ts,如:zh_CN.ts、en_US.ts - 通常在为 antd 添加或修改某一项本地化配置时,如无特殊说明,需要同时修改所有语言的本地化配置
- 本地化配置的内容通常是纯字符串
- 带有
${}的变量将在实际使用的地方被实时替换成对应的变量内容
import { useLocale } from '../locale';
import enUS from '../locale/en_US';
export function TestComp(props) {
const { locale: propLocale } = props;
const [contextLocale] = useLocale('TestComp', enUS);
const locale = { ...contextLocale, ...propLocale };
return <div title={locale?.title}>{locale?.text}</div>;
}[component-name]/
├── ComponentName.tsx # 主组件实现
├── index.tsx # 导出入口
├── demo/ # 演示代码
│ ├── basic.tsx
│ └── basic.md
├── style/ # 样式系统
│ ├── index.ts
│ └── token.ts
├── __tests__/ # 测试文件
│ ├── index.test.tsx
│ └── a11y.test.ts
├── index.en-US.md # 英文文档
└── index.zh-CN.md # 中文文档
import React, { forwardRef, useContext, useRef } from 'react';
import { clsx } from 'clsx';
import { useComposeRef } from '../_util/hooks';
import { useComponentConfig } from '../_util/hooks/useComponentConfig';
import { devUseWarning } from '../_util/warning';
import { ConfigProviderContext } from '../../config-provider';
import useStyle from './style';
export interface ComponentNameProps {
// ... 其他 props
className?: string;
style?: React.CSSProperties;
classNames?: ComponentClassNames;
styles?: ComponentStyles;
}
export interface ComponentRef {
nativeElement: HTMLElement;
focus: VoidFunction;
blur: VoidFunction;
}
export type ComponentClassNames = {
root?: string;
// ...
};
export type ComponentStyles = {
root?: React.CSSProperties;
// ...
};
const InternalComponent = React.forwardRef<ComponentRef, ComponentNameProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
className,
style,
classNames,
styles,
...restProps
} = props;
const { getPrefixCls, direction } = useContext(ConfigProviderContext);
const componentConfig = useComponentConfig('ComponentName');
const prefixCls = getPrefixCls('component-name', customizePrefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
const domRef = useRef<HTMLElement>(null);
const mergedRef = useComposeRef(ref, domRef);
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('ComponentName');
warning.deprecated(!deprecatedProp, 'deprecatedProp', 'newProp');
}
return wrapCSSVar(
<div
ref={mergedRef}
className={clsx(
prefixCls,
hashId,
cssVarCls,
className,
classNames?.root,
componentConfig.className,
)}
style={{ ...style, ...styles?.root, ...componentConfig.style }}
dir={direction}
{...restProps}
>
{/* 子内容 */}
</div>,
);
});
const Component = InternalComponent as typeof InternalComponent & {
displayName?: string;
};
if (process.env.NODE_ENV !== 'production') {
Component.displayName = 'ComponentName';
}
export default Component;// style/token.ts
import type { TokenType } from '../../theme/internal';
// style/index.ts
import { genStyleHooks } from '../../theme/internal';
import { prepareComponentToken } from './token';
export interface ComponentToken {
componentFontSize?: number;
componentPadding?: number;
}
export const prepareComponentToken: GetDefaultToken<'ComponentName'> = (token) => ({
componentFontSize: token.fontSize,
componentPadding: token.paddingXS,
});
const genComponentStyle: GenerateStyle<ComponentToken, CSSObject> = (token) => {
const { componentCls, fontSize, padding } = token;
return {
[componentCls]: {
fontSize,
padding,
},
};
};
export default genStyleHooks(
'ComponentName',
(token) => [genComponentStyle(token)],
prepareComponentToken,
);- ✅ 提供中英文两个版本
- ✅ 新的属性需要声明可用的版本号
- ✅ 属性命名符合 antd 的 API 命名规则
- 针对 Markdown 文件中的标题(# 到 ######)自动生成锚点 ID
- 所有中文标题(H1-H6)必须手动指定一个简洁、有意义的英文锚点
- 格式:
## 中文标题 {#english-anchor-id} - 英文标题通常不需要手动指定锚点,但如果需要,可以使用相同的格式
- 锚点 ID 必须符合正则表达式
^[a-zA-Z][\w-:\.]*$,且长度不应超过 32 个字符 - 用于演示(demo)且包含
-demo-的 id 不受前面的长度限制 - FAQ 章节下的所有标题锚点必须以
faq-作为前缀 - 为确保在不同语言间切换时锚点依然有效,同一问题的中英文锚点应保持完全一致
示例:
- 中文标题:
### 如何使用组件 {#how-to-use-component} - 英文标题:
### How to Use the Component {#how-to-use-component}
-
文件位置:在
CHANGELOG.en-US.md和CHANGELOG.zh-CN.md书写每个版本的变更 -
有效性过滤:忽略用户无感知的改动(如文档网站改进、纯测试用例更新、内部重构、工具链优化等),除非其对开发者有直接影响。保持 CHANGELOG 的内容有效性。
-
开发者视角:用面向开发者的角度和叙述方式撰写 CHANGELOG,描述"用户的原始问题"和"对开发者的影响",而非"具体的解决代码"。
- ❌ 修复 Typography 的 DOM 结构问题。
- ✅ 💄 Typography 重构并简化 DOM 结构,修复内容空格丢失的问题。(中文:Emoji + 组件名 + 描述,无冒号)
- ✅ 💄 Refactor Typography DOM structure and fix content space loss.(英文:Emoji + 动词 + 组件名 + 描述)
-
版本与命名:
- 新增属性必须符合 antd API 命名规则
- 新增属性建议在描述中暗示或明确声明可用版本号
-
双语输出:每次处理必须同时提供 中文版 和 英文版
-
PR 链接:尽量给出原始的 PR 链接,社区提交的 PR 改动加上提交者的链接
-
条目顺序与符号:
- Emoji 置顶:每条条目以 Emoji 开头(如 🐞 💄 🆕),后接内容
- 不加冒号:组件名后不使用英文冒号,直接接描述
-
组件名要求:
- 每条必含组件名:每条 changelog 正文中都必须出现对应组件名(分组标题下的子条同样要在句中出现组件名)
- 组件名不用反引号:组件名(如 Modal、Drawer、Button、Upload.Dragger)不使用
`包裹;属性名、API、token 等仍用反引号
-
中英文条目句式:
- 中文:
Emoji 组件名 动词/描述 … [#PR](链接) [@贡献者]例:🐞 Button 修复暗色主题下 \color` 的 `hover` 与 `active` 状态颜色相反的问题。` - 英文:
Emoji 动词 组件名 描述 … [#PR](链接) [@贡献者](动词在前,如 Fix / Add / Support / Remove / Disable / Refactor / Improve / Change)例:🐞 Fix Button reversed \hover` and `active` colors for `color` in dark theme.`
- 中文:
-
分组逻辑:
- 多项改动:同一组件有 2 条及以上改动时,使用
- 组件名作为分类标题(不加粗),具体条目缩进排列,子条中仍须包含组件名 - 单项改动:直接写单行条目,不设分类标题
- 多项改动:同一组件有 2 条及以上改动时,使用
-
文本细节:
- 代码包裹:所有属性名、方法名、API、
role/aria属性必须使用反引号`包裹(组件名除外) - 中英空格:中文与英文、数字、链接、
@用户名之间必须保留 一个空格
- 代码包裹:所有属性名、方法名、API、
| Emoji | 用途 |
|---|---|
| 🐞 | 修复 Bug |
| 💄 | 样式更新或 token 更新 |
| 🆕 | 新增特性 / 新增属性 |
| 🔥 | 极其值得关注的新增特性 |
| 🇺🇸🇨🇳🇬🇧 | 国际化改动 |
| 📖 📝 | 文档或网站改进 |
| ✅ | 新增或更新测试用例 |
| 🛎 | 更新警告/提示信息 |
| ⌨️ ♿ | 可访问性增强 |
| 🗑 | 废弃或移除 |
| 🛠 | 重构或工具链优化 |
| ⚡️ | 性能提升 |
需要同时提供中英文两个版本,格式如下:
中文版(Emoji 在前、无冒号、每条含组件名、属性用反引号):
- ConfigProvider
- 🆕 ConfigProvider 支持 Modal 和 Drawer 的 `maskClosable` 全局配置。[#56739](链接) [@luozz1994](链接)
- Button
- 🐞 Button 修复暗色主题下 `color` 的 `hover` 与 `active` 状态颜色相反的问题。[#56872](链接) [@zombieJ](链接)
- 💄 Modal & Drawer 默认关闭蒙层 blur 效果。[#56781](链接) [@aojunhao123](链接)
- 🐞 Tooltip & Popover 修复弹出层动画起始位置偏左的问题。[#56887](链接) [@zombieJ](链接)英文版(Emoji 在前、动词在前、无冒号、每条含组件名):
- ConfigProvider
- 🆕 Support ConfigProvider global configuration of `maskClosable` for Modal and Drawer. [#56739](link) [@luozz1994](link)
- Button
- 🐞 Fix Button reversed `hover` and `active` colors for `color` in dark theme. [#56872](link) [@zombieJ](link)
- 💄 Disable Modal & Drawer mask blur effect by default. [#56781](link) [@aojunhao123](link)
- 🐞 Fix Tooltip & Popover popup animation starting position being shifted to the left. [#56887](link) [@zombieJ](link)禁止直接提交到以下保护分支:
master:主分支,用于发布feature:特性分支,用于开发新版本next:下一个版本分支
- 从保护分支(通常是
master)创建新的功能分支 - 在新分支上进行开发
- 提交 Pull Request 到目标分支
- 等待 Code Review 和 CI 通过
- 合并到目标分支
| 类型 | 格式 | 示例 |
|---|---|---|
| 功能开发 | feat/description-of-feature |
feat/add-dark-mode |
| 问题修复 | fix/issue-number-or-description |
fix/button-style-issue |
| 文档更新 | docs/what-is-changed |
docs/update-api-docs |
| 代码重构 | refactor/what-is-changed |
refactor/button-component |
| 样式修改 | style/what-is-changed |
style/fix-button-padding |
| 测试相关 | test/what-is-changed |
test/add-button-tests |
| 构建相关 | build/what-is-changed |
build/update-webpack-config |
| 持续集成 | ci/what-is-changed |
ci/add-github-actions |
| 性能优化 | perf/what-is-changed |
perf/optimize-render |
| 依赖升级 | deps/package-name-version |
deps/upgrade-react-19 |
分支命名注意事项:
- 使用小写字母
- 使用连字符(-)分隔单词
- 简短但具有描述性
- 避免使用下划线或其他特殊字符
- 如果与 Issue 关联,可以包含 Issue 编号
- PR 标题始终使用英文
- 遵循格式:
类型: 简短描述 - 示例:
fix: fix button style issues in Safari browserfeat: add dark mode support
- PR 内容默认使用英文
- 尽量简洁清晰地描述改动内容和目的
- 可以视需要在英文描述后附上中文说明
提交 PR 时请使用项目中提供的模板:
- 英文模板(推荐):
PULL_REQUEST_TEMPLATE.md - 中文模板:
PULL_REQUEST_TEMPLATE_CN.md
-
合并策略:
- 新特性请提交至
feature分支 - 其余可提交至
master分支
- 新特性请提交至
-
审核流程:
- PR 需要由至少一名维护者审核通过后才能合并
- 确保所有 CI 检查都通过
- 解决所有 Code Review 中提出的问题
-
PR 质量要求:
- 确保代码符合项目代码风格
- 添加必要的测试用例
- 更新相关文档
- 大型改动需要更详细的说明和更多的审核者参与
-
工具标注:
- 如果是用 Cursor 提交的代码,请在 PR body 末尾进行标注:
> Submitted by Cursor
- 如果是用 Cursor 提交的代码,请在 PR body 末尾进行标注:
- 🆕 新特性提交
- 🐞 Bug 修复
- 📝 文档改进
- 📽️ 演示代码改进
- 💄 样式/交互改进
- 🤖 TypeScript 更新
- 📦 包体积优化
- ⚡️ 性能优化
- 🌐 国际化改进
- ✅ 确保代码运行正常,无控制台错误
- ✅ 适配常见浏览器
- ✅ 避免过时 API,及时更新到新推荐用法
- ✅ 测试覆盖率达到 100%
- ✅ 通过所有 ESLint 和 TypeScript 检查
- ✅ 避免不必要的重新渲染
- ✅ 合理使用
React.memo、useMemo和useCallback - ✅ 样式计算应当高效,避免重复计算
- ✅ 图片和资源应当优化
- ✅ 支持 Tree Shaking
- ✅ 支持 React 18 ~ 19 版本
- ✅ 兼容 Chrome 80+ 浏览器
- ✅ 支持服务端渲染(SSR)
- ✅ 保持向下兼容,避免 breaking change
- ✅ 支持 TypeScript 4.0+
- 编辑器: 推荐使用 VS Code 或其他支持 TypeScript 的编辑器
- 代码检查: ESLint (@antfu/eslint-config) + Biome
- 格式化: Biome + Prettier
- 类型检查: TypeScript 5.9+ 严格模式
- Git hooks: Husky + lint-staged
| 工具 | 用途 |
|---|---|
| Father | 组件编译(lib/es) |
| Webpack | dist 构建和产物分析 |
| Dumi | 文档站点构建 |
| Mako | SSR 构建器(生产环境) |
- lib/: CommonJS 格式
- es/: ES Modules 格式
- dist/: UMD 格式(包含 dist/antd.min.js)
- locale/: 国际化配置
- 所有 PR 必须通过 CI 检查
- 包括单元测试、集成测试、类型检查、代码风格检查
- 自动化发布流程
- 支持多环境部署
- 支持视觉回归测试
| 配置文件 | 说明 |
|---|---|
package.json |
项目配置和脚本 |
tsconfig.json |
TypeScript 配置 |
eslint.config.mjs |
ESLint 配置 |
biome.json |
Biome 配置 |
.prettierrc |
Prettier 配置 |
.jest.js |
Jest 测试配置 |
.dumirc.ts |
Dumi 文档配置 |
webpack.config.js |
Webpack 构建配置 |
# 确认 Node.js 版本
node -v # 应该 >= 18
# 尝试清理 node_modules 和重新安装
rm -rf node_modules package-lock.json
npm install
# 重新生成版本信息
npm run version- 确保已运行
npm run style生成样式文件 - 检查
useStylehook 是否正确调用 - 确认
hashId和cssVarCls是否正确应用到类名
# 运行 TypeScript 类型检查
npm run tsc
# 清理构建产物后重新编译
npm run clean && npm run compile# 更新快照
npm run test:update
# 按组件更新快照
npm test -- --updateSnapshot components/button/__tests__# 本地运行视觉回归测试
npm run test:visual-regression:local
# 需要确保 Puppeteer 和相关依赖已正确安装# 运行包体积分析
npm run size-limit
# 检查是否有重复依赖包(production 构建)
npm run dist
# 分析 bundle
ANALYZER=true npm run dist# 重新生成 Token 元数据
npm run token:meta
# 收集 Token 统计
npm run token:statistic
# 重新构建样式
npm run style- 在
components/locale/下添加对应的语言文件 - 更新
components/locale/index.tsx的类型定义 - 确保所有语言配置保持同步
- API Naming Rules
- #16048 - Current listing api & Chinese version
- #25066 - API standard in the document
- Development Guide
- @ant-design/cssinjs - CSS-in-JS 解决方案
- React 文档
- TypeScript 文档