截止日期逼近:Bolt-New 与 Windsurf 真实对比
上周四,我需要在周一前为客户构建一个库存仪表盘的功能原型。客户要求:一个带有搜索功能的实时库存表格、一张显示过去7天库存变动的图表,以及一个简单的添加新品表单。我的工具有两个:Bolt-New 和 Windsurf。我在同一任务上连续使用了这两个工具。以下是使用结果。
准备工作
我给每个工具相同的提示:
"创建一个React仪表盘,包含一个显示库存物品(名称、SKU、数量、最后更新时间)的表格。添加一个可过滤表格的搜索栏。包含一张显示过去7天数量变化的折线图。添加一个包含名称、SKU和数量字段的新增物品表单。使用Tailwind CSS。"
两个工具我都使用了默认设置。没有自定义提示,没有微调。只使用原始输出。
Bolt-New:首次尝试
Bolt-New 是一个基于浏览器的AI编码工具,可以从自然语言生成全栈应用。它运行在云虚拟机上,让你在构建过程中实时查看应用。
第一印象: Bolt-New 立即开始生成代码。它创建了一个使用 Vite 的React应用,安装了依赖项,并在大约45秒内构建了UI。仪表盘显示了一个表格、一个搜索栏和一个占位图表区域。
运行良好的部分:
- 表格使用虚拟数据渲染。搜索能即时过滤行。
- 表单出现在底部,包含三个字段。提交后会在表格中添加新行。
- 图表使用 Recharts 生成。显示了7个随机值的数据点。
出现问题的地方:
- 添加新物品时图表没有更新。它是静态的,只在加载时生成一次。
- 表单没有验证SKU格式。我输入了"abc-123",它接受了,尽管客户要求严格的8位字母数字格式。
- 搜索栏区分大小写。搜索"widget"没有找到"Widget"。
- "最后更新时间"列显示的是ISO格式的时间戳,而不是像"2小时前"这样的相对时间。
修复过程: 我输入了"让图表在添加新物品时更新"和"使搜索不区分大小写"。Bolt-New 重新生成了相关组件。图表开始更新,但搜索修复引入了一个bug:清除搜索后表格现在显示重复行。我不得不输入"修复清除搜索后重复行"来让它重新工作。
达到可用原型的时间: 8分钟,包括修复。
代码质量: 对于原型来说可以接受。组件都在一个文件(App.jsx)中。状态管理使用了useState,没有上下文或reducer。图表组件与父组件紧密耦合。
Windsurf:第二次尝试
Windsurf 是一个IDE插件(VS Code / JetBrains),充当"AI结对程序员"。它使用上下文感知模型,可以读取整个项目。
第一印象: Windsurf 没有生成完整的应用。相反,它打开了一个聊天面板并询问:"你想要什么样的项目结构?单文件还是多组件?"我选择了多组件。然后它生成了一个文件夹结构:src/components/Table.jsx、src/components/Chart.jsx、src/components/Form.jsx、src/hooks/useInventory.js、src/App.jsx。
运行良好的部分:
- 搜索默认不区分大小写。
- 图表使用
useEffect在库存列表变化时重新获取数据。它实时更新。 - 表单有验证:SKU必须恰好8个字符,只能包含字母数字。它显示了内联错误消息。
- "最后更新时间"列使用
date-fns(formatDistanceToNow)显示相对时间。 - 代码是模块化的。每个组件有自己的文件。状态管理使用带有
useReducer的自定义钩子。
出现问题的地方:
- 初始图表没有渲染。
useEffect缺少一个依赖项。我不得不将[inventory]添加到依赖数组中。 - 表单提交后没有清除字段。用户必须手动清除它们。
- 表格没有分页。对于它生成的20个虚拟物品来说还好,但对于实际使用来说,这将无法使用。
修复过程: 我输入了"修复图表依赖数组"和"提交后清除表单"。Windsurf 内联进行了更改,没有重新生成整个文件。它还建议添加分页,我接受了。它添加了简单的"上一页/下一页"按钮,页面大小为10。
达到可用原型的时间: 12分钟,包括修复和分页。
代码质量: 好得多。自定义钩子很干净。组件是单一职责的。图表使用了单独的数据转换函数。
对比表格
| 特性 | Bolt-New | Windsurf |
|---|---|---|
| 定价 | 免费版:每月5个项目,每个运行时10分钟。Pro版:20美元/月(无限项目,60分钟运行时)。 | 免费版:每月50次请求。Pro版:15美元/月(每月500次请求)。团队版:25美元/月(无限请求)。 |
| 设置时间 | 0分钟(基于浏览器) | 5分钟(安装插件,打开项目) |
| 首次生成 | 45秒 | 2分钟(生成结构+文件) |