mixvideo-v2/.promptx/development-guide.md

11 KiB

MixVideo 开发指南

快速开始

环境准备

# 检查环境要求
node --version    # >= 18.0.0
rustc --version   # >= 1.70.0
pnpm --version    # >= 8.0.0

# 克隆项目
git clone <repository-url>
cd mixvideo

# 安装依赖
pnpm install

# 启动开发环境
pnpm tauri:dev

项目结构概览

mixvideo/
├── .promptx/                 # 开发规范文档
├── apps/desktop/             # 主应用
│   ├── src/                  # React前端
│   └── src-tauri/           # Rust后端
├── docs/                     # 项目文档
├── package.json             # 根配置
├── pnpm-workspace.yaml      # 工作空间配置
└── Cargo.toml              # Rust工作空间

开发工作流

1. 功能开发流程

# 1. 创建功能分支
git checkout -b feature/新功能名称

# 2. 开发和测试
pnpm tauri:dev  # 启动开发服务器
pnpm test       # 运行测试

# 3. 代码检查
pnpm lint       # ESLint检查
pnpm format     # Prettier格式化
cargo clippy    # Rust代码检查

# 4. 提交代码
git add .
git commit -m "feat: 添加新功能描述"

# 5. 推送和合并
git push origin feature/新功能名称
# 创建Pull Request

2. 提交信息规范

# 提交类型
feat:     新功能
fix:      修复bug
docs:     文档更新
style:    代码格式调整
refactor: 重构代码
test:     测试相关
chore:    构建工具或辅助工具的变动

# 示例
git commit -m "feat: 添加AI视频分类功能"
git commit -m "fix: 修复素材导入时的路径问题"
git commit -m "docs: 更新API文档"

3. 代码审查清单

  • 功能是否按需求实现
  • 代码是否遵循项目规范
  • 是否有适当的错误处理
  • 是否有相应的测试覆盖
  • 性能是否有考虑
  • 安全性是否有保障
  • 文档是否更新

核心开发模式

前端开发模式

1. 组件开发

// 1. 定义类型
interface ComponentProps {
  id: string;
  title: string;
  onAction?: (data: any) => void;
}

// 2. 实现组件
export const Component: FC<ComponentProps> = ({ id, title, onAction }) => {
  // Hooks
  const [state, setState] = useState();
  const { data, loading } = useCustomHook();
  
  // 事件处理
  const handleAction = useCallback(() => {
    onAction?.(data);
  }, [onAction, data]);
  
  // 渲染
  return (
    <div className="component-container">
      {/* 组件内容 */}
    </div>
  );
};

2. 状态管理

// 使用Zustand进行状态管理
export const useFeatureStore = create<FeatureState>((set, get) => ({
  // 状态
  data: [],
  loading: false,
  error: null,
  
  // 操作
  fetchData: async () => {
    set({ loading: true });
    try {
      const data = await api.getData();
      set({ data, loading: false });
    } catch (error) {
      set({ error: error.message, loading: false });
    }
  },
}));

3. 服务层调用

// 调用Tauri命令
export class FeatureService {
  static async getData(): Promise<Data[]> {
    try {
      return await invoke<Data[]>('get_data');
    } catch (error) {
      throw new Error(`获取数据失败: ${error}`);
    }
  }
}

后端开发模式

1. 数据模型

// 定义数据模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entity {
    pub id: String,
    pub name: String,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

impl Entity {
    pub fn new(name: String) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            name,
            created_at: now,
            updated_at: now,
        }
    }
}

2. 仓库层

// 数据访问层
pub struct EntityRepository {
    database: Arc<Database>,
}

impl EntityRepository {
    pub async fn create(&self, entity: &Entity) -> Result<()> {
        let conn = self.database.get_connection().await?;
        // 数据库操作
        Ok(())
    }
    
    pub async fn get_by_id(&self, id: &str) -> Result<Option<Entity>> {
        let conn = self.database.get_read_connection().await?;
        // 查询操作
        Ok(None)
    }
}

3. 业务服务

// 业务逻辑层
pub struct EntityService;

impl EntityService {
    pub async fn create_entity(
        repository: &EntityRepository,
        request: CreateEntityRequest,
    ) -> Result<Entity> {
        // 业务验证
        if request.name.trim().is_empty() {
            return Err(anyhow!("名称不能为空"));
        }
        
        // 创建实体
        let entity = Entity::new(request.name);
        
        // 保存到数据库
        repository.create(&entity).await?;
        
        Ok(entity)
    }
}

4. Tauri命令

// 表现层命令
#[command]
pub async fn create_entity(
    state: State<'_, AppState>,
    request: CreateEntityRequest,
) -> Result<Entity, String> {
    let repository = state.get_entity_repository()
        .map_err(|e| e.to_string())?;
    
    EntityService::create_entity(&repository, request)
        .await
        .map_err(|e| e.to_string())
}

测试策略

前端测试

// 组件测试
describe('Component', () => {
  it('应该正确渲染', () => {
    render(<Component id="1" title="Test" />);
    expect(screen.getByText('Test')).toBeInTheDocument();
  });
  
  it('应该处理用户交互', async () => {
    const onAction = vi.fn();
    render(<Component id="1" title="Test" onAction={onAction} />);
    
    fireEvent.click(screen.getByRole('button'));
    await waitFor(() => {
      expect(onAction).toHaveBeenCalled();
    });
  });
});

