typescript-eslint/pre-commit hook (monorepo): Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser
typescript-eslint/pre-commit hook (monorepo): Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser
我们最近迁移到了 monorepo,我们仍在尝试设置所有内容。我们使用带有 prettier 的 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_a
与 webpack
捆绑在一起,使用 ts-loader
、eslint-webpack-plugin
和 project_a/tsconfig.json
效果非常好。没有报告 linting 错误。与 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 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
这对我来说毫无意义,为什么这个错误只会在那个特定的用例中抛出,当通过预提交挂钩进行 linting 时。此外,它非常奇特,因为 project_a/tsconfig.json
include
是该文件夹中的所有文件(node_modules
和 build
工件除外)。
"include": ["**/*"]
我觉得可能跟我们添加了
有关
"include": ["common/**/*"]
在 ./tsconfig.json
。这是添加的(根据评论),因为在 VSCode 中打开 common
中的文件并尝试保存一些更改,会使 eslint 崩溃,因为根据各种来源,@typescript-eslint/parser
将包括内存中的所有文件以收集 linting 的类型信息。
所有相关的 Github 问题只是提到,根据错误 itslef,有问题的文件只是不包括在内,但我不明白这是怎么发生在我的场景中的。
您的配置:
- 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
,这是一个 managed 环境(pre-commit
将创建自己独立的独立节点环境并使用它——并且不会有访问您的依赖项)
你可能想要 language: system
因为你正在管理预提交的外部环境
免责声明:我创建了预提交
事实证明,@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
}
}
我们最近迁移到了 monorepo,我们仍在尝试设置所有内容。我们使用带有 prettier 的 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_a
与 webpack
捆绑在一起,使用 ts-loader
、eslint-webpack-plugin
和 project_a/tsconfig.json
效果非常好。没有报告 linting 错误。与 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 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
这对我来说毫无意义,为什么这个错误只会在那个特定的用例中抛出,当通过预提交挂钩进行 linting 时。此外,它非常奇特,因为 project_a/tsconfig.json
include
是该文件夹中的所有文件(node_modules
和 build
工件除外)。
"include": ["**/*"]
我觉得可能跟我们添加了
有关"include": ["common/**/*"]
在 ./tsconfig.json
。这是添加的(根据评论),因为在 VSCode 中打开 common
中的文件并尝试保存一些更改,会使 eslint 崩溃,因为根据各种来源,@typescript-eslint/parser
将包括内存中的所有文件以收集 linting 的类型信息。
所有相关的 Github 问题只是提到,根据错误 itslef,有问题的文件只是不包括在内,但我不明白这是怎么发生在我的场景中的。
您的配置:
- 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
,这是一个 managed 环境(pre-commit
将创建自己独立的独立节点环境并使用它——并且不会有访问您的依赖项)
你可能想要 language: system
因为你正在管理预提交的外部环境
免责声明:我创建了预提交
事实证明,@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 } }