← 返回日报
🌐 机器翻译 · DeepSeek · GitHub

millionco react-doctor


好的,这是您要求的英文文章的中文翻译,已按照规范处理。


millionco react-doctor

您的智能体编写了糟糕的 React 代码,这个工具能捕获它。一条命令即可扫描您的代码库,并输出一个 0 到 100 的健康评分,附带可操作的诊断信息。适用于 Next.js、Vite 和 React Native。

查看实际效果 →

安装

在您的项目根目录运行:

npx -y react-doctor@latest .

您将获得一个评分(75+ 优秀,50 到 74 需要改进,低于 50 严重)以及一系列问题列表,涵盖状态与副作用、性能、架构、安全、可访问性和死代码。规则会根据您的框架和 React 版本自动切换。

Main.mp4

为您的编码智能体安装

教会您的编码智能体 React 最佳实践,使其从一开始就停止编写糟糕的代码。

npx -y react-doctor@latest install

系统会提示您选择要为哪些检测到的智能体进行安装。传递 --yes 参数可跳过提示。

适用于 Claude Code、Cursor、Codex、OpenCode 以及 50 多个其他智能体。

GitHub Actions

一个复合操作(composite action)随此仓库一起提供。将其放入 .github/workflows/react-doctor.yml

name: React Doctor
on:
  pull_request:
  push:
    branches: [main]
permissions:
  contents: read
  pull-requests: write # 需要用于发布 PR 评论
jobs:
  react-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0 # `diff` 需要
      - uses: millionco/react-doctor@main
        with:
          diff: main
          github-token: ${{ secrets.GITHUB_TOKEN }}

当在 pull_request 事件上设置了 github-token 时,发现的问题会作为 PR 评论发布(并更新)。该操作还会暴露一个评分输出(0–100),您可以在后续步骤中使用。

输入参数: directoryverboseprojectdiffgithub-tokenfail-onerror / warning / none)、offlinenode-version。完整说明请参阅 action.yml

不想使用市场操作?纯 npx 形式也可以:

- run: npx -y react-doctor@latest --fail-on warning

配置

在项目根目录创建 react-doctor.config.json

{
  "ignore": {
    "rules": [
      "react/no-danger",
      "jsx-a11y/no-autofocus"
    ],
    "files": [
      "src/generated/**"
    ],
    "overrides": [
      {
        "files": [
          "components/modules/diff/**"
        ],
        "rules": [
          "react-doctor/no-array-index-as-key",
          "react-doctor/no-render-in-render"
        ]
      },
      {
        "files": [
          "components/search/HighlightedSnippet.tsx"
        ],
        "rules": [
          "react/no-danger"
        ]
      }
    ]
  }
}

三个嵌套键,三个层次的粒度——选择最适合您的最窄范围:

您也可以在 package.json 中使用 "reactDoctor" 键。

CLI 标志始终覆盖配置值。

React Doctor 会尊重 .gitignore.eslintignore.oxlintignore.prettierignore 以及 .gitattributes 中的 linguist-vendored / linguist-generated 注释。行内 // eslint-disable*// oxlint-disable* 注释也会被识别。

如果您有 JSON 格式的 oxlint 或 eslint 配置(.oxlintrc.json.eslintrc.json),其规则会自动合并到扫描中并计入评分。设置 adoptExistingLintConfig: false 可选择退出。

可选的配套插件

当在扫描的项目中(或在您的 monorepo 中提升)安装了以下 ESLint 插件时,React Doctor 会将其规则纳入同一扫描。两者都列为可选的 peer 依赖项——只安装您需要的。

| 插件 | 添加内容 | 命名空间 | | :--- | :--- | :--- | | eslint-plugin-react-hooks (v6 或 v7) | React Compiler 前端的正确性规则——当在项目中检测到 React Compiler 时触发。 | react-hooks-js/* | | eslint-plugin-react-you-might-not-need-an-effect (v0.10+) | 补充性的“副作用即反模式”规则(no-derived-stateno-chain-state-updatesno-event-handlerno-pass-data-to-parent 等),与 React Doctor 原生的“状态与副作用”规则一起运行。 | effect/* |

行内抑制

// react-doctor-disable-next-line react-doctor/no-cascading-set-state
useEffect(() => {
  setA(value);
  setB(value);
}, [value]);

当同一行触发了两个规则时,您有两个等效的选择。

在单个注释中用逗号分隔规则 ID:

// react-doctor-disable-next-line react-doctor/rerender-state-only-in-handlers, react-doctor/no-derived-useState
const [localSearch, setLocalSearch] = useState(searchQuery);

或者直接在诊断代码上方为每个规则堆叠一个注释。只要堆叠的注释与目标行之间没有其他内容(除了其他 react-doctor-disable-next-line 注释),它们就会被识别:

// react-doctor-disable-next-line react-doctor/rerender-state-only-in-handlers
// react-doctor-disable-next-line react-doctor/no-derived-useState
const [localSearch, setLocalSearch] = useState(searchQuery);

堆叠注释之间的代码行会中断链接:只有紧邻诊断代码上方的注释(以及堆叠在其上的任何连续的 react-doctor-disable-next-line 注释)会被识别。

如果一个注释看起来是相邻的,但规则仍然触发,请运行 react-doctor --explain ——它会报告是否找到了附近的抑制注释、它覆盖了哪些规则以及为什么它没有生效。

块注释在 JSX 内部有效:

{/* react-doctor-disable-next-line react/no-danger */}

对于多行 JSX,将注释直接放在开始标签上方会覆盖整个属性列表(符合 ESLint 约定)。

Lint 插件(独立)

同一套规则集同时作为 oxlint 插件和 ESLint 插件提供,因此您可以将其接入项目已运行的任何 lint 引擎。

oxlint.oxlintrc.json 中:

{
  "jsPlugins": [{
    "name": "react-doctor",
    "specifier": "react-doctor/oxlint-plugin"
  }],
  "rules": {
    "react-doctor/no-fetch-in-effect": "warn",
    "react-doctor/no-derived-state-effect": "warn",
  },
}

ESLint 扁平配置:

import reactDocto

📖 阅读原文 →