// Hook测试
describe('useCustomHook', () => {
  it('应该返回正确的数据', async () => {
    const { result } = renderHook(() => useCustomHook());
    
    await waitFor(() => {
      expect(result.current.data).toBeDefined();
    });
  });
});

后端测试

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_create_entity() {
        // 准备测试数据
        let db = setup_test_database().await;
        let repository = EntityRepository::new(db);
        let request = CreateEntityRequest {
            name: "Test Entity".to_string(),
        };
        
        // 执行测试
        let result = EntityService::create_entity(&repository, request).await;
        
        // 验证结果
        assert!(result.is_ok());
        let entity = result.unwrap();
        assert_eq!(entity.name, "Test Entity");
    }
}

调试技巧

前端调试

// 1. 使用浏览器开发者工具
console.log('调试信息:', data);
console.error('错误信息:', error);

// 2. React DevTools
// 安装React DevTools浏览器扩展

// 3. Zustand DevTools
const useStore = create(
  devtools((set, get) => ({
    // store实现
  }))
);

// 4. 网络请求调试
// 在Network面板查看Tauri命令调用

后端调试

// 1. 使用tracing进行日志记录
use tracing::{info, warn, error, debug};

#[instrument]
async fn debug_function() {
    info!("函数开始执行");
    debug!("调试信息: {:?}", data);
    warn!("警告信息");
    error!("错误信息: {}", error);
}

// 2. 使用dbg!宏
let result = dbg!(some_calculation());

// 3. 条件编译调试代码
#[cfg(debug_assertions)]
println!("调试模式下的输出");

数据库调试

-- 查看查询计划
EXPLAIN QUERY PLAN SELECT * FROM materials WHERE project_id = ?;

-- 检查索引使用
.schema materials
.indices materials

-- 分析表统计
ANALYZE;

性能优化

前端性能优化

// 1. 组件优化
const OptimizedComponent = memo(({ data }) => {
  const memoizedValue = useMemo(() => {
    return expensiveCalculation(data);
  }, [data]);
  
  const memoizedCallback = useCallback(() => {
    handleAction(data);
  }, [data]);
  
  return <div>{memoizedValue}</div>;
});

// 2. 懒加载
const LazyComponent = lazy(() => import('./LazyComponent'));

// 3. 虚拟化长列表
import { FixedSizeList as List } from 'react-window';

const VirtualList = ({ items }) => (
  <List
    height={600}
    itemCount={items.length}
    itemSize={80}
  >
    {({ index, style }) => (
      <div style={style}>
        <Item data={items[index]} />
      </div>
    )}
  </List>
);

后端性能优化

// 1. 数据库连接池
let pool = ConnectionPool::new(database_url, pool_config)?;

// 2. 批量操作
async fn batch_insert(items: &[Item]) -> Result<()> {
    let conn = pool.get().await?;
    let tx = conn.transaction()?;
    
    for item in items {
        tx.execute("INSERT INTO ...", params![...])?;
    }
    
    tx.commit()?;
    Ok(())
}

// 3. 异步并发
use futures::future::join_all;

let futures: Vec<_> = items.iter()
    .map(|item| process_item(item))
    .collect();

let results = join_all(futures).await;

常见问题解决

1. 构建问题

# 清理缓存
pnpm clean
rm -rf node_modules
rm -rf target
pnpm install

# Rust编译问题
cargo clean
cargo build

2. 开发环境问题

# 端口冲突
lsof -ti:1420 | xargs kill -9

# 权限问题
sudo chown -R $(whoami) ~/.cargo

3. 数据库问题

// 数据库锁定
// 检查是否有其他进程占用数据库
// 使用WAL模式减少锁定

// 迁移失败
// 检查SQL语法
// 验证外键约束

4. 前端问题

// 状态更新问题
// 检查依赖数组
// 使用useCallback和useMemo

// 渲染性能问题
// 使用React DevTools Profiler
// 检查不必要的重渲染

部署指南

开发环境部署

# 启动开发服务器
pnpm tauri:dev

生产环境构建

# 构建应用
pnpm tauri:build

# 构建产物位置
# Windows: target/release/bundle/msi/
# macOS: target/release/bundle/dmg/
# Linux: target/release/bundle/deb/

发布流程

# 1. 更新版本号
# 修改 package.json 和 Cargo.toml 中的版本号

# 2. 创建发布标签
git tag v0.2.1
git push origin v0.2.1

# 3. GitHub Actions自动构建和发布
# 查看 .github/workflows/ 中的配置

最佳实践总结

代码质量

  1. 遵循规范: 严格按照项目编码规范开发
  2. 测试驱动: 为核心功能编写测试
  3. 代码审查: 所有代码都要经过审查
  4. 文档更新: 及时更新相关文档

性能考虑

  1. 数据库优化: 合理使用索引和查询优化
  2. 前端优化: 使用虚拟化、懒加载等技术
  3. 内存管理: 避免内存泄漏和过度使用
  4. 网络优化: 减少不必要的网络请求

安全意识

  1. 输入验证: 严格验证所有用户输入
  2. 错误处理: 不泄露敏感信息
  3. 权限控制: 实施适当的访问控制
  4. 数据保护: 保护用户数据安全

用户体验

  1. 响应式设计: 支持多种设备和屏幕尺寸
  2. 加载状态: 提供清晰的加载反馈
  3. 错误提示: 友好的错误信息和恢复建议
  4. 无障碍性: 支持键盘导航和屏幕阅读器