Tips & Tricks (更新: 2026/6/2)

用 Claude Code 配置 ESLint Flat Config

用Claude Code搭建ESLint Flat Config,覆盖TypeScript、React、Astro、CI校验和修复提示词。

用 Claude Code 配置 ESLint Flat Config

不要把ESLint配置完全交给Claude Code猜

ESLint是JavaScript和TypeScript的静态分析工具。静态分析指的是在代码真正运行前检查源码,提前发现未处理的Promise、危险的HTML注入、React Hooks误用、无障碍问题和团队风格不一致。

ESLint v9以后,Flat Config成为主流配置方式。到2026年6月,官方文档仍然围绕eslint.config.jseslint.config.mjs说明配置文件。但是,只对Claude Code说“帮我配置ESLint”还不够。它可能混入旧.eslintrc写法,也可能跳过类型信息,或者启用一堆让CI变慢却没有实际收益的规则。

更稳妥的做法是先给Claude Code一个明确边界:项目是什么技术栈、哪些目录是生成物、哪些命令必须通过、哪些规则可以在测试文件中放宽。本文把Masa在React管理后台、Astro内容站和TypeScript库里验证过的流程整理成可复制的版本。

官方资料建议同时查看:ESLint Configuration Filestypescript-eslint typed lintingeslint-plugin-astro User Guide以及Claude Code CLI reference

先固定依赖和scripts

让Claude Code改文件之前,先安装和项目匹配的依赖。基础依赖覆盖ESLint、TypeScript、React、Hooks、无障碍检查和import排序。只有Astro项目才需要额外安装Astro插件。

npm i -D eslint @eslint/js typescript typescript-eslint globals
npm i -D eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
npm i -D eslint-plugin-simple-import-sort

# 只有Astro项目需要
npm i -D eslint-plugin-astro astro-eslint-parser

package.json里要把本地修复和CI校验分开。lint:fix用于本地整理,linttypecheck用于CI。--max-warnings=0会让警告也导致失败,旧项目第一次导入时可以等清理完成后再启用。

{
  "scripts": {
    "lint": "eslint . --max-warnings=0",
    "lint:fix": "eslint . --fix",
    "lint:debug": "eslint --print-config src/App.tsx > .eslint-debug.json",
    "typecheck": "tsc --noEmit",
    "ci:verify": "npm run lint && npm run typecheck"
  }
}

整体流程可以这样理解。Claude Code不应该只生成配置文件,还要执行团队以后会执行的验证命令。

package.json scripts
  -> eslint.config.mjs
  -> npm run lint:fix
  -> npm run lint
  -> npm run typecheck
  -> CI gate
  -> 让Claude Code复查剩余diff

TypeScript/React项目的Flat Config

React + TypeScript项目可以从下面的eslint.config.mjs开始。projectService: true会启用类型信息,让规则不仅看语法,还能理解TypeScript类型。它很有用,但也会增加开销,所以生成目录和构建产物一定要提前忽略。

import js from "@eslint/js";
import globals from "globals";
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import jsxA11y from "eslint-plugin-jsx-a11y";
import simpleImportSort from "eslint-plugin-simple-import-sort";
import tseslint from "typescript-eslint";

