当前位置: 首页 > news >正文

从零配置 ESLint 9 + React + TypeScript:踩坑与终极解决方案

带你彻底搞懂 ESLint 扁平配置(Flat Config),告别 'React' must be in scope 和各种奇怪的插件兼容问题。

前言

最近在使用 Vite + React 19 + TypeScript 搭建项目时,想接入 ESLint 来规范代码。本以为运行 pnpm create @eslint/config 就能一键搞定,结果却连续踩了五六个坑:

  • 'React' must be in scope when using JSX
  • TypeError: Plugin config "jsx-runtime" ... cannot be used in this context
  • TypeError: contextOrFilename.getFilename is not a function
  • Warning: React version not specified
  • Plugin "plugin:react" not found

经过一番研究,我终于梳理出了一套稳定、干净、无报错的 ESLint 9 扁平配置方案。本文将完整记录踩坑过程与最终解决方案,希望对遇到类似问题的同学有所帮助。

一、为什么选择 ESLint 9 扁平配置?

ESLint 从 9.0 开始将扁平配置(Flat Config)作为默认配置格式,取代了传统的 .eslintrc 方式。扁平配置的核心是一个导出的数组,每个对象可以包含 filesignoreslanguageOptionspluginsrules 等字段,配置组合更加直观和强大。

然而,官方脚手架 pnpm create @eslint/config 生成的配置往往存在兼容性问题,尤其是与 eslint-plugin-react@typescript-eslint 配合使用时。

二、最终可用的完整配置文件

先上成品,不想看过程可以直接复制以下 eslint.config.js

import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import reactPlugin from "eslint-plugin-react";
import { defineConfig } from "eslint/config";export default defineConfig([// 1. 忽略构建目录{ignores: ["dist", "node_modules", "coverage"],},// 2. 自动检测 React 版本(消除警告){settings: {react: {version: "detect",},},},// 3. ESLint 官方 JS 推荐规则js.configs.recommended,// 4. TypeScript ESLint 推荐规则...tseslint.configs.recommended,// 5. 手动配置 React 规则(关键!不使用预设){files: ["**/*.{js,jsx,ts,tsx}"],plugins: {react: reactPlugin,},languageOptions: {globals: globals.browser,parserOptions: {ecmaFeatures: {jsx: true,},},},rules: {// React 17+ 不再需要导入 React"react/react-in-jsx-scope": "off","react/jsx-uses-react": "off",// 安全规则:强制 target="_blank" 必须带 rel"react/jsx-no-target-blank": "error",// 确保 JSX 中使用的变量不会被误报未使用"react/jsx-uses-vars": "error",// 关闭有兼容性问题的规则(若希望启用可尝试升级插件)"react/display-name": "off",// 可选:关闭不常用的规则"react/prop-types": "off",},},
]);

运行 pnpm run lint 即可看到代码规范检查正常执行,无报错,无 React 导入错误。

三、一路踩过的坑 & 为什么这样写

下面按我实际遇到的错误顺序,解释各个坑的成因及解决思路。

坑1:'React' must be in scope

表现:使用 JSX 时要求显式导入 React,即使项目使用 React 17+ 新 JSX 转换。

错误原因eslint-plugin-react 默认开启了 react/react-in-jsx-scope 规则,要求每个 JSX 文件顶部都要 import React from 'react'。虽然可以关闭该规则,但在扁平配置中规则覆盖顺序很容易出错。

解决方案:在配置对象的 rules 中显式关闭,并确保该对象位于数组最后(或至少在其他可能开启该规则的配置之后)。上面最终配置中,所有 React 规则都在一个独立对象内,且放在 js.configs.recommendedtseslint.configs.recommended 之后。

坑2:Plugin config "jsx-runtime" ... cannot be used in this context

表现:使用 extends: ["js/recommended", "react/jsx-runtime"] 时报错。

错误原因:字符串 "react/jsx-runtime" 是传统 .eslintrc 格式的预设引用,无法直接用于扁平配置。虽然 defineConfig 支持部分 extends 语法,但 "plugin:react/jsx-runtime" 这种带 plugin: 前缀的写法在扁平配置中需要额外配置 plugins 映射,且容易出错。

解决方案:完全摒弃 extends 字符串,改用手动规则配置。直接写 "react/react-in-jsx-scope": "off" 更直接可靠。

坑3:TypeError: contextOrFilename.getFilename is not a function

表现:使用了 pluginReact.configs.flat.recommended 预设后,ESLint 在检查文件时崩溃。

错误原因eslint-plugin-react 的某些规则(如 react/display-name)内部调用了 context.getFilename(),但在 ESLint 10 的扁平配置中,context 对象结构发生了变化,导致该函数未定义。这是插件与 ESLint 10 的兼容性问题,目前(插件 v7.37.5)仍未完全修复。

解决方案放弃使用 pluginReact.configs.flat.recommended 预设,手动注册插件并只启用实际需要的规则。这样绕开了有问题的 react/display-name 规则(将其设为 off)。如果你确实需要该规则,可尝试降级 ESLint 到 8.x,但长远来看建议等待插件更新。

坑4:Warning: React version not specified

表现:控制台输出警告,提示未指定 React 版本。

错误原因eslint-plugin-react 需要知道项目使用的 React 版本,以便正确应用某些规则。

解决方案:在配置中添加 settings.react.version: "detect",插件会自动读取 package.json 中的 React 版本。

坑5:Plugin "plugin:react" not found

表现:写了 extends: ["plugin:react/recommended"] 后报错。

错误原因:扁平配置中使用 plugin: 前缀的字符串时,必须同时提供 plugins 映射(如 plugins: { react: pluginReact }),且字符串前缀 plugin: 不能去除。但即使映射正确,仍可能因其他原因失败。

