项目结构组织
项目结构组织的重要性
合理的项目结构组织能显著提升代码可维护性、团队协作效率以及长期迭代的可持续性。TypeScript项目的结构设计需要考虑类型系统特性、模块化方案以及现代前端工程化的最佳实践。
基础目录结构设计
典型的TypeScript项目通常包含以下核心目录:
project-root/
├── src/ # 源代码目录
│ ├── core/ # 核心业务逻辑
│ ├── features/ # 功能模块
│ ├── shared/ # 共享资源
│ └── index.ts # 入口文件
├── tests/ # 测试代码
├── typings/ # 类型声明
├── configs/ # 构建配置
└── package.json
按功能划分的模块化结构
功能模块化(Function-First)结构适合中大型项目:
// 示例:用户认证模块结构
src/
auth/
├── components/ # 认证相关UI组件
├── hooks/ # 自定义Hook
├── services/ # API服务
├── types/ # 类型定义
├── utils/ # 工具函数
├── index.ts # 模块出口
└── auth.test.ts # 测试文件
这种结构使每个功能模块自成体系,便于单独维护和测试。
分层架构实践
清晰的层次划分有助于控制代码复杂度:
// 典型的分层结构示例
src/
├── presentation/ # 表现层(React组件等)
├── application/ # 应用逻辑层
├── domain/ # 领域模型层
└── infrastructure/ # 基础设施(API调用等)
每层通过明确定义的接口通信,例如领域层定义仓库接口,基础设施层实现具体仓库:
// domain/repositories/UserRepository.ts
interface UserRepository {
getUser(id: string): Promise<User>;
}
// infrastructure/repositories/HttpUserRepository.ts
class HttpUserRepository implements UserRepository {
async getUser(id: string) {
// 实际HTTP实现
}
}
类型系统的组织策略
TypeScript项目的类型定义需要特别规划:
- 全局类型:放在
types/
目录或src/types.ts
- 模块专属类型:与模块共存
- 第三方类型扩展:使用声明合并
// 扩展第三方库类型示例
declare module 'some-library' {
interface LibraryConfig {
customOption?: boolean;
}
}
配置管理的结构设计
环境配置和构建配置应分离管理:
config/
├── webpack/ # webpack配置
│ ├── common.config.ts
│ ├── dev.config.ts
│ └── prod.config.ts
└── env/ # 环境变量
├── development.ts
├── production.ts
└── test.ts
使用TypeScript编写配置可获得类型检查和智能提示:
// config/env/development.ts
export default {
apiBaseUrl: 'http://localhost:3000',
enableMock: true,
} as const; // 使用as const获得精确类型推断
测试代码的组织方式
测试代码应镜像源代码结构:
src/
components/
Button/
├── Button.tsx
└── Button.test.tsx # 同级测试
tests/
integration/ # 集成测试
e2e/ # 端到端测试
__mocks__/ # Mock文件
使用Jest的测试示例:
// 组件测试示例
import { render } from '@testing-library/react';
import Button from '../Button';
describe('Button Component', () => {
it('renders with correct text', () => {
const { getByText } = render(<Button>Click</Button>);
expect(getByText('Click')).toBeInTheDocument();
});
});
工具代码的集中管理
共享工具函数应按用途分类:
// src/shared/utils/
├── array.ts # 数组工具
├── date.ts # 日期处理
├── string.ts # 字符串处理
└── validation.ts # 验证逻辑
示例工具函数实现:
// src/shared/utils/array.ts
export function chunk<T>(array: T[], size: number): T[][] {
return Array.from(
{ length: Math.ceil(array.length / size) },
(_, i) => array.slice(i * size, i * size + size)
);
}
样式资源的组织方案
CSS-in-TS方案推荐与组件同目录:
components/
Card/
├── Card.tsx
├── Card.module.scss
├── Card.test.tsx
└── types.ts
全局样式和主题单独管理:
// src/styles/
├── theme/ # 主题定义
├── mixins/ # 样式混合
├── base.scss # 基础样式
└── variables.ts # 样式变量(TypeScript)
多包管理策略
大型项目可采用monorepo结构:
packages/
├── core/ # 核心库
├── web-app/ # 网页应用
├── mobile-app/ # 移动应用
└── shared/ # 共享代码
使用TypeScript项目引用:
// tsconfig.json
{
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@shared/*": ["packages/shared/src/*"]
}
}
}
文档与代码的协同
文档应作为项目的一部分:
docs/
├── architecture.md
├── api/ # API文档
└── examples/ # 代码示例
使用TypeDoc生成API文档:
/**
* 用户服务接口
* @remarks
* 提供用户相关的所有操作
*/
export interface UserService {
/**
* 根据ID获取用户
* @param id - 用户唯一标识
*/
getUser(id: string): Promise<User>;
}
构建产物的结构优化
输出目录应保持清晰:
dist/ # 构建输出
├── esm/ # ES模块
├── cjs/ # CommonJS
├── types/ # 类型声明
└── assets/ # 静态资源
通过package.json
定义入口:
{
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/types/index.d.ts"
}
代码规范的强制执行
使用ESLint和Prettier维护一致性:
configs/
├── eslint/
│ ├── base.ts
│ ├── react.ts
│ └── node.ts
└── prettier.ts
示例ESLint配置:
// configs/eslint/base.ts
export default {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
'@typescript-eslint/explicit-function-return-type': 'error'
}
};
环境特定的差异处理
通过条件导入处理环境差异:
// src/core/api/client.ts
let apiClient: ApiClient;
if (process.env.NODE_ENV === 'test') {
apiClient = new MockApiClient();
} else {
apiClient = new HttpApiClient();
}
export default apiClient;
自动化脚本的组织
复杂脚本应放在专用目录:
scripts/
├── build.ts # 自定义构建脚本
├── migrate.ts # 数据库迁移
└── seed.ts # 测试数据生成
使用TypeScript编写脚本示例:
// scripts/migrate.ts
import { migrateDatabase } from '../src/core/database';
async function runMigrations() {
try {
await migrateDatabase();
console.log('Migrations completed');
} catch (error) {
console.error('Migration failed:', error);
process.exit(1);
}
}
runMigrations();
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn