我用AI重构了一段500行的屎山代码,这是我的Prompt和思考过程

哈喽,大家好,相信很多前端小伙伴开发时已经离不开AI了,我们在用AI IDE时如何让AI为我们生成的代码更合理,可读性更强,更好维护呢。Prompt很关键。今天这篇文章,也许能给你带来一些启发。

链接:https://juejin.cn/post/7570630923710054452

作者:ErpanOmer

我们团队,维护着一个有5年历史的史诗级中后台项目😖。在这座屎山里,有一个叫handleOrderSubmit.js的文件。

可以下载瞧一瞧 有多屎👉 handleOrderSubmit.js[1]

它是一个长达500多行的React useEffect 钩子函数(是的,你没看错,一个useEffect)。

它混合了订单数据的本地校验价格计算优惠券应用API请求全局状态更新、以及错误弹窗处理... 所有的逻辑,都塞在一个函数里,用if/elsetry/catch层层嵌套。

没人敢动它😖。

本事试试看.gif
本事试试看.gif

每次产品经理提一个小需求,比如在提交订单时,增加一种新的优惠券类型,我们整个团队的表情都像被雷劈了。因为我们知道,改这个函数,要么加班一周,要么就等着P0级事故。

上周,产品经理要求我们在这个函数里,加入一个全新的风控逻辑。

我评估了一下,手动重构,至少需要一个资深工程师一周的时间,而且风险极大。

我受够了。我决定,把这个烫手的任务,扔给我的实习生——AI(我用的是GPT-5 mini,穷😂)。

这篇文章,就是我人机协作,啃下这块硬骨头的完整复盘,大家继续看。

我不能直接说重构它

我犯的第一个错误,是直接把500行代码贴给AI,然后说:帮我重构这段代码

AI很听话,它给我的,是一段看起来更整洁的代码——它把if/else换成了switch,提了几个变量... 这不叫重构,这叫重新排版,毫无意义。

我很快意识到:AI是一个能力超强、但没有灵魂的执行者。我,作为开发者,必须给它提供一个清晰的方案。

于是,我制定了一个五步重构法

我的Prompt和思考

我的核心思想是:AI负责执行,我负责决策。 我要像一个指挥家一样,一步一步地引导AI,把这500行的代码,拆解成高内聚、低耦合的模块。

第一步:先让AI读懂屎山

我不能上来就让AI改。我得先确认,它和我对这段代码的理解,在一个频道上。

Prompt:

你是一个资深的React架构师。请分析下面这段500行的useEffect代码。

  1. 告诉我它做了几件主要的事情?(职责分析)
  2. 找出所有的副作用(比如API请求、localStorage操作、全局状态更新)。
  3. 找出所有的纯逻辑(比如数据校验、价格计算)。
  4. 评价它的可维护性和可测试性
image.png
image.png

GPT的回答,给了我一个惊喜。它清晰地列出了:

  1. 职责:它承担了至少5个职责:表单校验、价格计算、库存检查、创建订单、处理UI反馈。
  2. 副作用api.post(...)setLoading(true)showToast(...)...
  3. 纯逻辑validateForm(...)calculateTotalPrice(...)...
  4. 评价:可维护性极低,单一职责原则被严重违反,几乎不可测试。

很好,AI看懂了!我们就可以可以开始了😁。

第二步:先分离纯逻辑代码

这是最关键的一步。我要把计算和动作分开。

Prompt:

非常好。现在,请你只针对纯逻辑部分(表单校验、价格计算)进行重构。

  1. 把这些逻辑,从原函数中提取出来,变成独立的、可导出的纯函数
  2. 这些函数必须是纯的:不能有任何副作用(不能调用apisetLoading)。
  3. 使用TypeScript,为这些新函数的入参和返回值,提供清晰的类型定义。
image.png
image.png

AI立刻唰唰唰地给了我几个文件:

validate.ts:

export function validateOrder(formData: OrderForm): string | null {
  if (!formData.user) return '用户信息不能为空';
  if (formData.items.length === 0return '商品不能为空';
  // ... 10 more rules
  return null;
}

calculator.ts:

export function calculateTotalPrice(items: Item[], coupon: Coupon): number {
  let total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  if (coupon.type === 'PERCENT') {
    total *= (1 - coupon.value / 100);
  }
  // ... 20 more rules
  return total;
}
第三步:让AI为自己的代码做测试

我怎么知道AI提炼的逻辑,是对的还是错的?答案:让它自己写单元测试来证明。

Prompt:

你现在是一个QA工程师。请使用Vitest,为你刚才提取的validateOrdercalculateTotalPrice这两个函数,编写全面的单元测试用例。 必须覆盖所有边界情况,包括正常、异常、和边缘值。

AI再次给了我惊喜。它生成的测试用例,比我手写的还要全:

// calculator.test.ts
import { describe, it, expect } from'vitest';
import { calculateTotalPrice } from'./calculator';

describe('calculateTotalPrice'() => {
  it('should return 0 for empty cart'() => {
    expect(calculateTotalPrice([], null)).toBe(0);
  });

  it('should apply percent coupon'() => {
    const items = [{ price: 100, quantity: 1 }];
    const coupon = { type'PERCENT', value: 10 };
    expect(calculateTotalPrice(items, coupon)).toBe(90);
  });
// ... 省略更多
});

我把这些测试用例跑了一遍,全部通过。我现在信心大增😁。

第四步:重写协调层

现在,纯逻辑已经被分离并验证了。原来的500行屎山,只剩下副作用和流程控制代码了。是时候重写它了。

Prompt:

干得漂亮。现在,我们来重构那个原始的useEffect函数

  1. 它现在唯一的职责是协调
  2. 调用我们刚才创建的validateOrdercalculateTotalPrice纯函数。
  3. 把所有的副作用(API请求、setLoadingshowToast清晰地编排起来。
  4. **使用async/await**,让异步流程更清晰,用try/catch处理错误。

这次,AI给我的,是一个只有30行左右的、清晰的流程代码:

// 重构后的 useEffect
useEffect(() => {
const submitOrder = async () => {
    setLoading(true);
    try {
      // 1. 协调:验证 (纯)
      const errorMsg = validateOrder(formData);
      if (errorMsg) {
        showToast(errorMsg);
        return;
      }
      
      // 2. 协调:计算 (纯)
      const totalPrice = calculateTotalPrice(formData.items, formData.coupon);

      // 3. 协调:副作用(不纯)
      const result = await api.post('/order/submit', { ...formData, totalPrice });
      
      // 4. 协调:响应(不纯)
      if (result.code === 200) {
        showToast('订单提交成功!');
        router.push('/success');
      } else {
        showToast(result.message);
      }
    } catch (err) {
      showToast(err.message);
    } finally {
      setLoading(false);
    }
  };

if (isSubmitting) { // 假设一个触发条件
    submitOrder();
    setIsSubmitting(false);
  }
}, [isSubmitting, formData /* ...其他依赖 */]);

第五步:最后守卫工作,加入新功能

别忘了,我重构的目的,是为了加风控这个新功能。

Prompt:

最后一步。请在API请求之前,加入一个风控检查的逻辑(调用riskControl.check(...))。这是一个异步函数,如果检查不通过,它会抛出一个错误。

AI在第2步和第3步之间,加了几行代码,完美收工。

这次重构,我总共花了大概5个小时,而不是原计划的一周。

总觉得 AI 不会淘汰会写代码的工程师。

只会降维打击那些只会堆砌代码的工程师。

那段500行的屎山,在过去,是我的噩梦;现在,有了AI的帮助,它变成了我的靶场。

这种感觉,真爽🙌。

🔥号外~号外~

最近我们推出了大厂的一手面经模块,都是刚面完的小伙伴们热乎乎分享的:

  • 字节、阿里、腾讯最新面试真题
  • 面试流程和注意事项
  • 面试官的重点提问和考察点

这些面经都是花了不少心思整理的,比网上那些过时的八股文靠谱多了。

有需要的小伙伴可以点击这里👉前端面试题宝典打开小程序,首页即可直接领取【大厂真实面经】),也可直接联系小助手咨询。

毕竟信息差就是竞争力,早点了解面试套路,早点拿到心仪offer!

有会员购买、辅导咨询的小伙伴,可以通过下面的二维码,联系我们的小助手。

Image


   “分享、点赞在看” 支持一波👍