export default tseslint.config(
  {
    ignores: [
      "node_modules/",
      "dist/",
      "build/",
      "coverage/",
      ".next/",
      ".astro/",
      "public/",
      "*.min.js"
    ]
  },
  js.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  ...tseslint.configs.stylisticTypeChecked,
  {
    files: ["**/*.{js,mjs,cjs,ts,tsx}"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      globals: {
        ...globals.browser,
        ...globals.node,
        ...globals.es2024
      },
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname
      }
    }
  },
  {
    files: ["**/*.{jsx,tsx}"],
    ...react.configs.flat.recommended,
    settings: {
      react: { version: "detect" }
    },
    rules: {
      ...react.configs.flat.recommended.rules,
      "react/react-in-jsx-scope": "off",
      "react/prop-types": "off"
    }
  },
  {
    files: ["**/*.{jsx,tsx}"],
    plugins: {
      "react-hooks": reactHooks,
      "jsx-a11y": jsxA11y
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      ...jsxA11y.configs.recommended.rules
    }
  },
  {
    plugins: {
      "simple-import-sort": simpleImportSort
    },
    rules: {
      "simple-import-sort/imports": "error",
      "simple-import-sort/exports": "error",
      "@typescript-eslint/consistent-type-imports": [
        "error",
        { prefer: "type-imports", fixStyle: "separate-type-imports" }
      ],
      "@typescript-eslint/no-floating-promises": "error",
      "@typescript-eslint/no-misused-promises": [
        "error",
        { checksVoidReturn: { attributes: false } }
      ],
      "@typescript-eslint/no-unused-vars": [
        "error",
        { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }
      ],
      "no-console": ["warn", { allow: ["warn", "error"] }]
    }
  },
  {
    files: ["**/*.{js,mjs,cjs}"],
    extends: [tseslint.configs.disableTypeChecked]
  },
  {
    files: ["**/*.{test,spec}.{ts,tsx}", "**/__tests__/**/*.{ts,tsx}"],
    rules: {
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-unsafe-assignment": "off",
      "@typescript-eslint/no-unsafe-member-access": "off"
    }
  }
);

这个配置的重点不是追求个人偏好的格式,而是抓住真正会影响线上质量的问题。no-floating-promises能发现忘记await的异步调用,no-misused-promises能减少React事件处理里的危险Promise,consistent-type-imports让类型导入保持清晰。测试文件可以局部放宽,但不要因此降低生产代码标准。

Astro网站要单独处理.astro

Astro文件里同时有模板、TypeScript frontmatter、组件调用和客户端脚本。如果把React规则直接套到.astro文件上,ESLint常常还没开始检查就解析失败。

Astro内容站可以先使用插件的Flat推荐配置,再给.astro增加安全规则。astro/no-set-html-directive对博客和文档站尤其有价值,因为HTML注入在内容审稿时很容易被忽略。

import js from "@eslint/js";
import astro from "eslint-plugin-astro";
import globals from "globals";
import tseslint from "typescript-eslint";

export default tseslint.config(
  {
    ignores: ["dist/", ".astro/", "node_modules/", "public/"]
  },
  js.configs.recommended,
  ...astro.configs["flat/recommended"],
  ...astro.configs["jsx-a11y-recommended"],
  ...tseslint.configs.recommendedTypeChecked,
  {
    files: ["**/*.{ts,tsx}"],
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node
      },
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname
      }
    }
  },
  {
    files: ["**/*.astro"],
    languageOptions: {
      parserOptions: {
        parser: tseslint.parser,
        extraFileExtensions: [".astro"],
        projectService: true,
        tsconfigRootDir: import.meta.dirname
      }
    },
    rules: {
      "astro/no-set-html-directive": "error",
      "astro/no-unused-define-vars-in-style": "error"
    }
  }
);

不要让ESLint承担所有格式化任务。格式交给Prettier,ESLint专注于危险代码、无障碍、类型相关错误和项目规则。可以搭配阅读Claude Code的Prettier配置指南

三个真实使用场景

场景一是SaaS管理后台。邀请用户、修改账单状态、调整权限都依赖异步逻辑。这里@typescript-eslint/no-floating-promises应该设为error,否则一个遗漏的await就可能变成真实事故。

场景二是Astro技术博客。最有价值的检查是.astro解析、无障碍、未使用样式和危险HTML。因为站点通常有大量生成页,所以忽略dist/.astro/和其他输出目录非常重要。

场景三是TypeScript库。公开API要比测试更严格。生产代码保持类型import、未使用变量和export规则,测试fixture里再局部允许any

项目应该加强的规则可以放宽的位置
React管理后台Promise、Hooks、a11yStorybook mock
Astro博客.astro、HTML注入、未使用CSS生成内容
TypeScript库类型import、未使用变量、export测试fixture

