AI 辅助前端开发全链路指南
充分利用 AI 工具(Cursor、GitHub Copilot、ChatGPT 等)提升前端开发全流程效率
📋 目录
概述
AI 辅助开发的价值
## 为什么要用 AI 辅助开发?
### 1. 效率提升
- 代码生成速度提升 50-80%
- 减少重复性工作
- 快速原型开发
- 自动化测试生成
### 2. 质量提升
- 代码规范统一
- 减少低级错误
- 最佳实践应用
- 自动代码审查
### 3. 学习加速
- 实时代码建议
- 技术方案推荐
- 问题快速解决
- 知识快速获取
### 4. 创新能力
- 快速验证想法
- 探索新技术
- 优化方案对比
- 技术方案生成
开发链路全景
前端开发完整链路
graph LR
A[PRD] --> B[原型图]
B --> C[设计稿]
C --> D[UI实现]
D --> E[接口对接]
E --> F[测试]
F --> G[代码审查]
G --> H[项目部署]
A1[AI需求分析] -.-> A
B1[AI原型生成] -.-> B
C1[Figma to Code] -.-> C
D1[AI代码生成] -.-> D
E1[AI接口Mock] -.-> E
F1[AI测试生成] -.-> F
G1[AI代码审查] -.-> G
H1[AI部署脚本] -.-> H
各环节 AI 应用
1. PRD 阶段 - AI 需求分析
工具推荐
- ChatGPT / Claude: 需求分析和细化
- Cursor: 需求文档生成
- Notion AI: 需求管理
应用场景
1.1 需求理解和分析
## Prompt 示例
### 需求分析
我收到一个需求:【粘贴原始需求】
请帮我:
- 分析这个需求的核心目标
- 识别关键功能点
- 列出技术实现要点
- 指出可能的技术难点
- 提供实现建议
### 需求细化
基于以下需求:【需求描述】
请帮我生成:
- 详细的功能列表
- 用户故事(User Story)
- 验收标准(Acceptance Criteria)
- 技术方案建议
- 工作量评估
1.2 技术方案生成
// 在 Cursor 中使用 Composer
// Cmd/Ctrl + I 打开 Composer
/**
* Prompt:
* 基于以下需求,生成技术方案文档:
*
* 需求:开发一个支持实时协作的在线文档编辑器
*
* 请包含:
* 1. 技术栈选型(前端框架、状态管理、实时通信)
* 2. 架构设计(组件结构、数据流)
* 3. 核心功能实现方案
* 4. 性能优化策略
* 5. 潜在风险和应对方案
*/
// AI 会生成完整的技术方案文档
1.3 需求文档模板生成
## Cursor Prompt
生成一个前端需求文档模板,包含:
- 需求背景
- 目标用户
- 功能需求
- 非功能需求
- 技术约束
- 验收标准
- 时间计划
并基于以下需求填充模板:【粘贴需求】
2. 原型图阶段 - AI 原型生成
工具推荐
- v0.dev: AI 生成 React 组件
- Galileo AI: AI 生成 UI 设计
- Uizard: 手绘转原型
- Cursor + Prompt: 生成原型代码
应用场景
2.1 快速原型生成
// 在 Cursor 中生成原型
// Cmd/Ctrl + K 使用内联编辑
/**
* Prompt:
* 生成一个用户列表页面的原型代码,包含:
* 1. 顶部搜索栏(支持姓名、邮箱搜索)
* 2. 用户列表(表格形式,显示头像、姓名、邮箱、角色、状态)
* 3. 分页组件
* 4. 操作按钮(编辑、删除、禁用)
* 5. 使用 Vue 3 + TypeScript + Element Plus
*/
// AI 会生成完整的原型代码
2.2 交互原型生成
<!-- Cursor Prompt -->
<!--
生成一个多步骤表单原型:
1. 步骤指示器(3步:基本信息、详细信息、确认提交)
2. 表单验证
3. 上一步/下一步导航
4. 数据临时保存
5. 使用 Vue 3 Composition API
-->
<template>
<!-- AI 生成的代码 -->
</template>
2.3 响应式原型
/**
* Cursor Prompt:
*
* 生成一个响应式卡片列表组件:
* - 桌面端:4列网格布局
* - 平板端:2列网格布局
* - 移动端:单列布局
* - 支持懒加载
* - 支持骨架屏
* - 使用 Tailwind CSS
*/
3. 设计稿阶段 - Figma to Code
工具推荐
- Figma to Code (Cursor Plugin): 直接转换
- Anima: Figma 插件
- Locofy: 设计稿转代码
- Builder.io: 可视化转代码
应用场景
3.1 Figma 设计稿直接转 Vue/React 代码
// 方法1: 使用 Figma to Code 插件
// 1. 在 Figma 中选中设计稿
// 2. 右键 -> Plugins -> Figma to Code
// 3. 选择目标框架(Vue 3 / React)
// 4. 复制生成的代码到 Cursor
// 方法2: 使用 Cursor + Figma 截图
/**
* Cursor Prompt:
*
* 我有一个 Figma 设计稿(附上截图),请帮我:
* 1. 分析设计稿的布局结构
* 2. 生成对应的 Vue 3 组件代码
* 3. 使用 Tailwind CSS 实现样式
* 4. 确保响应式布局
* 5. 添加必要的交互效果
*
* 设计稿描述:
* - 顶部导航栏(Logo + 菜单 + 用户头像)
* - 左侧边栏(可折叠)
* - 主内容区域(卡片布局)
* - 底部分页
*/
3.2 设计系统组件生成
// Cursor Prompt
/**
* 基于以下设计系统规范,生成 Vue 3 组件库:
*
* 设计规范:
* - 主色:#1890ff
* - 圆角:4px
* - 间距系统:4px 基数(4, 8, 12, 16, 24, 32)
* - 字体:14px 基准
*
* 需要生成的组件:
* 1. Button(主要、次要、危险、禁用状态)
* 2. Input(普通、密码、搜索、带图标)
* 3. Card(基础卡片、带头部、带操作)
* 4. Modal(对话框)
*
* 要求:
* - TypeScript 类型定义
* - 支持主题定制
* - 支持暗黑模式
* - 完整的 Props 和 Emits
*/
3.3 样式提取和优化
// Cursor Prompt
/**
* 分析这个 Figma 设计稿,提取:
*
* 1. 颜色变量(CSS Variables)
* 2. 间距系统(Spacing Scale)
* 3. 字体系统(Typography)
* 4. 阴影系统(Shadows)
* 5. 断点系统(Breakpoints)
*
* 生成对应的:
* - Tailwind 配置
* - SCSS 变量
* - CSS Variables
*/
4. UI 实现阶段 - AI 代码生成
工具推荐
- Cursor: 主力开发工具
- GitHub Copilot: 代码补全
- Tabnine: AI 代码助手
- Codeium: 免费替代方案
应用场景
4.1 组件快速生成
<!-- Cursor Composer 模式 (Cmd/Ctrl + I) -->
<!--
Prompt: 生成一个用户卡片组件
要求:
1. 显示用户头像、姓名、职位、邮箱
2. 支持在线状态显示(绿点)
3. 鼠标悬停显示更多信息(电话、地址)
4. 点击头像放大预览
5. 支持操作按钮(发消息、查看详情)
6. 使用 Vue 3 + TypeScript + Tailwind CSS
7. 支持暗黑模式
8. 添加加载骨架屏
-->
<script setup lang="ts">
// AI 生成完整的组件代码
interface Props {
user: {
id: string
name: string
avatar: string
position: string
email: string
phone?: string
address?: string
isOnline: boolean
}
loading?: boolean
}
const props = withDefaults(defineProps<Props>(), {
loading: false,
})
const emit = defineEmits<{
(e: 'message', userId: string): void
(e: 'viewDetail', userId: string): void
}>()
// ... AI 生成的逻辑
</script>
<template>
<!-- AI 生成的模板 -->
</template>
<style scoped>
/* AI 生成的样式 */
</style>
4.2 复杂交互实现
// Cursor Inline Edit (Cmd/Ctrl + K)
/**
* Prompt:
* 实现一个拖拽排序的看板组件
*
* 功能:
* 1. 支持多列看板(待办、进行中、已完成)
* 2. 卡片可以在列之间拖拽
* 3. 拖拽时显示占位符
* 4. 拖拽结束保存新顺序
* 5. 支持卡片内容编辑
* 6. 使用 @vueuse/core 的 useDraggable
* 7. 添加拖拽动画效果
*/
// AI 会生成完整的拖拽逻辑
4.3 响应式布局实现
<!-- Cursor Prompt -->
<!--
生成一个响应式仪表板布局:
布局要求:
- 桌面端(>1024px):侧边栏 + 主内容区(2列网格)
- 平板端(768-1024px):侧边栏可折叠 + 主内容区(1列)
- 移动端(<768px):底部导航 + 主内容区(1列)
组件:
- 顶部导航栏(固定)
- 侧边栏/底部导航(响应式切换)
- 主内容区(网格布局)
- 统计卡片(4个)
- 图表区域(2个)
使用 Tailwind CSS 实现
-->
4.4 动画效果实现
// Cursor Prompt
/**
* 为这个列表组件添加动画效果:
*
* 1. 列表项进入动画(从下往上淡入)
* 2. 列表项删除动画(淡出并向右滑动)
* 3. 列表项更新动画(闪烁高亮)
* 4. 列表加载骨架屏动画
* 5. 使用 Vue Transition 和 CSS 动画
* 6. 性能优化(使用 transform 和 opacity)
*/
5. 接口对接阶段 - AI 接口处理
工具推荐
- Cursor: API 代码生成
- Postman: API 测试
- Apifox: API 文档和 Mock
- ChatGPT: API 文档理解
应用场景
5.1 API 类型定义生成
// Cursor Prompt
/**
* 基于以下 API 文档,生成 TypeScript 类型定义:
*
* API: GET /api/users
* Response:
* {
* "code": 200,
* "data": {
* "list": [
* {
* "id": "1",
* "name": "张三",
* "email": "zhangsan@example.com",
* "role": "admin",
* "status": "active",
* "createdAt": "2024-01-01T00:00:00Z"
* }
* ],
* "total": 100,
* "page": 1,
* "pageSize": 10
* },
* "message": "success"
* }
*
* 生成:
* 1. 请求参数类型
* 2. 响应数据类型
* 3. API 函数封装
* 4. 错误处理
*/
// AI 生成的代码
interface UserListParams {
page?: number
pageSize?: number
keyword?: string
role?: string
status?: string
}
interface User {
id: string
name: string
email: string
role: 'admin' | 'user' | 'guest'
status: 'active' | 'inactive'
createdAt: string
}
interface UserListResponse {
list: User[]
total: number
page: number
pageSize: number
}
interface ApiResponse<T> {
code: number
data: T
message: string
}
// API 函数
export async function getUserList(params: UserListParams): Promise<UserListResponse> {
const response = await request.get<ApiResponse<UserListResponse>>('/api/users', { params })
if (response.code !== 200) {
throw new Error(response.message)
}
return response.data
}
5.2 Mock 数据生成
// Cursor Prompt
/**
* 为以下 API 生成 Mock 数据:
*
* API: GET /api/dashboard/stats
*
* 需要 Mock:
* 1. 用户统计(总数、今日新增、活跃用户)
* 2. 订单统计(总数、今日订单、订单金额)
* 3. 访问统计(PV、UV、访问趋势)
* 4. 使用 Mock.js 生成随机数据
* 5. 支持延迟响应(模拟网络延迟)
*/
// AI 生成的 Mock 代码
import Mock from 'mockjs'
Mock.mock('/api/dashboard/stats', 'get', () => {
return Mock.mock({
code: 200,
data: {
users: {
total: '@integer(10000, 50000)',
todayNew: '@integer(100, 500)',
active: '@integer(5000, 20000)',
},
orders: {
total: '@integer(50000, 100000)',
todayOrders: '@integer(500, 1000)',
'amount|1': '@float(100000, 500000, 2, 2)',
},
visits: {
pv: '@integer(100000, 500000)',
uv: '@integer(50000, 200000)',
'trend|7': [
{
date: '@date("MM-dd")',
pv: '@integer(10000, 50000)',
uv: '@integer(5000, 20000)',
},
],
},
},
message: 'success',
})
})
5.3 API 错误处理
// Cursor Prompt
/**
* 为这个 API 调用添加完善的错误处理:
*
* 要求:
* 1. 网络错误处理
* 2. HTTP 状态码处理(401、403、404、500)
* 3. 业务错误处理(code !== 200)
* 4. 超时处理
* 5. 重试机制(失败重试3次)
* 6. 错误提示(使用 Element Plus Message)
* 7. 错误日志上报
*/
// AI 生成的错误处理代码
import { ElMessage } from 'element-plus'
class ApiError extends Error {
code: number
constructor(message: string, code: number) {
super(message)
this.code = code
this.name = 'ApiError'
}
}
async function requestWithRetry<T>(
fn: () => Promise<T>,
retries = 3,
delay = 1000
): Promise<T> {
try {
return await fn()
} catch (error) {
if (retries > 0) {
await new Promise((resolve) => setTimeout(resolve, delay))
return requestWithRetry(fn, retries - 1, delay * 2)
}
throw error
}
}
export async function apiCall<T>(url: string, options?: RequestInit): Promise<T> {
try {
const response = await requestWithRetry(
() =>
fetch(url, {
...options,
signal: AbortSignal.timeout(10000), // 10s 超时
}),
3
)
// HTTP 状态码处理
if (!response.ok) {
switch (response.status) {
case 401:
ElMessage.error('未登录或登录已过期')
// 跳转登录页
break
case 403:
ElMessage.error('没有权限访问')
break
case 404:
ElMessage.error('请求的资源不存在')
break
case 500:
ElMessage.error('服务器错误')
break
default:
ElMessage.error(`请求失败: ${response.statusText}`)
}
throw new ApiError(response.statusText, response.status)
}
const data = await response.json()
// 业务错误处理
if (data.code !== 200) {
ElMessage.error(data.message || '请求失败')
throw new ApiError(data.message, data.code)
}
return data.data
} catch (error) {
// 网络错误处理
if (error instanceof TypeError) {
ElMessage.error('网络连接失败,请检查网络')
}
// 超时处理
if (error.name === 'AbortError') {
ElMessage.error('请求超时,请稍后重试')
}
// 错误日志上报
console.error('API Error:', error)
// reportError(error)
throw error
}
}
5.4 API 请求封装
// Cursor Prompt
/**
* 生成一个完整的 API 请求封装工具:
*
* 功能:
* 1. 请求拦截器(添加 token、请求日志)
* 2. 响应拦截器(统一处理响应、错误处理)
* 3. 请求取消(防止重复请求)
* 4. 请求缓存(GET 请求缓存)
* 5. 请求队列(并发控制)
* 6. 进度显示(loading 状态)
* 7. TypeScript 类型支持
*/
// AI 会生成完整的请求封装代码
6. 测试阶段 - AI 测试生成
工具推荐
- Cursor: 测试代码生成
- GitHub Copilot: 测试用例补全
- ChatGPT: 测试策略咨询
应用场景
6.1 单元测试生成
// Cursor Prompt
/**
* 为以下函数生成完整的单元测试:
*
* 使用 Vitest + @vue/test-utils
*
* 要求:
* 1. 测试所有分支逻辑
* 2. 测试边界情况
* 3. 测试错误处理
* 4. Mock 外部依赖
* 5. 测试覆盖率 > 80%
*/
// 原函数
export function calculateDiscount(price: number, userLevel: string): number {
if (price <= 0) throw new Error('Price must be positive')
const discounts = {
vip: 0.8,
member: 0.9,
guest: 1,
}
const discount = discounts[userLevel] || 1
return price * discount
}
// AI 生成的测试代码
import { describe, it, expect } from 'vitest'
import { calculateDiscount } from './discount'
describe('calculateDiscount', () => {
it('should calculate VIP discount correctly', () => {
expect(calculateDiscount(100, 'vip')).toBe(80)
})
it('should calculate member discount correctly', () => {
expect(calculateDiscount(100, 'member')).toBe(90)
})
it('should return original price for guest', () => {
expect(calculateDiscount(100, 'guest')).toBe(100)
})
it('should return original price for unknown user level', () => {
expect(calculateDiscount(100, 'unknown')).toBe(100)
})
it('should throw error for negative price', () => {
expect(() => calculateDiscount(-100, 'vip')).toThrow('Price must be positive')
})
it('should throw error for zero price', () => {
expect(() => calculateDiscount(0, 'vip')).toThrow('Price must be positive')
})
it('should handle decimal prices', () => {
expect(calculateDiscount(99.99, 'vip')).toBeCloseTo(79.99, 2)
})
})
6.2 组件测试生成
// Cursor Prompt
/**
* 为这个 Vue 组件生成完整的测试:
*
* 测试内容:
* 1. 组件渲染
* 2. Props 传递
* 3. 事件触发
* 4. 用户交互
* 5. 条件渲染
* 6. 异步操作
* 7. 快照测试
*/
// 组件代码
<script setup lang="ts">
interface Props {
title: string
count: number
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'increment'): void
(e: 'decrement'): void
}>()
</script>
<template>
<div class="counter">
<h2>{{ title }}</h2>
<p>Count: {{ count }}</p>
<button @click="emit('increment')">+</button>
<button @click="emit('decrement')">-</button>
</div>
</template>
// AI 生成的测试代码
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
describe('Counter', () => {
it('should render title and count', () => {
const wrapper = mount(Counter, {
props: {
title: 'Test Counter',
count: 5,
},
})
expect(wrapper.find('h2').text()).toBe('Test Counter')
expect(wrapper.find('p').text()).toBe('Count: 5')
})
it('should emit increment event when + button clicked', async () => {
const wrapper = mount(Counter, {
props: {
title: 'Test',
count: 0,
},
})
await wrapper.findAll('button')[0].trigger('click')
expect(wrapper.emitted('increment')).toBeTruthy()
expect(wrapper.emitted('increment')).toHaveLength(1)
})
it('should emit decrement event when - button clicked', async () => {
const wrapper = mount(Counter, {
props: {
title: 'Test',
count: 0,
},
})
await wrapper.findAll('button')[1].trigger('click')
expect(wrapper.emitted('decrement')).toBeTruthy()
expect(wrapper.emitted('decrement')).toHaveLength(1)
})
it('should match snapshot', () => {
const wrapper = mount(Counter, {
props: {
title: 'Snapshot Test',
count: 10,
},
})
expect(wrapper.html()).toMatchSnapshot()
})
})
6.3 E2E 测试生成
// Cursor Prompt
/**
* 为用户登录流程生成 E2E 测试:
*
* 使用 Playwright
*
* 测试场景:
* 1. 成功登录
* 2. 错误的用户名/密码
* 3. 空表单提交
* 4. 记住密码功能
* 5. 登录后跳转
*/
// AI 生成的 E2E 测试
import { test, expect } from '@playwright/test'
test.describe('User Login', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/login')
})
test('should login successfully with valid credentials', async ({ page }) => {
await page.fill('input[name="username"]', 'testuser')
await page.fill('input[name="password"]', 'password123')
await page.click('button[type="submit"]')
await expect(page).toHaveURL('/dashboard')
await expect(page.locator('.user-name')).toContainText('testuser')
})
test('should show error with invalid credentials', async ({ page }) => {
await page.fill('input[name="username"]', 'wronguser')
await page.fill('input[name="password"]', 'wrongpass')
await page.click('button[type="submit"]')
await expect(page.locator('.error-message')).toBeVisible()
await expect(page.locator('.error-message')).toContainText('用户名或密码错误')
})
test('should validate empty form', async ({ page }) => {
await page.click('button[type="submit"]')
await expect(page.locator('.error-message')).toBeVisible()
await expect(page).toHaveURL('/login')
})
test('should remember password when checked', async ({ page, context }) => {
await page.fill('input[name="username"]', 'testuser')
await page.fill('input[name="password"]', 'password123')
await page.check('input[name="remember"]')
await page.click('button[type="submit"]')
// 检查 cookie
const cookies = await context.cookies()
const rememberToken = cookies.find((c) => c.name === 'remember_token')
expect(rememberToken).toBeDefined()
})
})
7. 代码审查阶段 - AI 代码审查
工具推荐
- Cursor: 内置代码审查
- GitHub Copilot: PR 审查建议
- CodeRabbit: AI PR 审查
- SonarQube: 代码质量分析
应用场景
7.1 代码质量检查
// Cursor Prompt
/**
* 审查以下代码,检查:
*
* 1. 代码规范(ESLint、Prettier)
* 2. 类型安全(TypeScript)
* 3. 性能问题
* 4. 安全漏洞
* 5. 最佳实践
* 6. 代码复杂度
* 7. 可维护性
*
* 并提供改进建议
*/
// 待审查的代码
function getUserData(id) {
const data = fetch('/api/users/' + id).then((res) => res.json())
return data
}
// AI 审查结果和改进建议
/**
* 代码审查结果:
*
* 问题:
* 1. ❌ 缺少类型定义
* 2. ❌ 缺少错误处理
* 3. ❌ 使用字符串拼接而非模板字符串
* 4. ❌ 没有处理 HTTP 错误状态
* 5. ❌ 函数名不够描述性
*
* 改进建议:
*/
// 改进后的代码
interface User {
id: string
name: string
email: string
}
async function fetchUserById(userId: string): Promise<User> {
try {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data: User = await response.json()
return data
} catch (error) {
console.error('Failed to fetch user:', error)
throw error
}
}
7.2 性能优化建议
// Cursor Prompt
/**
* 分析这个组件的性能问题,并提供优化建议:
*/
// 待优化的组件
<script setup lang="ts">
import { ref } from 'vue'
const list = ref([])
function handleSearch(keyword: string) {
// 每次搜索都重新过滤整个列表
list.value = originalList.filter((item) => item.name.includes(keyword))
}
</script>
// AI 优化建议
/**
* 性能问题:
* 1. ❌ 每次搜索都遍历整个列表
* 2. ❌ 没有防抖处理
* 3. ❌ 没有使用 computed 缓存
*
* 优化建议:
*/
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useDebounceFn } from '@vueuse/core'
const originalList = ref([])
const keyword = ref('')
// 使用 computed 缓存过滤结果
const filteredList = computed(() => {
if (!keyword.value) return originalList.value
return originalList.value.filter((item) =>
item.name.toLowerCase().includes(keyword.value.toLowerCase())
)
})
// 使用防抖优化搜索
const handleSearch = useDebounceFn((value: string) => {
keyword.value = value
}, 300)
</script>
7.3 安全性检查
// Cursor Prompt
/**
* 检查以下代码的安全问题:
*/
// 待检查的代码
function renderUserInput(input: string) {
document.getElementById('content').innerHTML = input
}
// AI 安全审查
/**
* 安全问题:
* 1. ❌ XSS 漏洞:直接使用 innerHTML 渲染用户输入
* 2. ❌ 没有输入验证和清理
*
* 修复建议:
*/
import DOMPurify from 'dompurify'
function renderUserInput(input: string) {
// 使用 DOMPurify 清理用户输入
const cleanInput = DOMPurify.sanitize(input)
const element = document.getElementById('content')
if (element) {
element.innerHTML = cleanInput
}
}
// 或者使用 textContent 避免 HTML 注入
function renderUserInputSafe(input: string) {
const element = document.getElementById('content')
if (element) {
element.textContent = input
}
}
8. 项目部署阶段 - AI 部署脚本
工具推荐
- Cursor: 部署脚本生成
- ChatGPT: DevOps 咨询
- GitHub Actions: CI/CD
应用场景
8.1 CI/CD 配置生成
# Cursor Prompt
# 生成一个完整的 GitHub Actions CI/CD 配置:
#
# 要求:
# 1. 代码检查(ESLint、TypeScript)
# 2. 单元测试(Vitest)
# 3. E2E 测试(Playwright)
# 4. 构建项目
# 5. 部署到 Vercel/Netlify
# 6. 通知(钉钉/企业微信)
# AI 生成的配置
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'pnpm'
- run: pnpm install
- run: pnpm lint
- run: pnpm type-check
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'pnpm'
- run: pnpm install
- run: pnpm test:unit
- run: pnpm test:e2e
- name: Upload coverage
uses: codecov/codecov-action@v3
build:
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'pnpm'
- run: pnpm install
- run: pnpm build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: dist
path: dist/
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
notify:
needs: deploy
runs-on: ubuntu-latest
if: always()
steps:
- name: Send notification
run: |
curl -X POST ${{ secrets.WEBHOOK_URL }} \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "部署完成: ${{ job.status }}"
}
}'
8.2 Docker 配置生成
# Cursor Prompt
# 生成一个优化的 Docker 配置:
#
# 要求:
# 1. 多阶段构建
# 2. 缓存优化
# 3. 镜像体积优化
# 4. 安全最佳实践
# 5. 健康检查
# AI 生成的 Dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
# 复制 package 文件
COPY package.json pnpm-lock.yaml ./
# 安装 pnpm
RUN npm install -g pnpm
# 安装依赖(利用 Docker 缓存)
RUN pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建应用
RUN pnpm build
# 生产阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 80
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
# 启动 nginx
CMD ["nginx", "-g", "daemon off;"]
8.3 部署脚本生成
# Cursor Prompt
# 生成一个自动化部署脚本:
#
# 功能:
# 1. 检查环境
# 2. 拉取最新代码
# 3. 安装依赖
# 4. 运行测试
# 5. 构建项目
# 6. 备份旧版本
# 7. 部署新版本
# 8. 健康检查
# 9. 回滚机制
# AI 生成的部署脚本
#!/bin/bash
set -e # 遇到错误立即退出
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 配置
PROJECT_DIR="/var/www/my-app"
BACKUP_DIR="/var/backups/my-app"
BRANCH="main"
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查环境
check_environment() {
log_info "检查环境..."
# 检查 Node.js
if ! command -v node &> /dev/null; then
log_error "Node.js 未安装"
exit 1
fi
# 检查 pnpm
if ! command -v pnpm &> /dev/null; then
log_error "pnpm 未安装"
exit 1
fi
log_info "环境检查通过"
}
# 拉取最新代码
pull_code() {
log_info "拉取最新代码..."
cd $PROJECT_DIR
git fetch origin
git checkout $BRANCH
git pull origin $BRANCH
log_info "代码更新完成"
}
# 安装依赖
install_dependencies() {
log_info "安装依赖..."
cd $PROJECT_DIR
pnpm install --frozen-lockfile
log_info "依赖安装完成"
}
# 运行测试
run_tests() {
log_info "运行测试..."
cd $PROJECT_DIR
pnpm test:unit
log_info "测试通过"
}
# 构建项目
build_project() {
log_info "构建项目..."
cd $PROJECT_DIR
pnpm build
log_info "构建完成"
}
# 备份旧版本
backup_old_version() {
log_info "备份旧版本..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/backup_$TIMESTAMP"
mkdir -p $BACKUP_DIR
cp -r $PROJECT_DIR/dist $BACKUP_PATH
log_info "备份完成: $BACKUP_PATH"
# 只保留最近5个备份
ls -t $BACKUP_DIR | tail -n +6 | xargs -I {} rm -rf $BACKUP_DIR/{}
}
# 部署新版本
deploy() {
log_info "部署新版本..."
# 这里根据实际情况部署
# 例如:复制到 nginx 目录
sudo cp -r $PROJECT_DIR/dist/* /usr/share/nginx/html/
# 重启 nginx
sudo systemctl reload nginx
log_info "部署完成"
}
# 健康检查
health_check() {
log_info "健康检查..."
# 等待服务启动
sleep 5
# 检查服务是否正常
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost)
if [ $HTTP_CODE -eq 200 ]; then
log_info "健康检查通过"
return 0
else
log_error "健康检查失败: HTTP $HTTP_CODE"
return 1
fi
}
# 回滚
rollback() {
log_warn "开始回滚..."
# 获取最新的备份
LATEST_BACKUP=$(ls -t $BACKUP_DIR | head -n 1)
if [ -z "$LATEST_BACKUP" ]; then
log_error "没有可用的备份"
exit 1
fi
# 恢复备份
sudo cp -r $BACKUP_DIR/$LATEST_BACKUP/* /usr/share/nginx/html/
sudo systemctl reload nginx
log_info "回滚完成"
}
# 主流程
main() {
log_info "开始部署..."
check_environment
pull_code
install_dependencies
run_tests
build_project
backup_old_version
deploy
if health_check; then
log_info "部署成功!"
else
log_error "部署失败,开始回滚..."
rollback
exit 1
fi
}
# 执行主流程
main
工具配置
Cursor 配置
// .cursor/settings.json
{
"cursor.ai.model": "gpt-4",
"cursor.ai.temperature": 0.7,
"cursor.ai.maxTokens": 4096,
"cursor.ai.enableAutoComplete": true,
"cursor.ai.enableInlineChat": true,
"cursor.ai.enableComposer": true,
// 自定义 Prompt
"cursor.ai.customPrompts": [
{
"name": "生成 Vue 3 组件",
"prompt": "生成一个 Vue 3 组件,使用 TypeScript 和 Composition API,包含完整的类型定义和注释"
},
{
"name": "生成单元测试",
"prompt": "为选中的代码生成完整的单元测试,使用 Vitest,包含所有边界情况"
},
{
"name": "代码审查",
"prompt": "审查选中的代码,检查性能、安全、最佳实践问题,并提供改进建议"
}
],
// 项目规则
"cursor.ai.rules": [
"使用 Vue 3 Composition API",
"使用 TypeScript 严格模式",
"使用 Tailwind CSS",
"遵循 ESLint 规则",
"添加完整的类型定义",
"添加必要的注释"
]
}
.cursorrules 文件
# .cursorrules
你是一个专业的 Vue 3 + TypeScript 开发专家。
## 项目信息
- 框架:Vue 3 + TypeScript
- UI 库:Element Plus
- 状态管理:Pinia
- 构建工具:Vite
- CSS:Tailwind CSS + SCSS
## 代码规范
1. 使用 `<script setup lang="ts">` 语法
2. 使用 Composition API
3. 所有函数和变量必须有类型定义
4. 使用 `interface` 定义对象类型
5. 组件 Props 使用 `defineProps<Props>()`
6. 组件 Emits 使用 `defineEmits<Emits>()`
7. 使用 `ref` 和 `reactive` 管理状态
8. 使用 `computed` 计算属性
9. 使用 `watch` 监听变化
10. 组件命名使用 PascalCase
## 文件结构
src/ ├── components/ # 组件 ├── composables/ # 组合式函数 ├── stores/ # Pinia stores ├── types/ # 类型定义 ├── utils/ # 工具函数 └── views/ # 页面
## 命名规范
- 组件:PascalCase (UserCard.vue)
- 文件:kebab-case (user-card.ts)
- 变量/函数:camelCase (getUserInfo)
- 常量:UPPER_SNAKE_CASE (MAX_COUNT)
- 类型:PascalCase (UserInfo)
## 注释规范
- 组件必须有描述注释
- 复杂函数必须有 JSDoc 注释
- 类型定义必须有注释
## 示例代码
```vue
<script setup lang="ts">
/**
* 用户卡片组件
* @description 显示用户基本信息
*/
interface Props {
/** 用户信息 */
user: {
id: string
name: string
avatar: string
}
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'click', userId: string): void
}>()
const handleClick = () => {
emit('click', props.user.id)
}
</script>
<template>
<div class="user-card" @click="handleClick">
<img :src="user.avatar" :alt="user.name" />
<span>{{ user.name }}</span>
</div>
</template>
<style scoped>
.user-card {
@apply flex items-center gap-2 p-4 rounded-lg cursor-pointer hover:bg-gray-100;
}
</style>
生成代码时
- 始终使用 TypeScript
- 添加完整的类型定义
- 添加必要的注释
- 遵循项目规范
- 考虑性能优化
- 考虑错误处理
- 考虑边界情况
---
## 最佳实践
### 1. Prompt 编写技巧
```markdown
## 好的 Prompt 特征
### ✅ 清晰具体
生成一个用户列表组件,包含:
- 搜索功能(姓名、邮箱)
- 表格展示(头像、姓名、邮箱、角色、状态)
- 分页功能
- 操作按钮(编辑、删除)
- 使用 Vue 3 + TypeScript + Element Plus
### ❌ 模糊不清
做一个用户列表
### ✅ 提供上下文
我们的项目使用 Vue 3 + TypeScript + Pinia。 现在需要实现一个全局状态管理,用于管理用户信息。 包含:用户信息、登录状态、权限列表。 请生成完整的 Pinia store 代码。
### ❌ 缺少上下文
写一个 store
### ✅ 分步骤
第一步:生成用户信息的类型定义 第二步:生成 API 请求函数 第三步:生成 Pinia store 第四步:生成使用示例
### ❌ 一次性要求太多
生成整个用户管理系统
2. 代码审查清单
## AI 生成代码审查清单
### 类型安全
- [ ] 所有变量都有类型定义
- [ ] 没有使用 `any` 类型
- [ ] Props 和 Emits 有类型定义
- [ ] API 响应有类型定义
### 代码质量
- [ ] 遵循项目代码规范
- [ ] 没有重复代码
- [ ] 函数职责单一
- [ ] 变量命名清晰
### 性能
- [ ] 使用 `computed` 缓存计算结果
- [ ] 使用 `v-memo` 优化列表渲染
- [ ] 避免不必要的响应式
- [ ] 合理使用 `watch`
### 错误处理
- [ ] API 请求有错误处理
- [ ] 用户输入有验证
- [ ] 边界情况有处理
- [ ] 有友好的错误提示
### 可维护性
- [ ] 有必要的注释
- [ ] 组件拆分合理
- [ ] 逻辑清晰易懂
- [ ] 易于测试
3. 效率提升技巧
## 提升开发效率的技巧
### 1. 使用快捷键
- `Cmd/Ctrl + K`: 内联编辑
- `Cmd/Ctrl + I`: Composer 模式
- `Cmd/Ctrl + L`: 聊天模式
- `Tab`: 接受建议
- `Esc`: 拒绝建议
### 2. 善用注释触发
```typescript
// 生成一个防抖函数
// AI 会自动生成代码
// 为这个函数添加错误处理
// AI 会添加 try-catch
// 优化这段代码的性能
// AI 会提供优化建议
3. 使用代码片段
- 创建常用代码片段
- 使用 AI 生成代码片段
- 团队共享代码片段
4. 批量处理
- 选中多个文件
- 使用 AI 批量重构
- 批量添加类型定义
- 批量生成测试
5. 持续学习
- 查看 AI 生成的代码
- 学习最佳实践
- 积累 Prompt 模板
- 分享经验
---
## 案例演示
### 完整案例:从设计稿到上线
```markdown
## 案例:开发一个用户管理页面
### 1. PRD 阶段
**输入**: 产品需求文档
**AI 操作**:
- 分析需求
- 生成技术方案
- 评估工作量
### 2. 设计稿阶段
**输入**: Figma 设计稿
**AI 操作**:
- Figma to Code
- 生成组件结构
- 提取样式变量
### 3. 开发阶段
**AI 操作**:
- 生成页面组件
- 生成 API 请求
- 生成状态管理
- 生成工具函数
### 4. 测试阶段
**AI 操作**:
- 生成单元测试
- 生成 E2E 测试
- 生成测试数据
### 5. 代码审查
**AI 操作**:
- 代码质量检查
- 性能分析
- 安全检查
### 6. 部署阶段
**AI 操作**:
- 生成 CI/CD 配置
- 生成部署脚本
- 生成监控配置
### 时间对比
- 传统开发:5天
- AI 辅助开发:2天
- 效率提升:60%
常见问题
Q1: AI 生成的代码可靠吗?
A: AI 生成的代码需要人工审查:
✅ 可靠的场景:
- 标准的 CRUD 操作
- 常见的业务逻辑
- 测试代码生成
- 配置文件生成
⚠️ 需要谨慎的场景:
- 复杂的业务逻辑
- 安全相关代码
- 性能关键代码
- 架构设计
建议:
1. 始终进行代码审查
2. 运行测试验证
3. 理解生成的代码
4. 根据需要调整
Q2: 如何提高 AI 生成代码的质量?
A: 提高质量的方法:
1. 提供清晰的 Prompt
2. 提供项目上下文(.cursorrules)
3. 提供示例代码
4. 分步骤生成
5. 及时反馈和调整
6. 积累 Prompt 模板
Q3: AI 会取代开发人员吗?
A: AI 是工具,不是替代:
AI 擅长:
- 重复性工作
- 标准代码生成
- 代码补全
- 文档生成
人类擅长:
- 架构设计
- 业务理解
- 创新思维
- 复杂问题解决
结论:AI 辅助开发,提升效率,但不会取代开发人员。
总结
AI 辅助开发的价值
- 效率提升: 50-80% 的开发效率提升
- 质量提升: 代码规范统一,减少低级错误
- 学习加速: 快速学习新技术和最佳实践
- 创新能力: 快速验证想法,探索新方案
最佳实践
- 合理使用: 不是所有场景都适合 AI
- 代码审查: 始终审查 AI 生成的代码
- 持续学习: 学习 AI 生成的优秀代码
- 团队协作: 分享 Prompt 和经验
未来展望
- AI 能力持续提升
- 工具生态更加完善
- 开发模式持续演进
- 人机协作更加高效
相关文档: