Skip to content

iannil/typed-frontend-template

Repository files navigation

TypeScript 前端模板

业务无关的、生产就绪的前端模板,基于 TypeScript、React、shadcn/ui 构建,遵循领域驱动设计 (DDD) 和整洁架构 (Clean Architecture) 原则。

🎯 项目概述

这是一个业务无关的、生产就绪的前端模板,基于 TypeScript、React 和 shadcn/ui 构建,遵循领域驱动设计 (DDD) 和整洁架构 (Clean Architecture) 原则。

此模板为任何前端应用提供坚实的架构基础。它完全业务无关,意味着您可以将其用作任何项目领域的起点 - 电子商务、SaaS、仪表板或任何 Web 应用。

核心特性

  • 业务无关 - 纯架构模板,不包含业务逻辑
  • 严格分层 - DDD 四层架构,清晰的依赖关系
  • 类型安全 - TypeScript 严格模式,完整类型覆盖
  • 高可测试 - 34+ 测试文件,覆盖所有架构层
  • 现代化UI - shadcn/ui + Tailwind CSS + 暗黑模式
  • 生产就绪 - 完整的基础设施和最佳实践

🏗️ 架构设计

基于 DDD 和整洁架构的严格分层:

表现层 (UI 组件)
    ↓
应用层 (用例 & DTOs)
    ↓
领域层 (核心业务逻辑)
    ↑
基础设施层 (技术实现)

依赖规则: 依赖只能向内指向,外层依赖内层,内层不知道外层的存在。

🛠 技术栈

分类 技术 版本
核心 React 19.2.0
TypeScript 4.9.5
UI shadcn/ui + Radix UI 最新
Tailwind CSS 3.4.0
lucide-react (图标) 最新
构建 CRACO 7.1.0
react-scripts 5.0.1
测试 Jest 27.x
React Testing Library 16.3.0
其他 Monaco Editor 4.7.0
Axios 1.13.2

📁 项目结构

src/
├── domain/                    # 领域层 - 核心业务逻辑
│   ├── entities/              # 具有标识的领域实体
│   ├── valueObjects/          # 不可变值对象
│   ├── repositories/          # 仓储接口
│   └── services/              # 领域服务
│
├── application/               # 应用层 - 用例编排
│   ├── useCases/              # 应用用例
│   ├── dto/                   # 数据传输对象
│   ├── providers/             # 服务提供者接口
│   ├── batch/                 # 批量处理服务
│   └── streaming/             # 流式处理服务
│
├── infrastructure/            # 基础设施层 - 技术细节
│   ├── repositories/          # 仓储实现 (LocalStorage 等)
│   ├── cache/                 # LRU 缓存及 TTL 管理
│   ├── streaming/             # 流式 HTTP 客户端
│   ├── batch/                 # 批量操作执行器
│   └── deduplication/         # 请求去重
│
├── components/                # 表现层 - UI 组件
│   ├── ui/                    # shadcn/ui 组件 (16个)
│   ├── theme-provider.tsx     # 主题管理
│   └── ...                    # 功能组件
│
├── hooks/                     # 自定义 React Hooks
├── contexts/                  # React 上下文
├── services/                  # 外部服务适配器
├── types/                     # TypeScript 类型定义
├── utils/                     # 工具函数
└── lib/                       # 库配置

🚀 快速开始

环境要求

  • Node.js 16+
  • npm 或 yarn

安装

# 克隆仓库 (或作为模板使用)
git clone <your-repo-url>
cd typed-frontend-template

# 安装依赖
npm install

# 启动开发服务器
npm start

应用将在 http://localhost:3000 启动

可用脚本

# 开发
npm start              # 启动开发服务器

# 测试
npm test               # 运行测试 (监听模式)
npm test -- --coverage # 生成覆盖率报告

# 生产
npm run build          # 构建生产版本

📚 使用此模板

步骤 1: 定义领域模型 (领域层)

首先定义业务实体和值对象:

// src/domain/entities/Product.ts
export class Product {
  constructor(
    public readonly id: string,
    public name: string,
    public price: number
  ) {}
}

// src/domain/repositories/interfaces.ts
export interface IProductRepository {
  save(product: Product): Promise<void>;
  findById(id: string): Promise<Product | null>;
  findAll(): Promise<Product[]>;
  delete(id: string): Promise<void>;
}

步骤 2: 实现用例 (应用层)

定义应用的用例:

