Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@babel/no-invalid-this does not work for regular functions declared within class methods. #13085

Closed
umanghome opened this issue Apr 1, 2021 · 4 comments · Fixed by #13106
Closed
Labels
area: eslint i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@umanghome
Copy link

Bug Report

@babel/no-invalid-this does not work for regular functions declared within class methods.

Current behavior

No warning is thrown for usage of this within a regular function declared within a class method.

Input Code

function foo() {
  this.setState({ // error should be shown here (works)
    expanded: false,
  });
}

class Foo {
  handleToggle = () => {
    this.state = { // no error should be shown here (works)
      expanded: false,
    };

    function foox () {
      this.state = { // error should be shown here (does not work)
        expanded: false,
      }
    }

    foox();
  }
}

Expected behavior
An error should be shown on line 14 as well.

Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)

  • Filename: .babelrc
{
  "presets": [
    "@babel/preset-react",
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ],
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-export-default-from",
    "@babel/plugin-proposal-export-namespace-from",
    "@babel/plugin-proposal-optional-chaining",
    "@babel/plugin-proposal-nullish-coalescing-operator"
  ],
  "env": {
    "production": {
      "plugins": [
        "lodash"
      ]
    }
  }
}
  • Filename: .eslintrc
{
  "parser": "@babel/eslint-parser",
  "extends": [
    "airbnb",
    "prettier"
  ],
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "globals": {
    "chrome": false,
    "describe": false,
    "expect": false,
    "it": false
  },
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "legacyDecorators": true
    }
  },
  "plugins": [
    "react",
    "import",
    "@babel"
  ],
  "settings": {
    "import/resolver": {
      "node": {
        "moduleDirectory": [
          "node_modules",
          "assets/"
        ]
      }
    }
  },
  "rules": {
    "array-callback-return": 0,
    "array-bracket-spacing": 1,
    "camelcase": 1,
    "class-methods-use-this": 1,
    "comma-dangle": 0,
    "consistent-return": 0,
    "default-case": 1,
    "dot-notation": 0,
    "eqeqeq": 1,
    "id-length": 0,
    "import/no-extraneous-dependencies": 0,
    "import/extensions": 0,
    "import/first": 0,
    "import/named": 2,
    "import/no-unresolved": 0,
    "import/prefer-default-export": 0,
    "indent": [
      1,
      2,
      {
        "SwitchCase": 1
      }
    ],
    "jsx-a11y/alt-text": 1,
    "jsx-a11y/anchor-has-content": 0,
    "jsx-a11y/anchor-is-valid": 0,
    "jsx-a11y/click-events-have-key-events": 0,
    "jsx-a11y/interactive-supports-focus": 0,
    "jsx-a11y/label-has-for": 1,
    "jsx-a11y/media-has-caption": 0,
    "jsx-a11y/mouse-events-have-key-events": 0,
    "jsx-a11y/no-autofocus": 0,
    "jsx-a11y/no-static-element-interactions": 0,
    "max-len": [
      1,
      {
        "code": 150
      }
    ],
    "new-cap": 1,
    "no-console": [
      2,
      {
        "allow": [
          "warn",
          "error"
        ]
      }
    ],
    "no-else-return": 0,
    "no-extra-semi": 1,
    "@babel/no-invalid-this": "error",
    "no-lonely-if": 1,
    "no-nested-ternary": 1,
    "no-plusplus": 0,
    "no-underscore-dangle": 0,
    "no-unused-expressions": [
      2,
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ],
    "no-unused-vars": [
      1,
      {
        "argsIgnorePattern": "^_"
      }
    ],
    "no-use-before-define": [
      1,
      "nofunc"
    ],
    "no-useless-computed-key": 1,
    "no-useless-return": 0,
    "no-var": 1,
    "object-curly-newline": 1,
    "object-property-newline": 1,
    "object-shorthand": 1,
    "one-var": 1,
    "padded-blocks": 1,
    "prefer-const": 1,
    "prefer-destructuring": 1,
    "prefer-template": 0,
    "quote-props": [
      1,
      "as-needed"
    ],
    "quotes": [
      1,
      "single",
      "avoid-escape"
    ],
    "jsx-quotes": [
      1,
      "prefer-double"
    ],
    "radix": 1,
    "react/default-props-match-prop-types": 1,
    "react/forbid-prop-types": 0,
    "react/jsx-curly-brace-presence": 1,
    "react/jsx-no-bind": 1,
    "react/jsx-max-props-per-line": 0,
    "react/prop-types": 1,
    "react/no-unused-prop-types": 1,
    "react/jsx-boolean-value": 0,
    "react/jsx-closing-bracket-location": 1,
    "react/jsx-closing-tag-location": 1,
    "react/jsx-curly-spacing": 1,
    "react/jsx-equals-spacing": 1,
    "react/jsx-filename-extension": 1,
    "react/jsx-indent": 0,
    "react/jsx-indent-props": 1,
    "react/jsx-tag-spacing": 1,
    "react/no-danger": 1,
    "react/no-multi-comp": 0,
    "react/prefer-stateless-function": 0,
    "react/require-default-props": 1,
    "react/sort-comp": 0,
    "react/wrap-multilines": 0,
    "semi": 0,
    "space-infix-ops": 1,
    "spaced-comment": 0,
    "vars-on-top": 1,
    "react/jsx-key": 1
  },
  "overrides": [
    {
      // We want to use jsx syntax in our tests.
      "files": [
        "*spec.js"
      ],
      "rules": {
        "react/jsx-filename-extension": 0
      }
    }
  ]
}

Environment

System:
    OS: macOS 11.2.1
  Binaries:
    Node: 14.15.4 - ~/.nvm/versions/node/v14.15.4/bin/node
    npm: 7.6.3 - ~/.nvm/versions/node/v14.15.4/bin/npm
  npmPackages:
    @babel/core: ^7.0.0 => 7.13.14
    @babel/eslint-parser: ^7.13.14 => 7.13.14
    @babel/eslint-plugin: ^7.13.10 => 7.13.10
    @babel/plugin-proposal-class-properties: ^7.0.0 => 7.8.3
    @babel/plugin-proposal-decorators: ^7.0.0 => 7.12.12
    @babel/plugin-proposal-export-default-from: ^7.0.0 => 7.12.1
    @babel/plugin-proposal-export-namespace-from: ^7.0.0 => 7.12.1
    @babel/plugin-proposal-nullish-coalescing-operator: ^7.0.0 => 7.8.3
    @babel/plugin-proposal-optional-chaining: ^7.0.0 => 7.9.0
    @babel/preset-env: ^7.0.0 => 7.9.5
    @babel/preset-react: ^7.0.0 => 7.9.4
    babel-core: ^7.0.0-bridge.0 => 7.0.0-bridge.0
    babel-jest: ^23.4.2 => 23.6.0
    babel-loader: ^8.0.0 => 8.2.2
    babel-plugin-lodash: ^3.2.11 => 3.3.4
    babel-preset-react-hmre: ^1.0.0 => 1.1.1
    eslint: ^7.23.0 => 7.23.0
    idempotent-babel-polyfill: ^6.3.14 => 6.26.0
    jest: ^22.4.4 => 22.4.4
    webpack: ^4.25.1 => 4.42.1
@babel-bot
Copy link
Collaborator

Hey @umanghome! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

@JLHwung
Copy link
Contributor

JLHwung commented Apr 1, 2021

This issue is fixed in #12370, however we can not enable that feature because the ecosystem does not support the new AST. For a workaround, see the example config on #12891

BTW, the handleToggle in the example below is not a class method, but a class property whose value is an arrow function expression.

class Foo {
  handleToggle = () => {}
}

@umanghome
Copy link
Author

Thanks. I get this error when I try to use the config mentioned in #12891.

