为什么 eslint 考虑 JSX 或一些 react @types 未定义,因为升级 typescript-eslint/parser 到版本 4.0.0
Why eslint consider JSX or some react @types undefined, since upgrade typescript-eslint/parser to version 4.0.0
上下文是使用 ReactJs 构建的相当大的项目,基于 eslint 规则,使用此 eslint 配置
const DONT_WARN_CI = process.env.NODE_ENV === 'production' ? 0 : 1
module.exports = {
extends: [
'eslint:recommended',
'plugin:jsx-a11y/recommended',
'plugin:react/recommended',
'prettier',
'prettier/@typescript-eslint'
],
plugins: [
'react',
'html',
'json',
'prettier',
'import',
'jsx-a11y',
'jest',
'@typescript-eslint',
'cypress'
],
settings: {
'html/indent': '0',
es6: true,
react: {
version: '16.5'
},
propWrapperFunctions: ['forbidExtraProps'],
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx']
},
alias: {
extensions: ['.js', '.jsx', '.json']
}
}
},
env: {
browser: true,
node: true,
es6: true,
jest: true,
'cypress/globals': true
},
globals: {
React: true,
google: true,
mount: true,
mountWithRouter: true,
shallow: true,
shallowWithRouter: true,
context: true,
expect: true,
jsdom: true
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'es2020',
ecmaFeatures: {
globalReturn: true,
jsx: true
},
lib: ['ES2020']
},
rules: {
'arrow-parens': ['error', 'as-needed'],
'comma-dangle': ['error', 'never'],
eqeqeq: ['error', 'smart'],
'import/first': 0,
'import/named': 'error',
'import/no-deprecated': process.env.NODE_ENV === 'production' ? 0 : 1,
'import/no-unresolved': ['error', { commonjs: true }],
'jsx-a11y/alt-text': DONT_WARN_CI,
'jsx-a11y/anchor-has-content': DONT_WARN_CI,
'jsx-a11y/anchor-is-valid': DONT_WARN_CI,
'jsx-a11y/click-events-have-key-events': DONT_WARN_CI,
'jsx-a11y/heading-has-content': DONT_WARN_CI,
'jsx-a11y/iframe-has-title': DONT_WARN_CI,
'jsx-a11y/label-has-associated-control': [
'error',
{
controlComponents: ['select']
}
],
'jsx-a11y/label-has-for': [
'error',
{
required: {
some: ['nesting', 'id']
}
}
],
'jsx-a11y/media-has-caption': DONT_WARN_CI,
'jsx-a11y/mouse-events-have-key-events': DONT_WARN_CI,
'jsx-a11y/no-autofocus': DONT_WARN_CI,
'jsx-a11y/no-onchange': 0,
'jsx-a11y/no-noninteractive-element-interactions': DONT_WARN_CI,
'jsx-a11y/no-static-element-interactions': DONT_WARN_CI,
'jsx-a11y/no-noninteractive-tabindex': DONT_WARN_CI,
'jsx-a11y/tabindex-no-positive': DONT_WARN_CI,
'no-console': 'warn',
'no-debugger': 'warn',
'no-mixed-operators': 0,
'no-redeclare': 'off',
'no-restricted-globals': [
'error',
'addEventListener',
'blur',
'close',
'closed',
'confirm',
'defaultStatus',
'defaultstatus',
'event',
'external',
'find',
'focus',
'frameElement',
'frames',
'history',
'innerHeight',
'innerWidth',
'length',
'localStorage',
'location',
'locationbar',
'menubar',
'moveBy',
'moveTo',
'name',
'onblur',
'onerror',
'onfocus',
'onload',
'onresize',
'onunload',
'open',
'opener',
'opera',
'outerHeight',
'outerWidth',
'pageXOffset',
'pageYOffset',
'parent',
'print',
'removeEventListener',
'resizeBy',
'resizeTo',
'screen',
'screenLeft',
'screenTop',
'screenX',
'screenY',
'scroll',
'scrollbars',
'scrollBy',
'scrollTo',
'scrollX',
'scrollY',
'self',
'status',
'statusbar',
'stop',
'toolbar',
'top'
],
'no-restricted-modules': ['error', 'chai'],
'no-unused-vars': [
'error',
{
varsIgnorePattern: '^_',
argsIgnorePattern: '^_'
}
],
'no-var': 'error',
'one-var': ['error', { initialized: 'never' }],
'prefer-const': [
'error',
{
destructuring: 'any'
}
],
'prettier/prettier': 'error',
'react/jsx-curly-brace-presence': [
'error',
{ children: 'ignore', props: 'never' }
],
'react/jsx-no-bind': [
'error',
{
allowArrowFunctions: true
}
],
'react/jsx-no-literals': 1,
'react/jsx-no-target-blank': DONT_WARN_CI,
'react/jsx-no-undef': ['error', { allowGlobals: true }],
'react/no-deprecated': DONT_WARN_CI,
'react/prop-types': 0,
'require-await': 'error',
'space-before-function-paren': 0
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-unused-vars': 'off',
'import/no-unresolved': 'off'
}
}
]
}
自从 "@typescript-eslint/parser": "^4.0.0"
从 "@typescript-eslint/parser": "^3.10.1"
升级库后,以下命令...
eslint --fix --ext .js,.jsx,.json,.ts,.tsx . && stylelint --fix '**/*.scss'
... 带来以下错误
9:45 error 'ScrollBehavior' is not defined no-undef
224:12 error 'KeyboardEventInit' is not defined no-undef
53:5 error 'JSX' is not defined no-undef
我知道我可以将它们添加到道具 globals
以及键 JSX: true
或 KeyboardEventInit: true
中,但这不是我想要的方式。
对这里发生的事情有什么想法吗?配置错误在哪里?
非常感谢
官方答案在这里
https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors 它说确实要将它们添加到 globals
或禁用 [=12=] 规则因为打字稿已经有自己的检查
编辑
这是复制的官方文档
## I get errors from the `no-undef` rule about global variables not being defined, even though there are no TypeScript errors
The `no-undef` lint rule does not use TypeScript to determine the global variables that exist - instead, it relies upon ESLint's configuration.
We strongly recommend that you do not use the `no-undef` lint rule on TypeScript projects.
The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.
As of our v4.0.0 release, this also applies to types.
If you use global types from a 3rd party package (i.e. anything from an `@types` package), then you will have to configure ESLint appropriately to define these global types.
For example; the `JSX` namespace from `@types/react` is a global 3rd party type that you must define in your ESLint config.
Note, that for a mixed project including JavaScript and TypeScript, the `no-undef` rule (like any role) can be turned off for TypeScript files alone by adding an `overrides` section to .eslintrc.json:
json
"overrides": [
{
"files": ["*.ts"],
"rules": {
"no-undef": "off"
}
}
]
If you choose to leave on the ESLint `no-undef` lint rule, you can [manually define the set of allowed `globals` in your ESLint config](https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals), and/or you can use one of the [pre-defined environment (`env`) configurations](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments).
我在打字稿中尝试声明 JSX.Element
类型的变量时遇到了同样的问题。我在 .eslintrc.json
中将 "JSX":"readonly"
添加到 globals
,问题就消失了。在你的情况下它将是:
globals: {
React: true,
google: true,
mount: true,
mountWithRouter: true,
shallow: true,
shallowWithRouter: true,
context: true,
expect: true,
jsdom: true,
JSX: true,
},
从下面的link,我了解到您实际上在JSX
之后使用了几个选项。您可以使用 true
、false
、writable
或 readonly
(但不能使用 off
)。
来自typescript-eslint troubleshooting guide:
We strongly recommend that you do not use the no-undef lint rule on TypeScript projects. The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.
在您的 .eslintrc.js
中,使用 overrides
:
为 TypeScript 文件关闭规则
module.exports = {
root: true,
extends: '@react-native-community',
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'no-shadow': 'off',
'@typescript-eslint/no-shadow': ['error'],
},
overrides: [
{
files: ['*.ts', '*.tsx'],
rules: {
'no-undef': 'off',
},
},
],
};
上下文是使用 ReactJs 构建的相当大的项目,基于 eslint 规则,使用此 eslint 配置
const DONT_WARN_CI = process.env.NODE_ENV === 'production' ? 0 : 1
module.exports = {
extends: [
'eslint:recommended',
'plugin:jsx-a11y/recommended',
'plugin:react/recommended',
'prettier',
'prettier/@typescript-eslint'
],
plugins: [
'react',
'html',
'json',
'prettier',
'import',
'jsx-a11y',
'jest',
'@typescript-eslint',
'cypress'
],
settings: {
'html/indent': '0',
es6: true,
react: {
version: '16.5'
},
propWrapperFunctions: ['forbidExtraProps'],
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx']
},
alias: {
extensions: ['.js', '.jsx', '.json']
}
}
},
env: {
browser: true,
node: true,
es6: true,
jest: true,
'cypress/globals': true
},
globals: {
React: true,
google: true,
mount: true,
mountWithRouter: true,
shallow: true,
shallowWithRouter: true,
context: true,
expect: true,
jsdom: true
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'es2020',
ecmaFeatures: {
globalReturn: true,
jsx: true
},
lib: ['ES2020']
},
rules: {
'arrow-parens': ['error', 'as-needed'],
'comma-dangle': ['error', 'never'],
eqeqeq: ['error', 'smart'],
'import/first': 0,
'import/named': 'error',
'import/no-deprecated': process.env.NODE_ENV === 'production' ? 0 : 1,
'import/no-unresolved': ['error', { commonjs: true }],
'jsx-a11y/alt-text': DONT_WARN_CI,
'jsx-a11y/anchor-has-content': DONT_WARN_CI,
'jsx-a11y/anchor-is-valid': DONT_WARN_CI,
'jsx-a11y/click-events-have-key-events': DONT_WARN_CI,
'jsx-a11y/heading-has-content': DONT_WARN_CI,
'jsx-a11y/iframe-has-title': DONT_WARN_CI,
'jsx-a11y/label-has-associated-control': [
'error',
{
controlComponents: ['select']
}
],
'jsx-a11y/label-has-for': [
'error',
{
required: {
some: ['nesting', 'id']
}
}
],
'jsx-a11y/media-has-caption': DONT_WARN_CI,
'jsx-a11y/mouse-events-have-key-events': DONT_WARN_CI,
'jsx-a11y/no-autofocus': DONT_WARN_CI,
'jsx-a11y/no-onchange': 0,
'jsx-a11y/no-noninteractive-element-interactions': DONT_WARN_CI,
'jsx-a11y/no-static-element-interactions': DONT_WARN_CI,
'jsx-a11y/no-noninteractive-tabindex': DONT_WARN_CI,
'jsx-a11y/tabindex-no-positive': DONT_WARN_CI,
'no-console': 'warn',
'no-debugger': 'warn',
'no-mixed-operators': 0,
'no-redeclare': 'off',
'no-restricted-globals': [
'error',
'addEventListener',
'blur',
'close',
'closed',
'confirm',
'defaultStatus',
'defaultstatus',
'event',
'external',
'find',
'focus',
'frameElement',
'frames',
'history',
'innerHeight',
'innerWidth',
'length',
'localStorage',
'location',
'locationbar',
'menubar',
'moveBy',
'moveTo',
'name',
'onblur',
'onerror',
'onfocus',
'onload',
'onresize',
'onunload',
'open',
'opener',
'opera',
'outerHeight',
'outerWidth',
'pageXOffset',
'pageYOffset',
'parent',
'print',
'removeEventListener',
'resizeBy',
'resizeTo',
'screen',
'screenLeft',
'screenTop',
'screenX',
'screenY',
'scroll',
'scrollbars',
'scrollBy',
'scrollTo',
'scrollX',
'scrollY',
'self',
'status',
'statusbar',
'stop',
'toolbar',
'top'
],
'no-restricted-modules': ['error', 'chai'],
'no-unused-vars': [
'error',
{
varsIgnorePattern: '^_',
argsIgnorePattern: '^_'
}
],
'no-var': 'error',
'one-var': ['error', { initialized: 'never' }],
'prefer-const': [
'error',
{
destructuring: 'any'
}
],
'prettier/prettier': 'error',
'react/jsx-curly-brace-presence': [
'error',
{ children: 'ignore', props: 'never' }
],
'react/jsx-no-bind': [
'error',
{
allowArrowFunctions: true
}
],
'react/jsx-no-literals': 1,
'react/jsx-no-target-blank': DONT_WARN_CI,
'react/jsx-no-undef': ['error', { allowGlobals: true }],
'react/no-deprecated': DONT_WARN_CI,
'react/prop-types': 0,
'require-await': 'error',
'space-before-function-paren': 0
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'no-unused-vars': 'off',
'import/no-unresolved': 'off'
}
}
]
}
自从 "@typescript-eslint/parser": "^4.0.0"
从 "@typescript-eslint/parser": "^3.10.1"
升级库后,以下命令...
eslint --fix --ext .js,.jsx,.json,.ts,.tsx . && stylelint --fix '**/*.scss'
... 带来以下错误
9:45 error 'ScrollBehavior' is not defined no-undef
224:12 error 'KeyboardEventInit' is not defined no-undef
53:5 error 'JSX' is not defined no-undef
我知道我可以将它们添加到道具 globals
以及键 JSX: true
或 KeyboardEventInit: true
中,但这不是我想要的方式。
对这里发生的事情有什么想法吗?配置错误在哪里?
非常感谢
官方答案在这里
https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors 它说确实要将它们添加到 globals
或禁用 [=12=] 规则因为打字稿已经有自己的检查
编辑
这是复制的官方文档
## I get errors from the `no-undef` rule about global variables not being defined, even though there are no TypeScript errors
The `no-undef` lint rule does not use TypeScript to determine the global variables that exist - instead, it relies upon ESLint's configuration.
We strongly recommend that you do not use the `no-undef` lint rule on TypeScript projects.
The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.
As of our v4.0.0 release, this also applies to types.
If you use global types from a 3rd party package (i.e. anything from an `@types` package), then you will have to configure ESLint appropriately to define these global types.
For example; the `JSX` namespace from `@types/react` is a global 3rd party type that you must define in your ESLint config.
Note, that for a mixed project including JavaScript and TypeScript, the `no-undef` rule (like any role) can be turned off for TypeScript files alone by adding an `overrides` section to .eslintrc.json:
json
"overrides": [
{
"files": ["*.ts"],
"rules": {
"no-undef": "off"
}
}
]
If you choose to leave on the ESLint `no-undef` lint rule, you can [manually define the set of allowed `globals` in your ESLint config](https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals), and/or you can use one of the [pre-defined environment (`env`) configurations](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments).
我在打字稿中尝试声明 JSX.Element
类型的变量时遇到了同样的问题。我在 .eslintrc.json
中将 "JSX":"readonly"
添加到 globals
,问题就消失了。在你的情况下它将是:
globals: {
React: true,
google: true,
mount: true,
mountWithRouter: true,
shallow: true,
shallowWithRouter: true,
context: true,
expect: true,
jsdom: true,
JSX: true,
},
从下面的link,我了解到您实际上在JSX
之后使用了几个选项。您可以使用 true
、false
、writable
或 readonly
(但不能使用 off
)。
来自typescript-eslint troubleshooting guide:
We strongly recommend that you do not use the no-undef lint rule on TypeScript projects. The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.
在您的 .eslintrc.js
中,使用 overrides
:
module.exports = {
root: true,
extends: '@react-native-community',
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'no-shadow': 'off',
'@typescript-eslint/no-shadow': ['error'],
},
overrides: [
{
files: ['*.ts', '*.tsx'],
rules: {
'no-undef': 'off',
},
},
],
};