// src/application/useCases/ProductUseCases.ts
export class CreateProductUseCase {
  constructor(private repository: IProductRepository) {}

  async execute(data: CreateProductDTO): Promise<Product> {
    const product = new Product(
      generateId(),
      data.name,
      data.price
    );
    await this.repository.save(product);
    return product;
  }
}

步骤 3: 实现基础设施 (基础设施层)

提供具体实现:

// src/infrastructure/repositories/LocalStorageProductRepository.ts
export class LocalStorageProductRepository implements IProductRepository {
  private readonly storageKey = 'products';

  async save(product: Product): Promise<void> {
    const products = await this.findAll();
    const index = products.findIndex(p => p.id === product.id);

    if (index >= 0) {
      products[index] = product;
    } else {
      products.push(product);
    }

    localStorage.setItem(this.storageKey, JSON.stringify(products));
  }

  async findById(id: string): Promise<Product | null> {
    const products = await this.findAll();
    return products.find(p => p.id === id) || null;
  }

  async findAll(): Promise<Product[]> {
    const data = localStorage.getItem(this.storageKey);
    return data ? JSON.parse(data) : [];
  }

  async delete(id: string): Promise<void> {
    const products = await this.findAll();
    const filtered = products.filter(p => p.id !== id);
    localStorage.setItem(this.storageKey, JSON.stringify(filtered));
  }
}

步骤 4: 构建 UI 组件 (表现层)

使用 shadcn/ui 组件创建 UI:

// src/components/ProductList.tsx
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';

export function ProductList() {
  const { products, createProduct, deleteProduct } = useProducts();

  return (
    <div className="space-y-4">
      <Button onClick={createProduct}>添加产品</Button>

      {products.map(product => (
        <Card key={product.id}>
          <h3>{product.name}</h3>
          <p>¥{product.price}</p>
          <Button onClick={() => deleteProduct(product.id)}>删除</Button>
        </Card>
      ))}
    </div>
  );
}

步骤 5: 编写测试

通过全面的测试确保质量:

// src/domain/entities/__tests__/Product.test.ts
describe('Product', () => {
  it('应该创建包含 id、名称和价格的产品', () => {
    const product = new Product('1', '笔记本电脑', 999);

    expect(product.id).toBe('1');
    expect(product.name).toBe('笔记本电脑');
    expect(product.price).toBe(999);
  });
});

🎨 UI 组件

模板包含 16 个预配置的 shadcn/ui 组件:

  • 表单: Button, Input, Textarea, Label, Select, Switch
  • 布局: Dialog, Sheet, Tabs, Separator, Scroll Area
  • 反馈: Tooltip, Badge, Skeleton

所有组件支持:

  • 暗黑/亮色主题切换
  • 完整的 TypeScript 类型
  • 可访问性 (ARIA 标准)
  • 通过 Tailwind CSS 自定义

🧪 测试策略

模板包含覆盖所有层的全面测试:

34+ 测试文件:
├── 领域层 (3 个测试套件)
│   ├── 实体
│   ├── 值对象
│   └── 领域服务
├── 应用层 (5 个测试套件)
│   ├── 用例
│   ├── DTOs
│   └── 服务
├── 基础设施层 (7 个测试套件)
│   ├── 仓储
│   ├── 缓存
│   ├── 流式处理
│   └── 去重
└── 表现层 (8+ 个测试套件)
    └── 组件

🎯 设计模式

模板演示了几个关键设计模式:

  • 仓储模式 - 抽象数据访问
  • 适配器模式 - 外部服务集成
  • 工厂模式 - 对象创建
  • 策略模式 - 可互换的算法
  • 观察者模式 - 基于事件的更新 (通过 React Context)

🔒 SOLID 原则

架构严格遵循 SOLID 原则:

  • Single Responsibility (单一职责) - 每个类只有一个职责
  • Open/Closed (开闭原则) - 易于扩展而无需修改
  • Liskov Substitution (里氏替换) - 接口可互换
  • Interface Segregation (接口隔离) - 小而专注的接口
  • Dependency Inversion (依赖倒置) - 依赖抽象而非具体

📖 文档

🤝 贡献

这是一个模板项目。欢迎:

  1. Fork 它
  2. 根据需求定制
  3. 移除示例业务逻辑
  4. 添加你自己的领域模型

📄 许可证

MIT License - 可以自由将此模板用于任何项目。


使用 DDD + 整洁架构构建 ❤️

About

TypeScript + shadcn/ui + DDD + Clean Architecture

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages