Codex 还在用 React.FC、componentWillMount 这类废弃 API:怎么锁到现代写法

Codex 输出多年前废弃的 API,因为训练数据滞后。用 AGENTS.md、ESLint deprecation 规则、最新 docs 把它锁到现代写法。

你 review Codex 的 PR:新组件写 React.FC<Props>、另一个文件 import componentWillMount、还有一处 useEffect 的 callback 返回 Promise。这些不算 “错”——都能跑——但 React.FC 自 React 18 起不推荐、componentWillMount 自 React 16.3 起废弃、async effect 会泄漏。你现存代码都没这些写法;Codex 自己注进去的。

原因是训练数据滞后。Codex 训练数据截止在这些写法过气之前。放任不管它就写 2019 风味的 React、2015 风味的 Node、Python 2 风味的 type hint。修法是 AGENTS.md 显式规则 + ESLint deprecation 强制 + 指给 agent 看现行 doc。

常见原因

1. 训练数据早于这个 API 废弃

React.FC 在 2019 年很流行,2021 年左右失宠。基于 2022 年以前 GitHub 训练的 model 还在产出。类似的:componentWillMountcomponentWillReceiveProps、jQuery、var、Python 2 print 语句、Node request 库。

如何判断:diff 里出现了你 codebase 其他地方都没有的写法。grep 自己 repo 一下,别处零次,那就是 Codex 从训练数据拉的。

2. AGENTS.md 没写框架版本

Codex 不知道你的 React、Node、Python、框架版本是哪一代。它选训练数据里最常见的写法,可能和你版本匹配也可能不。

如何判断grep -i 'version\|deprecated\|prefer\|avoid' AGENTS.md 没写框架约定。

3. ESLint 装了但没拦废弃 API

有 ESLint,但没装 eslint-plugin-reacteslint-plugin-deprecation。agent 输出的古董代码 lint 不抓。

如何判断npm run lint 在带明显废弃代码的 PR 上还是过。

4. agent 看了 README 里过时的 tutorial

你的 README.mddocs/setup.md 还展示 class extends React.ComponentcomponentWillMount。Codex 当 “house style” 抄了。

如何判断grep -rn 'componentWillMount\|React.FC\|var ' README.md docs/ 有 match。

5. Codex 装了流行但过时的 npm 包

它加了 requestmomentnode-fetch@2uuid@3——都是当年流行、现在被认为废弃或被取代的。训练数据里满地都是。

如何判断npm install log 有 “deprecated” 警告。package.json 新增了已知过时的 dep。

最短修复路径

Step 1:AGENTS.md “只用现代写法” 规则

## API 和框架规则

技术栈:React 18、TypeScript 5、Node 20、Python 3.12。

新代码或改动代码里禁用:

- React class component——只用 function component + hook
- `React.FC` / `React.FunctionComponent`——直接给 props 标类型
- `componentWillMount``componentWillReceiveProps``componentWillUpdate`
- jQuery、Backbone、任何 2020 年以前的代码风格
- `var`——用 `const` / `let`
- TS/ESM 里的 `require()`——用 `import`
- `useEffect` 里返回 Promise 的 callback
- npm:`request``moment``node-fetch@2``uuid@3`——见 "approved packages"
- Python:`print` 语句、`urllib2``from __future__`、type comment

不确定某个写法是否还活着,先去看那个包的 GitHub README 里有没有 "deprecated"。

agent 有具体清单可对照,不用 vibes。

Step 2:装 eslint-plugin-deprecation 和 React 专用规则

npm install --save-dev eslint-plugin-deprecation @typescript-eslint/eslint-plugin eslint-plugin-react

.eslintrc.js

module.exports = {
  plugins: ['deprecation', 'react', '@typescript-eslint'],
  rules: {
    'deprecation/deprecation': 'error',
    'react/no-deprecated': 'error',
    'react/prefer-stateless-function': 'warn',
    '@typescript-eslint/ban-types': ['error', {
      types: {
        'React.FC': {
          message: '直接给 props 标类型,不要用 React.FC',
          fixWith: 'function-component'
        }
      }
    }],
    'no-restricted-imports': ['error', {
      paths: [
        { name: 'request', message: '用内置 fetch。' },
        { name: 'moment', message: '用 date-fns 或 Temporal。' },
        { name: 'node-fetch', message: 'Node 18+ 用全局 fetch。' }
      ]
    }]
  }
}

这样 Codex 的废弃写法直接 lint fail。agent 读 lint 输出会自己改。

Step 3:把 agent 指向最新 doc

AGENTS.md 加 “docs” 节:

## 参考文档(用这些,不要看老 tutorial)

- React:https://react.dev/(不是 legacy.reactjs.org)
- Next.js:https://nextjs.org/docs(App Router、server component)
- Node:https://nodejs.org/docs/latest-v20.x/api/
- TypeScript:https://www.typescriptlang.org/docs/handbook/
- Python:https://docs.python.org/3.12/

引用某个写法时,给上面这些里某个的链接。不许引用 2023 年以前的博客。

agent 会从指定域名拉写法,而不是泛训练数据。

Step 4:清理 codebase 里现存的废弃写法

repo 里的老代码等于给 Codex “可以这样写” 的许可。扫一遍:

# React
grep -rn 'React\.FC\|componentWillMount\|componentWillReceiveProps' src/
# Node
grep -rn "require\('request')\|from 'moment'" src/ package.json
# TypeScript
grep -rn ': any\b\|@ts-ignore' src/

把现存的迁了。agent 在 repo 里看不到这些,就不会再引入。

Step 5:CI 加 deprecation scan

# .github/workflows/deprecation-check.yml
name: Deprecation check
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - run: npm run lint
      - name: Custom deprecation scan
        run: |
          if grep -rn -E 'React\.FC|componentWillMount|require\(.request.\)' src/; then
            echo "发现废弃写法"
            exit 1
          fi

设 required status check,Codex 没法把废弃代码 merge 进去。

Step 6:定期 npm outdated 升 dep

老 dependency 拖着老 type definition。过期 @types/react 可能还在导出 React.FC。每季度刷一次:

npm outdated
npx npm-check-updates -u
npm install
npm test

新版 @types/react 即使没别的规则,也会把 Codex 引向现代写法。

预防

  • AGENTS.md 显式列出废弃写法和对应的现代替代
  • eslint-plugin-deprecationreact/no-deprecated 配成 error
  • AGENTS.md 里 “参考文档” 节指向当前正典 source
  • 清理现存 codebase 里的老写法,agent 才不会 “对齐” 老风格
  • CI 把 lint + grep-based deprecation scan 设成 required check
  • 季度刷 dependency;npm outdated,尤其 @types/*

相关

标签: #Codex #agent #排查 #deprecated