构建React应用程序时,ESLint结果不同。

8

我是React开发的初学者。

我试图解决项目中出现的所有错误/警告,但在开发环境和生产环境之间得到了不同的结果。我没有在配置中进行任何区别处理。

运行npm run lint给我这个输出:

npm run lint

运行npm run build给我这个输出:

npm run build

我得到不同的ESLint输出是否正常?

以下是我的package.json:

{
  "name": "immersion-dashboard",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@reduxjs/toolkit": "^1.5.1",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "@types/jest": "^24.0.0",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "@types/react-redux": "^7.1.7",
    "bootstrap": "^5.1.3",
    "react": "^17.0.2",
    "react-bootstrap": "^2.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.0",
    "react-scripts": "4.0.3",
    "typescript": "~4.1.5"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "cross-env": "^7.0.3",
    "eslint": "^7.32.0",
    "eslint-config-airbnb": "^19.0.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-import-resolver-typescript": "^2.5.0",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jest": "^25.2.4",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.27.0",
    "eslint-plugin-react-hooks": "^4.3.0",
    "husky": "^7.0.4",
    "lint-staged": "^12.0.2",
    "prettier": "^2.4.1"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "test:staged": "cross-env CI=true react-scripts test --env=jsdom --passWithNoTests",
    "eject": "react-scripts eject",
    "typescript": "tsc --project tsconfig.json --noEmit",
    "prettier": "prettier . --write",
    "lint": "eslint . --ext .ts --ext .tsx --fix",
    "lint-staged": "lint-staged"
  },
  "lint-staged": {
    "*.{ts,tsx,json,css}": "prettier --write",
    "*.{ts,tsx}": [
      "eslint --fix",
      "npm run test:staged"
    ]
  }
}

以及我的.eslintrc.json文件:

{
  "env": {
    "browser": true,
    "es2021": true,
    "jest/globals": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "airbnb",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint", "jest"],
  "rules": {
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "ts": "never",
        "tsx": "never"
      }
    ],
    "react/jsx-filename-extension": [
      "warn",
      {
        "extensions": [".tsx"]
      }
    ],
    "no-use-before-define": "off",
    "@typescript-eslint/no-use-before-define": ["error"],
    "no-param-reassign": [
      "error",
      {
        "props": false
      }
    ],
    "no-console": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "^_",
        "varsIgnorePattern": "^_"
      }
    ]
  },
  "settings": {
    "import/resolver": {
      "typescript": {}
    }
  }
}
1个回答

18

很抱歉,您正在同时运行两个具有不同配置的ESLint实例,让我解释一下原因。

Create React App ESLint

CRA已经为您设置了ESLint(以及其他内容):

在底层,我们使用webpack、Babel、ESLint和其他令人惊叹的项目来支持您的应用程序。

在CRA中,当您运行startbuild命令时,会在内部安装并运行ESLint,因此您可以在开发应用程序或构建最终包时在控制台中看到输出。您还可以在编辑器中获取lint输出。 CRA已经包含了ESLint的默认配置,包括几个插件。

您的项目ESLint

您已经单独在项目中安装了ESLint,并在自己的.eslintrc.json中进行了设置。这是完全可以的!这是对项目进行lint的常规方式。运行此ESLint的方法是通过您添加到脚本中的lint命令。


当你运行startbuild时,使用的是CRA的ESLint实例和配置来lint你的项目,但当你运行lint时,使用的是你自己的ESLint实例和配置来lint你的项目。它们的配置不完全相同,因此会报告不同的错误。
你可以通过运行npm ls eslint来检查你是否安装了两个ESLint实例,你会看到类似于这样的内容: npm dependencies tree displaying ESLint installed for both the project and CRA
在那里,你可以看到一个直接依赖eslint(你手动安装的那个),以及另一个eslint,它属于react-scripts(由CRA作为子依赖项安装)。
如何解决呢?
基本上有两个选项:
  1. 移除ESLint并自定义CRA的ESLint。您可以从项目中卸载eslint依赖项,删除自定义的.eslintrc.json文件,并扩展CRA ESLint配置。这必须通过package.json中的eslintConfig键完成。您不需要在那里放置您在.eslintrc.json中拥有的所有内容,因为大部分已经由CRA配置覆盖了。这种选项的缺点是:1)您无法使用npm run lint按需检查代码,因为CRA不允许您这样做;2)您受限于CRA使用的ESLint插件版本(例如,它们正在使用eslint-plugin-testing-library v3,但最新版本是v5,您不能使用它)。
  2. 忽略CRA的ESLint(推荐)。这是我通常做的事情。您可以选择退出CRA内置的ESLint实例。要做到这一点,您需要在项目根目录下创建一个.env文件,然后在其中输入DISABLE_ESLINT_PLUGIN=true。之后,当运行startbuild时,CRA将不会检查您的代码,所以您需要使用lint命令来检查它。理想情况下,您会在CI中运行lint命令,并在每次提交文件时本地运行lint-staged(如果这听起来对您不熟悉,请告诉我是否需要帮助设置任何这些内容),此外通过您的代码编辑器获得即时反馈ESLint错误(应该非常简单,只需设置VSCode或WebStorm即可)。

希望这可以帮助您,如果您还有其他问题要讨论,请告诉我!


1
谢谢您提供完整的答案!我已经使用 husky 设置了 lint-staged 以进行 pre-commit,所以现在我准备开始开发了,再次感谢您的帮助! - Tom Combet
1
我很高兴它有帮助! - Mario Beltrán
对于已弹出的 CRA 项目,我是否可以只删除 webpack.config.js 中的 ESLintPlugin?我认为这将要求在运行 start/build 命令之前手动运行 linting。 - JoeTidee
@JoeTidee 没错,虽然这与使用 DISABLE_ESLINT_PLUGIN 环境变量相同。 - Mario Beltrán

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接