解决方案:既然我们放弃了 extends 字符串,这个坑自然就不存在了。

四、核心配置要点总结

经过反复试验,下面几点是 ESLint 9 + React + TypeScript 稳定配置的必要条件

  1. 不要使用 pluginReact.configs.flat.recommended 预设(至少目前版本有兼容问题)。
  2. 不要使用 extends 字符串(如 "plugin:react/recommended""react/jsx-runtime")。
  3. 手动注册 React 插件plugins: { react: reactPlugin }
  4. 手动关闭 react/react-in-jsx-scope
  5. 通过 settings.react.version 指定版本(推荐 "detect")。
  6. 自定义规则对象放在数组末尾,以确保覆盖任何先前可能开启的规则。
  7. 使用 defineConfig 辅助函数(从 eslint/config 导入)可以获得更好的类型提示和 extends 支持,但即使不使用它,直接导出数组也是有效的。

五、拓展:集成 Prettier 和 Git 钩子

如果你还需要代码格式化工具和提交前自动检查,可以继续添加:

pnpm add -D prettier eslint-config-prettier husky lint-staged

然后在 eslint.config.js 最后加入:

import prettierConfig from "eslint-config-prettier";
export default defineConfig([// ... 之前的配置prettierConfig, // 关闭所有与 Prettier 冲突的规则
]);

配置 lint-staged

// package.json
{"lint-staged": {"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"]}
}

初始化 Husky:

npx husky init
echo "npx lint-staged" > .husky/pre-commit

六、结语

ESLint 9 的扁平配置带来了更强大的灵活性,但也让插件兼容性和配置写法变得更复杂。如果你正从旧版迁移或新建项目,希望本文能帮你少走弯路。

最终,一个稳定可用的 ESLint 配置不一定需要复杂的 extends 链或官方预设。手动注册插件 + 按需开启规则 反而更清晰、更可控。

如果你在配置中遇到了其他奇怪的问题,欢迎留言交流。也建议关注 eslint-plugin-react 的后续版本,或许未来 flat.recommended 预设会完全修复这些兼容问题,届时我们再更新配置方案。


本文档基于 ESLint 10.4.0、eslint-plugin-react 7.37.5、typescript-eslint 8.59.2 环境验证。

http://www.jsqmd.com/news/874673/

相关文章:

  • 2026年杭州网店客服外包TOP5服务商客观实测排行:杭州视频号客服外包、杭州靠谱的客服外包团队、杭州京东客服外包选择指南 - 优质品牌商家
  • 市面上有哪些真正可以轻松降低AI生成疑似率,好用性价比高的降AIGC软件
  • ops-nn 仓库概览:神经网络基础算子的“地基工程“
  • Rust内存管理模式:从所有权到智能指针的完整指南
  • 模块化AI:从大脑启示到工程实践,构建高效智能系统的核心范式
  • 诺和新元在华两大重点项目在天津和太仓竣工启用 | 美通社头条
  • 告别“盲人摸象”:用Sentinel-1数据+SBAS-InSAR,5步搞定城市地面沉降监测(附Python代码片段)
  • 2026年质量好的家装设计装饰装修优选公司推荐 - 行业平台推荐
  • 手把手教你学Simulink——交流微电网中双向DC-AC变换器的多模式切换仿真
  • 2026金属楼梯定制优质厂家推荐榜:旋转楼梯定制、旋转楼梯源头工厂、耐高温不锈钢板批发、钢板旋转楼梯、304不锈钢板批发选择指南 - 优质品牌商家
  • 云服务器Nginx静态网站首屏慢的四层根因与优化方案
  • 保姆级教程:在Ubuntu 20.04上从源码编译安装SUMO 1.19.0(含环境变量配置避坑指南)
  • 2026年广东地区重点建设项目防水母线槽供应商深度解析 - 2026年企业推荐榜
  • 遥感因果分析:多尺度表征拼接技术解析与工程实践
  • VLM情境感知实验:90%功能描述漂移揭示智能体功能优先视觉架构
  • 2026年4月本地钢制家具厂家推荐,铁艺公寓床/宿舍公寓床/高低床/单人床/图书馆钢制家具,钢制家具源头工厂哪家好 - 品牌推荐师
  • 分离轴算法(SAT)的前置步骤:手把手教你用Python实现凹多边形切割
  • 线性化多噪声训练:提升混沌系统长期预测稳定性的正则化技术
  • JWT签名机制与常见攻击实战:从PortSwigger靶场12关学透算法混淆、密钥混淆与JWKS劫持
  • Rust异步编程实战:构建高性能并发应用
  • 边缘计算与多车协同如何提升自动驾驶目标检测
  • Ubuntu 22.04双网卡配置踩坑记:netplan apply报错‘默认路由冲突’的三种解法
  • 2026四川导轨油代理商品牌推荐榜:壳牌润滑油代理商推荐、导轨油代理商推荐、昆仑润滑油代理商推荐、福斯润滑油代理商推荐选择指南 - 优质品牌商家
  • Keil µVision项目文件路径批量修改实战指南
  • NVIDIA Geforce RTX 5060 Ti显卡能本地部署的哪些AI应用?
  • 玛氏北京怀柔巧克力工厂迎来在华发展三十周年里程碑
  • 别再只懂ls -l了!手把手教你用getfattr/setfattr玩转Linux文件隐藏属性
  • AI企业参与国防采购的挑战、机遇与实操路线图
  • 从原理到实战:深入理解ArUco码如何算出相机在三维空间中的位置和朝向(Python/OpenCV)
  • 如何用Nvidia Geforce RTX 5060 Ti显卡进行本地Whisper语音转文字任务?