Error: ESLint configuration in .eslintrc is invalid:
	- Unexpected top-level property "babelOptions".
  • Filename: .eslintrc
{
  "parser": "@babel/eslint-parser",
  "babelOptions": {
    "parserOpts": {
      "plugins": [
        [
          "estree",
          {
            "classFeatures": true
          }
        ],
        "classPrivateProperties",
        "classProperties"
      ]
    }
  },
  "extends": [
    "airbnb",
    "prettier"
  ],
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "globals": {
    "chrome": false,
    "describe": false,
    "expect": false,
    "it": false
  },
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "legacyDecorators": true
    }
  },
  "plugins": [
    "react",
    "import",
    "@babel"
  ],
  "settings": {
    "import/resolver": {
      "node": {
        "moduleDirectory": [
          "node_modules",
          "assets/"
        ]
      }
    }
  },
  "rules": {
    "array-callback-return": 0,
    "array-bracket-spacing": 1,
    "camelcase": 1,
    "class-methods-use-this": 1,
    "comma-dangle": 0,
    "consistent-return": 0,
    "default-case": 1,
    "dot-notation": 0,
    "eqeqeq": 1,
    "id-length": 0,
    "import/no-extraneous-dependencies": 0,
    "import/extensions": 0,
    "import/first": 0,
    "import/named": 2,
    "import/no-unresolved": 0,
    "import/prefer-default-export": 0,
    "indent": [
      1,
      2,
      {
        "SwitchCase": 1
      }
    ],
    "jsx-a11y/alt-text": 1,
    "jsx-a11y/anchor-has-content": 0,
    "jsx-a11y/anchor-is-valid": 0,
    "jsx-a11y/click-events-have-key-events": 0,
    "jsx-a11y/interactive-supports-focus": 0,
    "jsx-a11y/label-has-for": 1,
    "jsx-a11y/media-has-caption": 0,
    "jsx-a11y/mouse-events-have-key-events": 0,
    "jsx-a11y/no-autofocus": 0,
    "jsx-a11y/no-static-element-interactions": 0,
    "max-len": [
      1,
      {
        "code": 150
      }
    ],
    "new-cap": 1,
    "no-console": [
      2,
      {
        "allow": [
          "warn",
          "error"
        ]
      }
    ],
    "no-else-return": 0,
    "no-extra-semi": 1,
    "@babel/no-invalid-this": "error",
    "no-lonely-if": 1,
    "no-nested-ternary": 1,
    "no-plusplus": 0,
    "no-underscore-dangle": 0,
    "no-unused-expressions": [
      2,
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ],
    "no-unused-vars": [
      1,
      {
        "argsIgnorePattern": "^_"
      }
    ],
    "no-use-before-define": [
      1,
      "nofunc"
    ],
    "no-useless-computed-key": 1,
    "no-useless-return": 0,
    "no-var": 1,
    "object-curly-newline": 1,
    "object-property-newline": 1,
    "object-shorthand": 1,
    "one-var": 1,
    "padded-blocks": 1,
    "prefer-const": 1,
    "prefer-destructuring": 1,
    "prefer-template": 0,
    "quote-props": [
      1,
      "as-needed"
    ],
    "quotes": [
      1,
      "single",
      "avoid-escape"
    ],
    "jsx-quotes": [
      1,
      "prefer-double"
    ],
    "radix": 1,
    "react/default-props-match-prop-types": 1,
    "react/forbid-prop-types": 0,
    "react/jsx-curly-brace-presence": 1,
    "react/jsx-no-bind": 1,
    "react/jsx-max-props-per-line": 0,
    "react/prop-types": 1,
    "react/no-unused-prop-types": 1,
    "react/jsx-boolean-value": 0,
    "react/jsx-closing-bracket-location": 1,
    "react/jsx-closing-tag-location": 1,
    "react/jsx-curly-spacing": 1,
    "react/jsx-equals-spacing": 1,
    "react/jsx-filename-extension": 1,
    "react/jsx-indent": 0,
    "react/jsx-indent-props": 1,
    "react/jsx-tag-spacing": 1,
    "react/no-danger": 1,
    "react/no-multi-comp": 0,
    "react/prefer-stateless-function": 0,
    "react/require-default-props": 1,
    "react/sort-comp": 0,
    "react/wrap-multilines": 0,
    "semi": 0,
    "space-infix-ops": 1,
    "spaced-comment": 0,
    "vars-on-top": 1,
    "react/jsx-key": 1
  },
  "overrides": [
    {
      // We want to use jsx syntax in our tests.
      "files": [
        "*spec.js"
      ],
      "rules": {
        "react/jsx-filename-extension": 0
      }
    }
  ]
}

@umanghome
Copy link
Author

Updated .eslintrc to this, but I still don't see the error.