如果还要在提交前做快速检查,可以继续看Husky + lint-staged指南。大型仓库里,pre-commit保持轻量,把更重的类型lint放到CI更实际。

用CI固定校验

本地通过不代表团队通过。CI必须运行同一组命令。GitHub Actions可以用下面这个最小配置。

name: code-quality

on:
  pull_request:
  push:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck

如果旧项目一次出现几百个错误,不要直接全仓库eslint --fix然后提交巨大diff。先按规则分类,再让Claude Code从风险最高、影响最小的类别开始修复。

npm run lint
npm run lint:fix
npm run lint
npm run typecheck
npm run lint:debug

lint:debug会输出某个文件最终命中的配置。当React规则错误地影响.astro,或者测试文件的放宽规则泄漏到生产代码时,它很有用。

Claude Code修复提示词

模板一:新导入。

请为这个仓库导入ESLint Flat Config。
技术栈是TypeScript + React。先阅读package.json、tsconfig和现有lint设置。
创建eslint.config.mjs,并持续修复直到npm run lint和npm run typecheck通过。
避免会改变行为的自动修复;如果必须做,请先说明理由。

模板二:修复lint错误。

我会粘贴npm run lint的输出。
请按规则分类,先修复风险低且影响小的错误,保持diff尽量小。
eslint-disable只能作为最后手段;如果使用,请写一行理由。
修改后执行npm run lint和npm run typecheck。

模板三:Astro支持。

请检查这个Astro站点的ESLint设置。
把.astro、.ts、.tsx的配置分开,并使用eslint-plugin-astro的Flat推荐配置。
将astro/no-set-html-directive设为error,并确认React规则没有错误作用到整个.astro文件。

模板四:CI失败调查。

GitHub Actions的lint job失败了。
请比较本地和CI里的Node、npm、ESLint及插件版本。
先写出复现命令,再区分需要改配置、更新依赖还是修改源码。
用最小安全diff修复。

给Claude Code的提示词要包含读取范围、执行命令和禁止事项。“修复lint”太宽泛,“不要削弱生产规则,并用这些命令证明修复完成”才更安全。

常见落坑

第一个坑是把旧.eslintrcextends链直接复制到Flat Config。两者结构不同。必须使用旧共享配置时可以考虑兼容层,但优先选插件文档里的Flat示例。

第二个坑是把类型lint套到所有文件。projectService: true很强,但生成物、打包文件和构建产物会拖慢CI。先写好ignores,比后面抢救CI时间更省事。

第三个坑是提交巨大的自动修复diff。import排序、类型import、未使用变量和格式变化会掩盖真正的行为变化。Masa第一次导入时通常按Promise、import、框架规则拆成小PR。

第四个坑是长期保留warning。永远不阻塞的warning会变成背景噪音。团队规则用error,临时教育用warn,信号弱的规则就不要启用。

第五个坑是不给Claude Code说明意图。告诉它“无障碍不能降级”“测试fixture允许any”“公开API要更严格”,比泛泛使用推荐配置更可靠。

总结

ESLint Flat Config把配置集中在一个文件里,规则责任边界更清楚。Claude Code的价值不是一次性生成文件,而是读取现有代码、运行检查、在不削弱标准的前提下逐步修正。

先选择React/TypeScript或Astro的正确基线,把npm run lintnpm run typecheck放进CI,再用上面的模板让Claude Code小步修复。所有eslint-disable和大型--fix diff都应该由人审。

后续可以继续配置PrettierHusky + lint-staged。如果需要可复用的审查提示词和导入清单,也可以看ClaudeCodeLab教材页

实际试用结果

Masa把这套配置放进一个React管理后台和Astro博客雏形中测试。第一次主要暴露了import顺序噪音和未处理Promise。一次性eslint --fix生成的diff很难审,所以按Promise、import、Astro安全规则分批处理更稳定。最终,把npm run lintnpm run typecheck固定到CI,再把失败日志交给Claude Code小步修复,是最可重复的做法。

#Claude Code #ESLint #コード品質 #TypeScript #開発環境
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。