🚨 踩坑记录与解决方案
1. 路径导入问题
问题现象:
typescript
// 错误:找不到模块
import styles from './Board.module.css'; // TS2307错误
解决方案:
方法一:创建类型声明文件
typescript
// src/vite-env.d.ts
/// <reference types="vite/client" />
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
方法二:正确的相对路径导入
typescript
// 组件导入其他组件
import { Square } from '../../ui/Square/Square'; // 明确文件路径
import { Button } from '../../ui/Button/Button';
// 避免使用index.ts快捷方式,直到配置正确
方法三:配置路径别名(推荐)
typescript
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
'@core': path.resolve(__dirname, './src/core')
}
}
})
// 然后在tsconfig.json中配置
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@core/*": ["./src/core/*"]
}
}
}
// 使用路径别名导入
import { Board } from '@components/game/Board/Board';
import { MinimaxAI } from '@core/algorithms/minimax';
🏗️ 项目架构详解
1. 现代前端项目架构概念
什么是项目架构?
就像盖房子需要蓝图一样,项目架构就是软件的"蓝图",它决定了:
- 代码如何组织
- 不同部分如何协作
- 如何扩展和维护
我们的项目架构:
ai-tic-tac-toe/
├── src/
│ ├── components/ # 组件层 - 负责显示界面
│ ├── core/ # 核心层 - 负责业务逻辑
│ ├── hooks/ # 逻辑层 - 负责状态管理
│ └── styles/ # 样式层 - 负责外观
2. 模块化设计
什么是模块化?
把大系统拆成小模块,每个模块专注做一件事。
我们的模块划分:
typescript
// UI模块 - 只关心显示
export const Button: React.FC<ButtonProps> = ({ children, onClick }) => {
return <button onClick={onClick}>{children}</button>;
};
// 业务模块 - 只关心游戏规则
export class MinimaxAI {
getBestMove(board: BoardState): number {
// AI算法实现
}
}
// 状态模块 - 只关心数据管理
export const useGame = () => {
const [board, setBoard] = useState(initialBoard);
// 状态管理逻辑
};
模块化的好处:
- ✅ 代码更易理解
- ✅ 便于团队协作
- ✅ 容易测试和维护
- ✅ 代码复用性强
3. 组件化设计
什么是组件化?
把界面拆分成独立的、可复用的部件。
我们的组件层次:
App (根组件)
└── GameLayout (布局组件)
├── GameStatus (状态显示)
├── Board (游戏棋盘)
│ └── Square (单个格子) × 9
└── GameControls (控制按钮)
组件通信方式:
typescript
// 1. 父传子 - Props
<Square value={squares[0]} onClick={() => handleClick(0)} />
// 2. 子传父 - 回调函数
const handleClick = (index: number) => {
// 处理点击事件
};
// 3. 状态提升 - 共享状态
const [board, setBoard] = useState(initialBoard);
📚 TypeScript 工程化开发要点
1. 类型系统基础
为什么要用TypeScript?
- 🛡️ 在代码运行前发现错误
- 📝 代码即文档,类型就是注释
- 🔧 更好的编辑器支持
基础类型示例:
typescript
// 原始类型
const name: string = "Alice";
const age: number = 25;
const isStudent: boolean = true;
// 数组类型
const numbers: number[] = [1, 2, 3];
const players: Array<'X' | 'O'> = ['X', 'O'];
// 对象类型
interface User {
id: number;
name: string;
email?: string; // 可选属性
}
// 函数类型
const calculateScore: (board: BoardState) => number = (board) => {
return 0;
};
2. React + TypeScript 集成
组件Props类型定义:
typescript
// 定义Props接口
interface SquareProps {
value: 'X' | 'O' | null; // 只能是这三个值
onClick: () => void; // 无参数无返回值的函数
isWinning: boolean; // 布尔值
disabled: boolean;
}
// 使用组件
export const Square: React.FC<SquareProps> = (props) => {
return (
<button
onClick={props.onClick}
disabled={props.disabled}
>
{props.value}
</button>
);
};
// 或者使用解构
export const Square: React.FC<SquareProps> = ({
value,
onClick,
isWinning,
disabled
}) => {
// 组件实现
};
Hooks类型定义:
typescript
// useState - 自动推断类型
const [count, setCount] = useState(0); // count自动是number类型
// 明确指定类型
const [board, setBoard] = useState<BoardState>(initialBoard);
// useCallback - 记忆函数
const handleClick = useCallback((index: number): void => {
// 这个函数会被记忆,依赖不变就不会重新创建
makeMove(index);
}, [makeMove]); // 依赖列表
// useMemo - 记忆计算结果
const gameStatus = useMemo((): GameStatus => {
// 昂贵的计算,结果会被缓存
return calculateGameStatus(board);
}, [board]); // board变化时才重新计算
3. 配置文件详解
package.json - 项目身份证:
json
{
"name": "ai-tic-tac-toe",
"version": "1.0.0",
"type": "module", // 使用ES模块
"scripts": {
"dev": "vite", // 开发命令
"build": "tsc && vite build", // 构建命令
"preview": "vite preview" // 预览构建结果
},
"dependencies": {
"react": "^18.2.0", // 生产依赖
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.0", // 类型定义
"typescript": "^5.0.2", // 开发工具
"vite": "^4.4.5"
}
}
tsconfig.json - TypeScript配置:
json
{
"compilerOptions": {
"target": "ES2020", // 编译目标版本
"lib": ["ES2020", "DOM"], // 使用的库文件
"module": "ESNext", // 模块系统
"strict": true, // 严格模式
"jsx": "react-jsx", // React JSX转换
"esModuleInterop": true // 模块互操作
},
"include": ["src"] // 包含的文件
}
🔧 开发工作流
1. 开发环境搭建
步骤:
- 安装Node.js (版本14+)
- 创建项目文件夹
- 初始化package.json:
npm init -y - 安装依赖:
npm install react react-dom - 安装开发依赖:
npm install -D typescript @types/react vite - 创建配置文件
2. 开发命令
bash
# 启动开发服务器
npm run dev
# 代码检查
npm run lint
# 构建生产版本
npm run build
# 类型检查
npx tsc --noEmit
3. 调试技巧
浏览器开发者工具:
- F12打开开发者工具
- Sources标签查看源代码
- Console查看错误信息
React开发者工具:
- 浏览器扩展,专门调试React应用
- 查看组件层次和状态
🎯 核心概念总结
1. ES Modules (ES模块)
什么是模块?
- 一个文件就是一个模块
- 使用
import/export来导入导出
示例:
typescript
// math.ts - 导出模块
export const add = (a: number, b: number): number => a + b;
export const PI = 3.14159;
// app.ts - 导入模块
import { add, PI } from './math';
console.log(add(2, 3)); // 5
2. 组件生命周期
函数组件生命周期:
typescript
const MyComponent: React.FC = () => {
// 1. 创建阶段 (每次渲染都执行)
const [state, setState] = useState(initialState);
// 2. 副作用阶段
useEffect(() => {
// 组件挂载后执行
console.log('组件已挂载');
return () => {
// 组件卸载前执行
console.log('组件即将卸载');
};
}, []); // 空依赖数组表示只执行一次
// 3. 渲染阶段
return <div>组件内容</div>;
};
3. 状态管理
状态提升:
typescript
// 子组件
const Child: React.FC<{ value: string; onChange: (value: string) => void }> =
({ value, onChange }) => {
return <input value={value} onChange={(e) => onChange(e.target.value)} />;
};
// 父组件
const Parent: React.FC = () => {
const [value, setValue] = useState('');
return <Child value={value} onChange={setValue} />;
};
📖 学习资源汇总
官方文档(必读)
-
TypeScript
- TypeScript官方手册 - 从基础到高级
- TypeScript练习场 - 在线编写TypeScript代码
-
React
- React官方教程 - 交互式学习React
- React Beta文档 - 最新的React概念
-
构建工具
实践教程
-
项目实战
- React TypeScript Cheatsheet - React+TS最佳实践
- 全栈Open - 免费的现代Web开发课程
-
算法学习
工具资源
-
开发工具
- VS Code官方文档 - 编辑器使用指南
- Chrome DevTools - 浏览器调试工具
-
代码质量
- ESLint规则 - 代码规范检查
- Prettier配置 - 代码格式化
社区资源
- 学习社区
- MDN Web Docs - Web技术权威参考
- Stack Overflow - 编程问题解答
- GitHub - 开源项目学习
推荐学习路径
- 第一阶段:HTML/CSS/JavaScript基础
- 第二阶段:TypeScript语法和类型系统
- 第三阶段:React基础概念和Hooks
- 第四阶段:构建工具和项目配置
- 第五阶段:算法和数据结构
- 第六阶段:实战项目开发
记住:编程是实践技能,多写代码比只看文档更重要。从这个小项目开始,逐步构建知识体系。