这是「Cline 实战」系列第一篇。第二篇我会讲怎么把 Cline + Cursor 组合起来,搭建标准化的发布流程,从代码清理到 Git 提交一键串联。

说在前面
上周接了个活儿——接手一个停更了一年多的 React 老项目。
拉下来代码一看,血压直接上来了:
- JS 和 TS 混着写,一个文件里能出现三种引号风格
node_modules没在.gitignore里,仓库大小 800MB- 依赖锁着
package-lock.json是半年前的,npm install一跑报 40 多个 warning - 零测试,一个
.test.ts文件都没有 - 三处
console.log藏在业务逻辑里当调试用,提交记录里写着 "先注释掉回头再删"
这种项目你肯定也见过。搁以前,光理清代码结构、删冗余、装依赖、补测试,起码得折腾两三天。但这次我用了 Cline,半天就搞定了,下面把整个过程掰开揉碎讲讲。
Cline 是啥?为啥选它
简单说,Cline 是一个跑在 VS Code 里的 AI 编程 Agent。注意,不是那种只会补全代码的 Copilot,而是能真正理解你整个项目、帮你规划、改代码、跑终端命令的"干活型" Agent。
选它有三个原因:
- 开源免费(Apache 2.0),GitHub 60K+ Star,社区活跃
- 每步操作都要你点头才执行,不会瞎改你的代码
- 能直接在终端里跑命令,装依赖、跑测试、起服务,一条龙
还有个关键设计叫 Plan/Act 双模式,先想后做,下面实操中会讲到。
环境准备
安装 Cline
在 VS Code 里 Ctrl+Shift+X 打开扩展市场,搜 "Cline",安装。
如果你在用 Cursor,Cline 也能装。Cursor 本身基于 VS Code 内核,兼容性没问题。第二篇我会详细讲 Cline + Cursor 的配合。
配置模型
打开 Cline 侧边栏,点设置图标,选 API Provider。我选了 OpenRouter,因为它聚合了各家模型,切换方便。
模型选择策略:
| 任务类型 | 推荐模型 | 理由 |
|---|---|---|
| 项目分析、复杂重构 | Claude Sonnet | 推理强,代码质量高 |
| 简单改名、加注释 | DeepSeek Chat | 便宜,够用 |
| 快速原型 | GPT-4o | 响应快 |
这次接手老项目,全程用的 Claude Sonnet。
创建 .clinerules
在项目根目录建一个 .clinerules 文件,告诉 Cline 这个项目的规范。这一步很重要,相当于给 AI 立规矩:
# 项目规范
## 技术栈
- React 18 + TypeScript 5
- 状态管理用 Zustand
- 样式用 Tailwind CSS
- 测试用 Vitest + Testing Library
- 提交信息用 conventional commits 格式
## 编码约定
- 禁止使用 any,所有类型显式声明
- 组件用函数式 + hooks
- 删除所有 console.log
- 不使用的 import 必须清理
- 文件命名用 kebab-case
## 目录结构
- 组件放 src/components/
- hooks 放 src/hooks/
- 工具函数放 src/lib/
- 测试文件跟源文件同目录,加 .test 后缀
这个文件会随 Git 提交,团队其他人拉代码后 Cline 自动读取,比口头传规范靠谱多了。
第一步:清理冗余代码
切到 Plan 模式
Cline 有两个模式:
Plan 模式只读不改,先分析代码库,给你一个执行计划。Act 模式才真正动手改文件、跑命令。
我切到 Plan 模式,输入:
分析这个项目的整体结构,找出以下问题:
1. 未使用的 import 和变量
2. 重复的代码逻辑
3. console.log 调试残留
4. 已废弃但未删除的文件
5. TODO/FIXME 注释
给出清理计划,先不要改代码。
Cline 花了大概两分钟,扫描了整个 src/ 目录,然后给出了一份详细报告:
- 未使用 import:47 个文件中共 132 处
- console.log 残留:18 处,其中 3 处在业务逻辑里
- 重复逻辑:表单验证逻辑在 5 个组件里重复实现
- 废弃文件:3 个旧的 API mock 文件、2 个未使用的工具函数文件
- TODO/FIXME:11 处,最早的写着 "2023-01-15 临时方案"
切到 Act 模式执行清理
看完计划觉得没问题,切到 Act 模式,让它干活。
这里我开的是中等自动批准级别——读文件和跑 eslint 这类安全命令自动放行,但改文件还是手动确认。
Cline 的执行过程大概是这样的:
- 逐个文件清理未使用 import,每个文件改完都会弹一个 diff 视图让你确认
- 删掉 18 处
console.log,有 2 处它判断可能在错误处理流程里有用,提出来问我要不要保留 - 把 5 个重复的表单验证逻辑抽成一个
validateForm工具函数 - 删除 5 个废弃文件
- 跑了一遍
npx eslint src/ --fix自动修复格式问题
整个过程大概花了 40 分钟。要是手动搞,光找那 132 处未使用 import 就得半天。
第二步:更新依赖
老项目最头疼的就是依赖问题。package.json 里一堆版本号带 ^ 和 ~,锁文件还是半年前的。
还是在 Act 模式,我让 Cline:
检查 package.json 中的所有依赖:
1. 列出过期的依赖
2. 检查是否有已知安全漏洞
3. 给出升级建议,区分 major/minor/patch
4. 先跑 npm audit,把高危漏洞修了
Cline 先跑了个 npm audit,报告里有 4 个高危漏洞、12 个中危。然后它开始逐个处理:

有几个坑值得说一下:
坑 1:React 从 18.2 升到 18.3 时,有个第三方组件库报了类型不兼容。 Cline 自动定位到是 @types/react 版本不匹配,改了 package.json 里的版本范围,重装后搞定。
坑 2:有个 react-scripts 5.0 的依赖链里有漏洞,但升到 5.1 会破坏构建配置。 Cline 建议用 npm audit fix --force 但提醒我可能有 breaking change。我让它先在 --dry-run 模式跑一下看看影响范围,确认没问题才执行。
升级完,重新跑了一遍 npm install,warning 从 40 多个降到 3 个(都是无关紧要的 peer dependency 警告)。
第三步:生成单元测试
这是我觉得 Cline 最给力的地方。零测试的项目,让它补测试。
先在项目根目录装好 Vitest:
帮我配置 Vitest + @testing-library/react + jsdom,
然后给 src/components/ 下的核心组件生成单元测试,
覆盖率目标 70% 以上。
Cline 的 Plan 模式先分析了所有组件的依赖关系,列出了测试优先级:
| 优先级 | 组件 | 理由 |
|---|---|---|
| P0 | LoginForm |
核心业务逻辑,有表单验证 |
| P0 | useAuth hook |
认证逻辑,涉及 token 管理 |
| P1 | DataTable |
数据展示组件,逻辑复杂 |
| P1 | validateForm |
刚提取的公共函数 |
| P2 | Header / Footer |
纯展示组件,低风险 |
然后切到 Act 模式,逐个写测试。它不是随便凑几个 expect(true).toBe(true) 这种,而是真正分析了组件的 props 和内部逻辑,写了边界情况的测试:
// LoginForm.test.tsx - Cline 生成的测试
import {
render, screen, fireEvent } from '@testing-library/react'
import {
LoginForm } from './LoginForm'
describe('LoginForm', () => {
it('空表单提交时显示必填提示', () => {
render(<LoginForm onSubmit={
vi.fn()} />)
fireEvent.click(screen.getByRole('button', {
name: /登录/i }))
expect(screen.getByText(/请输入用户名/)).toBeInTheDocument()
expect(screen.getByText(/请输入密码/)).toBeInTheDocument()
})
it('密码少于6位时显示长度提示', () => {
render(<LoginForm onSubmit={
vi.fn()} />)
fireEvent.change(screen.getByPlaceholderText(/用户名/i), {
target: {
value: 'testuser' }
})
fireEvent.change(screen.getByPlaceholderText(/密码/i), {
target: {
value: '123' }
})
fireEvent.click(screen.getByRole('button', {
name: /登录/i }))
expect(screen.getByText(/至少6个字符/)).toBeInTheDocument()
})
it('合法输入时调用 onSubmit', () => {
const onSubmit = vi.fn()
render(<LoginForm onSubmit={
onSubmit} />)
fireEvent.change(screen.getByPlaceholderText(/用户名/i), {
target: {
value: 'testuser' }
})
fireEvent.change(screen.getByPlaceholderText(/密码/i), {
target: {
value: 'password123' }
})
fireEvent.click(screen.getByRole('button', {
name: /登录/i }))
expect(onSubmit).toHaveBeenCalledWith({
username: 'testuser',
password: 'password123'
})
})
})
跑完 vitest run --coverage,覆盖率从 0% 到了 73%。有两个组件的测试报了错,Cline 自动定位到是组件里有个异步加载的逻辑没处理好 loading 状态,修了代码后测试全绿。
整个测试生成过程大概花了 1 小时。
整条流水线长什么样
把三步串起来看:

花了多少钱、多久时间
| 环节 | 耗时 | Token 消耗 | 大约花费 |
|---|---|---|---|
| 项目分析 + 清理冗余 | ~40 min | ~35 万 | $1.05 |
| 更新依赖 | ~30 min | ~18 万 | $0.54 |
| 生成单元测试 | ~60 min | ~42 万 | $1.26 |
| 合计 | ~2.5 小时 | ~95 万 | ~$2.85 |
用 Claude Sonnet 跑的,Cline 侧边栏右上角会实时显示 token 消耗和成本。要是手动搞这些活儿,两天起步。花了不到三刀,值。
踩过的坑
说几个实操中遇到的问题,你们可以提前避雷。
1. 上下文窗口会爆
对话太长的时候,Cline 会开始"忘事"。比如清理冗余的时候聊了太久,切到写测试时它已经忘了前面的项目结构。
解法:每完成一个阶段就 /newtask 开新对话。Cline 会自动总结当前会话要点,带到新对话里。另外可以用 /smol 压缩上下文。
2. Act 模式手滑点错
有次 Cline 要删一个文件,我习惯性点了 Approve,其实那个文件还有用。
解法:Cline 有文件时间线功能,cmd+z 可以撤销。但最好还是开中等自动批准级别,改文件手动确认。
3. 模型选错了
一开始图便宜用了 DeepSeek 跑测试生成,生成的测试用例有一半是凑数的,没覆盖边界情况。后来换 Claude Sonnet 重跑,质量好了一大截。
解法:简单的改名、加注释用便宜模型;写测试、重构这种需要推理能力的,别省那几毛钱。
小结
这次接手老项目,Cline 帮我做了三件事:
- 清理冗余:132 处未使用 import、18 处 console.log、5 个废弃文件,40 分钟搞定
- 更新依赖:4 个高危漏洞全修,依赖版本统一到最新 patch
- 补齐测试:从 0 到 73% 覆盖率,核心组件都有边界测试
以前接手一个祖传项目,最烦的就是前三天——清理垃圾、修依赖、补测试,全是脏活累活。现在有 Cline 这条自动化流水线,半天就能让老项目"可发布"。
但这只是第一步。项目能跑了之后,怎么保证后续每次提交都干净、每次发布都靠谱?
下一篇我会讲怎么把 Cline + Cursor 组合起来,搭建一套标准化的发布流程——从代码规范检查、自动测试到 Git 提交,一条龙串起来。关注不错过。
下一篇预告:《Cline + Cursor 组合拳:从代码清理到 Git 提交,我的标准化发布流程》
会讲怎么用
.clinerules+ Auto-approve + 终端自动化,把发布流程串成一键执行。搭完之后,团队新人也能按标准流程走,不用再口口相传规范了。