{
  "parser": "@babel/eslint-parser",
  "extends": [
    "airbnb",
    "prettier"
  ],
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "globals": {
    "chrome": false,
    "describe": false,
    "expect": false,
    "it": false
  },
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "legacyDecorators": true
    },
    "babelOptions": {
      "parserOpts": {
        "plugins": [
          [
            "estree",
            {
              "classFeatures": true
            }
          ],
          "classPrivateProperties",
          "classProperties"
        ]
      }
    }
  },
  "plugins": [
    "react",
    "import",
    "@babel"
  ],
  "settings": {
    "import/resolver": {
      "node": {
        "moduleDirectory": [
          "node_modules",
          "assets/"
        ]
      }
    }
  },
  "rules": {
    "array-callback-return": 0,
    "array-bracket-spacing": 1,
    "camelcase": 1,
    "class-methods-use-this": 1,
    "comma-dangle": 0,
    "consistent-return": 0,
    "default-case": 1,
    "dot-notation": 0,
    "eqeqeq": 1,
    "id-length": 0,
    "import/no-extraneous-dependencies": 0,
    "import/extensions": 0,
    "import/first": 0,
    "import/named": 2,
    "import/no-unresolved": 0,
    "import/prefer-default-export": 0,
    "indent": [
      1,
      2,
      {
        "SwitchCase": 1
      }
    ],
    "jsx-a11y/alt-text": 1,
    "jsx-a11y/anchor-has-content": 0,
    "jsx-a11y/anchor-is-valid": 0,
    "jsx-a11y/click-events-have-key-events": 0,
    "jsx-a11y/interactive-supports-focus": 0,
    "jsx-a11y/label-has-for": 1,
    "jsx-a11y/media-has-caption": 0,
    "jsx-a11y/mouse-events-have-key-events": 0,
    "jsx-a11y/no-autofocus": 0,
    "jsx-a11y/no-static-element-interactions": 0,
    "max-len": [
      1,
      {
        "code": 150
      }
    ],
    "new-cap": 1,
    "no-console": [
      2,
      {
        "allow": [
          "warn",
          "error"
        ]
      }
    ],
    "no-else-return": 0,
    "no-extra-semi": 1,
    "@babel/no-invalid-this": "error",
    "no-lonely-if": 1,
    "no-nested-ternary": 1,
    "no-plusplus": 0,
    "no-underscore-dangle": 0,
    "no-unused-expressions": [
      2,
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ],
    "no-unused-vars": [
      1,
      {
        "argsIgnorePattern": "^_"
      }
    ],
    "no-use-before-define": [
      1,
      "nofunc"
    ],
    "no-useless-computed-key": 1,
    "no-useless-return": 0,
    "no-var": 1,
    "object-curly-newline": 1,
    "object-property-newline": 1,
    "object-shorthand": 1,
    "one-var": 1,
    "padded-blocks": 1,
    "prefer-const": 1,
    "prefer-destructuring": 1,
    "prefer-template": 0,
    "quote-props": [
      1,
      "as-needed"
    ],
    "quotes": [
      1,
      "single",
      "avoid-escape"
    ],
    "jsx-quotes": [
      1,
      "prefer-double"
    ],
    "radix": 1,
    "react/default-props-match-prop-types": 1,
    "react/forbid-prop-types": 0,
    "react/jsx-curly-brace-presence": 1,
    "react/jsx-no-bind": 1,
    "react/jsx-max-props-per-line": 0,
    "react/prop-types": 1,
    "react/no-unused-prop-types": 1,
    "react/jsx-boolean-value": 0,
    "react/jsx-closing-bracket-location": 1,
    "react/jsx-closing-tag-location": 1,
    "react/jsx-curly-spacing": 1,
    "react/jsx-equals-spacing": 1,
    "react/jsx-filename-extension": 1,
    "react/jsx-indent": 0,
    "react/jsx-indent-props": 1,
    "react/jsx-tag-spacing": 1,
    "react/no-danger": 1,
    "react/no-multi-comp": 0,
    "react/prefer-stateless-function": 0,
    "react/require-default-props": 1,
    "react/sort-comp": 0,
    "react/wrap-multilines": 0,
    "semi": 0,
    "space-infix-ops": 1,
    "spaced-comment": 0,
    "vars-on-top": 1,
    "react/jsx-key": 1
  },
  "overrides": [
    {
      // We want to use jsx syntax in our tests.
      "files": [
        "*spec.js"
      ],
      "rules": {
        "react/jsx-filename-extension": 0
      }
    }
  ]
}

@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Jul 6, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: eslint i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants