You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Monorepo环境pre-commit执行typescript-eslint校验报parserOptions.project错误

问题背景

我们近期完成了monorepo架构迁移,目前仍在完善配套配置,技术栈采用TypeScript + ESLint + Prettier。

项目目录结构

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

- 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": {}
}

问题现象

以下场景执行均无异常:

  1. 使用webpack配合ts-loader、eslint-webpack-plugin基于project_a/tsconfig.json打包project_a项目,无任何lint报错
  2. VSCode的vscode-eslint插件无异常提示
  3. 在project_a目录下执行 ../node_modules/.bin/eslint . --ext .ts,.tsx --fix -c .eslintrc.json 正常通过,无lint错误

但修改project_a内的文件后执行git暂存提交时,pre-commit钩子抛出如下错误:

/home/web/project_a/components/component_a/Component.tsx
0:0 error Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser. The file does not match your project config: project_a/components/component_a/Component.tsx.
The file must be included in at least one of the projects provided

问题根因

pre-commit钩子默认在仓库根目录执行,而project_a/.eslintrc.json中parserOptions.project配置的是相对路径./tsconfig.json,从根目录执行时,该路径会被解析为根目录下的tsconfig.base.json,而tsconfig.base.json的include仅覆盖了common目录的文件,project_a下的文件不在其包含范围内,因此触发报错。

解决方案

可选方案如下,推荐组合使用方案1+方案2保证稳定性:

方案1:指定pre-commit钩子的执行目录

修改.pre-commit-config.yaml,给对应钩子添加working_directory参数指定执行目录为project_a,同时调整entry的路径适配:

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

方案2:固定tsconfig的解析基准路径

将project_a/.eslintrc.json改为.eslintrc.js,添加tsconfigRootDir配置,保证无论从哪个目录执行eslint,都能正确找到对应tsconfig:

module.exports = {
    // 原有配置不变
    "parserOptions": {
        "project": "./tsconfig.json",
        "tsconfigRootDir": __dirname, // 新增这一行
        "ecmaFeatures": {
            "jsx": true
        }
    },
    // 原有配置不变
}

方案3:显式指定tsconfig路径

也可以直接在pre-commit的entry中指定tsconfig的相对根目录的路径:

entry: node_modules/.bin/eslint --report-unused-disable-directives --fix -c project_a/.eslintrc.json --parser-options project:./project_a/tsconfig.json --ext .ts,.tsx

内容的提问来源于stack exchange,提问作者XeniaSis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:06:02