016.006.story.md 16 KB

Story 016.006: 搬迁核心类并完成模块化

Status

Approved

Story

作为 图表库开发者, 我想要 将 u-charts 核心库中的 uChartsEvent 事件类和 uCharts 主类搬迁到独立模块并导入所有模块,完成整个 u-charts 核心库的模块化搬迁以便 提高代码的可维护性、可测试性和类型安全性,为后续 React 组件封装打下基础。

Acceptance Criteria

  1. charts/ 目录下所有文件创建完成
  2. uChartsEvent 和 uCharts 类有完整类型注解
  3. src/index.ts 保持向后兼容,默认导出 uCharts 类
  4. 类型检查通过(pnpm typecheck),无 any 类型(除非必要)
  5. 包可以成功构建(pnpm build),自动生成 .d.ts 声明文件
  6. 代码组织清晰,易于维护和测试
  7. 模块间依赖关系合理,无循环依赖
  8. 代码逻辑与原始 u-charts.ts 完全一致

Tasks / Subtasks

  • [ ] Task 1: 分析核心类结构 (AC: 1, 2, 8)

    • 1.1 分析 uChartsEvent 事件类的所有方法和属性
    • 1.2 分析 uCharts 主类的构造函数和所有方法
    • 1.3 识别类方法与各模块的依赖关系
  • [ ] Task 2: 创建 charts 模块目录结构 (AC: 1)

    • 2.1 创建 src/lib/charts/u-charts-event.ts
    • 2.2 创建 src/lib/charts/u-charts.ts
    • 2.3 创建 src/lib/charts/index.ts
  • [ ] Task 3: 搬迁 uChartsEvent 类并添加类型注解 (AC: 2, 4, 8)

    • 3.1 将 uChartsEvent 类搬迁到 u-charts-event.ts
    • 3.2 为构造函数添加类型注解
    • 3.3 为 addEventListener 方法添加类型注解
    • 3.4 为 delEventListener 方法添加类型注解
    • 3.5 为 trigger 方法添加类型注解
    • 3.6 定义事件相关的 TypeScript 接口
  • [ ] Task 4: 搬迁 uCharts 类并添加类型注解 (AC: 2, 4, 8)

    • 4.1 将 uCharts 类搬迁到 u-charts.ts
    • 4.2 导入所有已模块化的子模块(config, utils, data-processing, charts-data, renderers)
    • 4.3 为构造函数参数添加类型注解
    • 4.4 为所有公共方法添加类型注解
    • 4.5 为所有私有方法添加类型注解
    • 4.6 定义 uCharts 相关的 TypeScript 接口
  • [ ] Task 5: 更新 src/index.ts 导出配置 (AC: 3, 5)

    • 5.1 导出所有公共API(uCharts, uChartsEvent)
    • 5.2 保持向后兼容性(默认导出 uCharts 类)
    • 5.3 导出各个模块供高级用户使用
    • 5.4 更新 package.json 的 exports 字段支持模块导出
  • [ ] Task 6: 验证搬迁结果 (AC: 4, 5, 6, 7)

    • 6.1 确保所有导出正确
    • 6.2 运行类型检查验证类型注解正确(pnpm typecheck
    • 6.3 运行构建验证生成 .d.ts 文件(pnpm build
    • 6.4 检查生成的 .d.ts 文件正确导出类型
    • 6.5 验证模块间无循环依赖
    • 6.6 确认代码逻辑与原始文件完全一致
  • [ ] Task 7: 删除或备份原始 u-charts.ts 文件 (AC: 8)

    • 7.1 备份原始 u-charts.ts 到 u-charts.ts.backup
    • 7.2 删除原始 u-charts.ts 文件
    • 7.3 验证包仍然可以正常导入和使用

Dev Notes

前置故事见解

故事 016.001 完成状态:

  • ✅ 已创建 mini-charts 包基础结构
  • ✅ 已迁移 u-charts 核心库到 src/lib/u-charts.ts(7680行代码)
  • ✅ 包可以成功构建和类型检查通过
  • ⚠️ 使用 @ts-nocheck 绕过原始库中的类型问题

故事 016.002 完成状态:

  • ✅ 已创建 config.tsutils/ 目录及所有子模块文件
  • ✅ 所有文件行数均在 500 行以内(最大 201 行 misc.ts)
  • ✅ 类型检查通过(pnpm typecheck
  • ✅ 为 Canvas 上下文使用 any 类型以兼容小程序环境

故事 016.003 完成状态:

  • ✅ 已创建 data-processing/ 目录及所有子文件
  • ✅ 成功搬迁了14个数据处理函数到4个独立文件
  • ✅ 所有函数都添加了完整的 TypeScript 类型注解
  • ✅ 类型检查通过(pnpm typecheck
  • ✅ 构建成功,所有文件正确生成到 dist 目录

故事 016.004 完成状态:

  • ✅ 已创建 charts-data/ 目录及所有子文件
  • ✅ 成功搬迁了所有图表数据点计算函数
  • ✅ 所有函数都添加了完整的 TypeScript 类型注解
  • ✅ 类型检查通过(pnpm typecheck
  • ✅ 构建成功,所有文件正确生成到 dist 目录

故事 016.005 完成状态:

  • ✅ 已创建 renderers/ 目录及所有子文件
  • ✅ 成功搬迁了所有绘制函数
  • ✅ 所有函数都添加了完整的 TypeScript 类型注解
  • ✅ 类型检查通过(pnpm typecheck
  • ✅ 构建成功,所有文件正确生成到 dist 目录

关键技术决策:

  • 保持代码逻辑完全不变,只改变文件组织方式
  • 只在搬迁过程中添加 TypeScript 类型注解,不修改代码的实现逻辑
  • 为复杂参数和返回值定义 TypeScript 接口
  • 使用 ES6 export 语法导出函数和类型

迁移策略: 保持 u-charts 核心绘制逻辑不变,渐进式模块化并添加类型定义

技术栈要求

来源: tech-stack.md

  • TypeScript: 5.4.5 [来源: tech-stack.md]
  • React: 18.0.0(mini 包使用 React 18,不是 React 19)[来源: 故事 016.001 Dev Notes]
  • Taro: 4.1.4 [来源: tech-stack.md]
  • Node.js: 20.18.3(运行时环境)[来源: tech-stack.md]
  • 包管理器: pnpm workspace [来源: source-tree.md]

项目结构指南

来源: source-tree.md

mini-ui-packages/
└── mini-charts/              # mini-charts 包
    ├── src/
    │   ├── index.ts          # 主入口文件(需要更新)
    │   └── lib/
    │       ├── u-charts.ts   # u-charts 核心库(7680行)- [本故事删除]
    │       ├── config.ts     # [已完成] 配置对象
    │       ├── utils/        # [已完成] 工具函数目录
    │       ├── data-processing/  # [已完成] 数据处理模块
    │       ├── charts-data/  # [已完成] 图表数据点计算模块
    │       ├── renderers/    # [已完成] 绘制函数模块
    │       └── charts/       # [本故事创建] 核心类模块
    │           ├── u-charts-event.ts  # uChartsEvent 事件类
    │           ├── u-charts.ts         # uCharts 主类
    │           └── index.ts            # 核心类模块统一导出
    ├── tests/
    │   └── u-charts.test.ts
    ├── package.json
    ├── tsconfig.json
    └── jest.config.cjs

TypeScript 配置规范

来源: ui-package-standards.md

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["DOM", "DOM.Iterable", "ES2020"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"]
}

本故事重要: 需要为所有类方法添加完整的类型注解,确保 strict: true 模式下无类型错误。

u-charts 核心类分析

来源: mini-charts/src/lib/u-charts.ts

uChartsEvent 事件类(u-charts-event.ts)

位置: 原始文件第 6939-6968 行(约30行)

方法名 功能描述
constructor 初始化事件存储对象
addEventListener 添加事件监听器
delEventListener 删除事件监听器
trigger 触发事件,调用所有监听器

类型定义示例:

export interface EventListener {
  (...args: any[]): void;
}

export interface EventMap {
  [type: string]: EventListener[];
}

export class uChartsEvent {
  events: EventMap;

  constructor();

  addEventListener(type: string, listener: EventListener): void;

  delEventListener(type: string): void;

  trigger(type: string, ...params: any[]): void;
}

uCharts 主类(u-charts.ts)

位置: 原始文件第 6970-7680 行(约610行)

主要方法和属性:

类别 方法/属性名 功能描述
构造函数 constructor 初始化图表配置和上下文
配置方法 initConfig 初始化配置对象
绘制方法 drawCanvas 执行画布绘制
事件处理 touchEvent 处理触摸事件
事件处理 eventListener 事件监听器
数据处理 getDataPoints 获取数据点
坐标计算 calXAxisData 计算X轴数据
坐标计算 calYAxisData 计算Y轴数据
动画方法 animation 执行动画
工具方法 getH5Offset 获取H5偏移量

重要依赖:

  • config.ts: 配置对象
  • utils/: 工具函数
  • data-processing/: 数据处理函数
  • charts-data/: 图表数据点计算函数
  • renderers/: 绘制函数

类型定义示例:

export interface ChartsConfig {
  pixelRatio?: number;
  fontSize?: number;
  fontColor?: string;
  background?: string;
  title?: ChartsTitle;
  subtitle?: ChartsTitle;
  duration?: number;
  yAxis?: YAxisConfig;
  xAxis?: XAxisConfig;
  legend?: LegendConfig;
  extra?: ExtraConfig;
  rotate?: boolean;
  [key: string]: any;
}

export interface ChartsContext {
  width: number;
  height: number;
  padding: number[];
  [key: string]: any;
}

export class uCharts extends uChartsEvent {
  opts: ChartsConfig;
  context: ChartsContext;
  // ... 其他属性

  constructor(opts: ChartsConfig);

  initConfig(config: ChartsConfig): void;

  drawCanvas(): void;

  touchEvent(event: TouchEvent): void;

  // ... 其他方法
}

类型定义规范

来源: ui-package-standards.md

本故事重要: 必须为所有类方法添加完整的类型注解,避免使用 any 类型(除非必要)。

类型定义原则:

  1. 为配置对象定义 TypeScript 接口
  2. 为类属性定义明确类型
  3. 为方法参数和返回值添加类型注解
  4. 使用泛型增强类型安全性
  5. 导出所有公共类型定义

编码标准

来源: coding-standards.md

  • 代码风格: TypeScript 严格模式,一致的缩进和命名
  • 类型注解: 必须为所有函数参数和返回值添加类型注解
  • 接口定义: 为复杂数据结构定义 TypeScript 接口
  • 导出规范: 使用 ES6 export 语法导出函数和类型
  • 类定义: 使用现代 TypeScript 类语法

测试策略

来源: coding-standards.md

测试框架: Jest(mini 包使用 Jest,不是 Vitest)

测试位置: tests/ 目录(与源码并列)

测试类型:

  • 单元测试: 测试核心类的功能
  • 不要求集成测试和 E2E 测试(这些在后续故事中)

测试要求:

  1. 为 uChartsEvent 类编写基础单元测试
  2. 为 uCharts 类编写基础功能测试
  3. 测试覆盖率目标: 基础测试即可,不要求高覆盖率
  4. Mock 相关依赖(如 Canvas 上下文等)

测试命令:

# 进入包目录
cd mini-ui-packages/mini-charts

# 运行所有测试
pnpm test

# 运行特定测试
pnpm test --testNamePattern "核心类测试"

# 类型检查
pnpm typecheck

# 构建
pnpm build

构建和发布规范

来源: ui-package-standards.md

mini-charts 包在 PNPM 工作空间中:

  • 开发模式: 直接使用 TypeScript 源码
  • 构建: 使用 tsc 编译到 dist/ 目录
  • 类型检查: 使用 tsc --noEmit 验证类型
  • 发布: 本故事不要求发布,仅验证本地构建成功

重要: 本故事完成后,应该可以:

  1. ✅ 运行 pnpm build 成功生成 dist/ 目录
  2. ✅ 运行 pnpm typecheck 无类型错误
  3. ✅ 自动生成 .d.ts 声明文件
  4. ✅ 所有新模块正确导出,可以被主入口文件引用
  5. ✅ 保持向后兼容性,默认导出 uCharts 类

开发流程

来源: development-workflow.md

开发命令:

# 进入包目录
cd mini-ui-packages/mini-charts

# 安装依赖(在根目录)
pnpm install

# 开发模式(监听文件变化)
pnpm dev

# 类型检查
pnpm typecheck

# 运行测试
pnpm test

# 构建
pnpm build

环境配置

来源: CLAUDE.md

  • Node.js: 20.19.2
  • 包管理器: pnpm
  • 测试调试: 使用 pnpm test --testNamePattern "测试名称" 运行特定测试
  • Mini 测试: 需要 Jest,不是 Vitest
  • 类型检查: 使用 pnpm typecheck 加 grep 来过滤要检查的指定文件

文件位置规范

来源: source-tree.md

所有新文件应创建在:

  • 核心类模块目录: mini-ui-packages/mini-charts/src/lib/charts/
  • 核心类文件:
    • u-charts-event.ts: uChartsEvent 事件类
    • u-charts.ts: uCharts 主类
    • index.ts: 核心类模块统一导出
  • 主入口: mini-ui-packages/mini-charts/src/index.ts(需要更新导出)
  • 测试文件: mini-ui-packages/mini-charts/tests/(可选,本故事不强制要求)

技术约束

  1. 搬迁原则: 保持代码逻辑完全不变,只改变文件组织方式
  2. 类型注解: 只在搬迁过程中添加 TypeScript 类型注解,不修改代码的实现逻辑
  3. 文件大小: 核心类可能超过 500 行,但应尽量保持在合理范围内
  4. 类型安全: 避免使用 any 类型(除非必要)
  5. 向后兼容: 保持与原始 u-charts.ts 的功能兼容性
  6. 模块依赖: 确保导入所有已模块化的子模块
  7. 循环依赖: 避免模块间循环依赖

验证标准

完成本故事后,应该满足:

  1. src/lib/charts/ 目录下所有文件存在
  2. ✅ uChartsEvent 和 uCharts 类有完整类型注解
  3. src/index.ts 保持向后兼容,默认导出 uCharts 类
  4. ✅ 运行 pnpm typecheck 无类型错误
  5. ✅ 运行 pnpm build 成功,自动生成 .d.ts 声明文件
  6. ✅ 检查生成的 .d.ts 文件正确导出类型
  7. ✅ 代码组织清晰,易于维护和测试
  8. ✅ 模块间依赖关系合理,无循环依赖
  9. ✅ 代码逻辑与原始 u-charts.ts 完全一致
  10. ✅ 原始 u-charts.ts 文件已删除或备份

不包含在本故事中的工作

来源: epic-016 故事列表

以下工作不在本故事范围内:

  • ❌ React 组件封装(故事 016.007)
  • ❌ 创建使用示例和文档(故事 016.008)
  • ❌ 创建测试套件(故事 016.009)

Testing

测试框架: Jest(不是 Vitest)

测试位置: tests/ 目录(与源码并列)

测试要求:

  1. 创建基础测试验证核心类的正确导入和导出
  2. 测试 uChartsEvent 类的事件功能(可选,本故事不强制要求)
  3. 测试 uCharts 类的基础功能(可选,本故事不强制要求)
  4. Mock 相关依赖(如 Canvas 上下文等)
  5. 测试覆盖率目标: 基础测试即可,不要求高覆盖率

测试命令:

# 运行所有测试
pnpm test

# 运行特定测试
pnpm test --testNamePattern "核心类测试"

参考: coding-standards.md

Change Log

Date Version Description Author
2025-12-24 1.0 创建故事文档 Bob (Scrum Master)
2025-12-24 1.1 更新状态为 Approved Bob (Scrum Master)
2025-12-24 1.2 暂停故事,发现遗漏辅助函数,创建故事 016.007 James (Dev Agent)

Dev Agent Record

此部分由开发代理在实施过程中填写

Agent Model Used

待开发代理填写

Debug Log References

待开发代理填写

Completion Notes List

待开发代理填写

File List

待开发代理填写

QA Results

此部分由 QA 代理在审查完成后填写