【问题标题】:typescript-eslint/pre-commit hook (monorepo): Parsing error: "parserOptions.project" has been set for @typescript-eslint/parsertypescript-eslint/pre-commit hook (monorepo):解析错误:“parserOptions.project”已为@typescript-eslint/parser 设置
【发布时间】:2021-11-01 20:44:37
【问题描述】:

我们最近迁移到 monorepo,我们仍在尝试设置所有内容。我们使用更漂亮的 typescript 和 eslint。结构如下:

root
  - common
    - folder_a
      - file_a.ts
  - build_scripts
    - script_a.js
  - project_a
    - components
      - component_a
        - Component.tsx
    - tsconfig.json
    - .eslintrc.json
    - node_modules
    - package.json
  - .prettierignore
  - .prettierrc.yml
  - .eslintignore
  - .eslintrc.base.json
  - tsconfig.base.json
  - node_modules
  - package.json
  - Makefile
  - webpack.config.js
  - .pre-commit-config.yaml

common 文件夹包含跨多个项目使用且不被视为其自身项目的代码(不是 tsconfig.json)。所有包含自己的 tsconfig.json 和 .eslintrc.json 文件的子项目都在扩展基础文件,如下所示:

tsconfig.base.json

{
    "compilerOptions": {
        "lib": ["ES2017", "DOM"],
        "target": "ES6",
        "module": "commonjs",
        "baseUrl": ".",
        "sourceMap": true,
        "alwaysStrict": true,
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "noEmitOnError": true,
        "paths": {
            "@common/*": ["./common/*"]
        }
    },
    // include all projects that don't have their own
    // tsconfig.json file AND need to be compiled/linted
    // => very important because typescript-eslint will
    // otherwise load ALL files in memory for type-checking
    // and consequently eslint will crash with an OOM error
    "include": ["common/**/*"]
}

.eslintrc.base.json(为简洁省略规则)

{
    "env": {
        "es2020": true,
        "node": true
    },
    "extends": [
        "plugin:destructuring/recommended",
        "airbnb-base",
        "prettier",
        "plugin:prettier/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "./tsconfig.base.json",
        "ecmaVersion": 11,
        "sourceType": "module"
    },
    "plugins": [
        "prettier",
        "@typescript-eslint",
        "destructuring"
    ],
    "rules": {}
}

.eslintignore

*/**/build
Makefile
**/*.js
**/*.json

.pre-commit-config.yaml(取自https://github.com/pre-commit/pre-commit/issues/466#issuecomment-274282684中的示例)

- repo: local
  hooks:
    - id: lint_fix
      name: lint_fix_project_a
      entry: node_modules/.bin/eslint --report-unused-disable-directives --fix -c project_a/.eslintrc.json --ext .ts,.tsx
      files: ^project_a/
      types: [file]
      language: node

package.json

{
  "name": "web",
  "version": "1.0.0",
  "private": true,
  "dependencies": {},
  "devDependencies": {
    "@babel/core": "7.2.2",,
    "@typescript-eslint/eslint-plugin": "4.15.1",
    "@typescript-eslint/parser": "4.15.1",
    "eslint": "7.20.0",
    "eslint-config-airbnb": "18.2.1",
    "eslint-config-airbnb-base": "14.2.0",
    "eslint-config-prettier": "6.10.1",
    "eslint-config-standard": "14.1.1",
    "eslint-import-resolver-typescript": "2.0.0",
    "eslint-plugin-destructuring": "2.2.0",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-node": "11.1.0",
    "eslint-plugin-prettier": "3.1.3",
    "eslint-plugin-promise": "4.2.1",
    "eslint-plugin-standard": "4.0.1",
    "eslint-webpack-plugin": "2.5.4",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-react": "7.22.0",
    "eslint-plugin-react-hooks": "4.2.0",
    "express": "4.0.0",
    "prettier": "2.1.2",
    "typescript": "3.9.7"
  }
}

project_a/tsconfig.json

{
  "extends": "../tsconfig.base.json",
  "compilerOptions": {
    "lib": ["ES2017", "DOM", "DOM.Iterable"],
    "jsx": "react",
    "baseUrl": ".",
    "paths": {
      "@common/*": ["../common/*"],
      "@components/*": ["./components/*"]
    }
  },
  // overwrite the base "includes"
  "include": ["**/*"],
  "exclude": [
    "**/node_modules/*",
    "**/build/*"
  ]
}

project_a/.eslintrc.json(为简洁省略规则)

{
    "extends": [
        "plugin:react/recommended",
        "plugin:destructuring/recommended",
        "airbnb",
        "airbnb/hooks",
        "prettier",
        "plugin:prettier/recommended",
        "prettier/react",
        "../.eslintrc.base.json"
    ],
    "env": {
        "browser": true,
        "commonjs": true,
        "node": false
    },
    "parserOptions": {
        "project": "./tsconfig.json",
        "ecmaFeatures": {
            "jsx": true
        }
    },
    "plugins": [
        "prettier",
        "react",
        "@typescript-eslint",
        "destructuring"
    ],
    "rules": {}
}

project_awebpack 捆绑在一起,使用ts-loadereslint-webpack-pluginproject_a/tsconfig.json 效果很好。没有报告掉毛错误。 VSCode 也一样,vscode-eslint 扩展不报告任何内容。

project_a 内运行以下代码也是成功的,没有任何 linting 错误。

../node_modules/.bin/eslint 。 --ext .ts,.tsx --fix -c .eslintrc.json

然而,当更改project_a 中的文件并尝试暂存和提交时,会抛出以下错误:

/home/web/project_a/components/component_a/Component.tsx

0:0 错误解析错误:“parserOptions.project”已设置为 @typescript-eslint/解析器。该文件与您的项目不匹配 配置:project_a/components/component_a/Component.tsx。

该文件必须包含在至少一个提供的项目中

这对我来说毫无意义,为什么只有在通过预提交挂钩进行 linting 时才会在特定用例中引发此错误。此外,它非常奇特,因为 project_a/tsconfig.json includes 该文件夹中的所有文件(node_modulesbuild 工件除外)。

"include": ["**/*"]

在我看来这可能与我们添加了有关

"include": ["common/**/*"]

./tsconfig.json。这是添加的(根据评论),因为在 VSCode 中打开来自 common 的文件并尝试保存一些更改会导致 eslint 崩溃,因为根据各种来源,@typescript-eslint/parser 将包含内存中的所有文件为 linting 收集类型信息。

所有相关的 Github 问题都只是提到不包括有问题的文件,根据错误本身,但我看不出在我的场景中这是如何发生的。

【问题讨论】:

    标签: typescript eslint pre-commit-hook typescript-eslint pre-commit.com


    【解决方案1】:

    事实证明,@typescript-eslint/parser 将提供的 tsconfig.json 解析为相对于当前工作目录,我在阅读文档时错过了该目录。因此,由于预提交钩子总是从根目录运行,它使用tsconfig.base.json 而不是project_a 中的那个。

    为了解决这个问题,需要采取以下步骤(根据https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-567365174):

    • project_a/.eslintrc.json 重命名为project_a/.eslintrc.js
    • 添加parserOptions.tsconfigRootDir,如下所示:
    • module.exports = {
        parserOptions: {
          project: './tsconfig.json'
          tsconfigRootDir: __dirname // important option
        }
      }
      

    【讨论】:

      【解决方案2】:

      您的配置:

      - repo: local
        hooks:
          - id: lint_fix
            name: lint_fix_project_a
            entry: node_modules/.bin/eslint --report-unused-disable-directives --fix -c project_a/.eslintrc.json --ext .ts,.tsx
            files: ^project_a/
            types: [file]
            language: node
      

      使用language: node,这是一个托管环境(pre-commit 将创建自己的独立节点环境并使用它——并且无法访问您的依赖项)

      您可能想要language: system,因为您正在管理预提交外部的环境


      免责声明:我创建了预提交

      【讨论】:

      • 感谢您的快速回复。不幸的是,同样的错误仍然发生
      • 钩子也将从存储库的根目录运行,因此等效的 entry 应该从那里成功
      • 我不确定我理解你对so the equivalent entry should succeed from there的意思
      • cd 到存储库的根目录并运行entry,其后至少有一个文件名,这相当于这里发生的事情(独立于pre-commit)——迭代直到它成功
      • 我现在遇到同样的错误,感谢您的解释。但它仍然不能解释从根目录和项目文件夹运行时 lint 结果的不一致
      猜你喜欢
      • 2020-11-10
      • 2020-02-18
      • 2021-01-24
      • 2022-11-19
      • 2020-12-31
      • 2021-06-13
      • 2020-11-30
      • 2021-07-27
      • 2021-08-24
      相关资源
      最近更新 更多