✒️
Notes
  • Lirenxn's daily notes
  • Featured
    • Concurrent on fiber and requestIdleCallback
    • Deep dive eslint
      • eslint with class property
      • eslint with fix
      • eslint with jsx
    • A opinioned intro to React Hooks
      • React Hooks 1 - An Overview
      • React Hooks 2 - A mindset change
      • React Hooks 3 - Test Hooks
    • Handy tricks
    • About Micro FrontEnd
    • Same-site cookie
    • Thoughts
      • Application Security for frontend OWASP
      • Javascript this
      • React validation
  • 2020 Daily Notes
    • Notes-04-05-eslint-and-babel
    • Notes-04-03-Hard-interview-question
    • Notes-03-31-ReactContext-JS-inherit
    • Notes-03-28-digital-signing-webpack-dynamic-import-JsonRest-Promise-pattern-performance.measure()
    • Wk-notes-03-16-i18n-solution
    • Notes-03-15-Concurrent-with-requestIdleCallback
    • Notes-03-15-Micro-frontend
    • Wk-notes-03-09-micro-frontend-bootstrapper
    • Wk-notes-02-27-API-design-(g)RPC-REST-etc
    • Wk-notes-02-26-React-form-validation-Boolean-algebra-Rule-for-this-App-security-npm-devtool-tricks
    • Wk-notes-02-18-i18n-gRPC
    • Wk-notes-02-11-Gradual-rollout-webpack-vscode-auto-import
    • Note-02-09-spring-webpack
    • Wk-notes-02-06-more-webpack
    • Wk-notes-02-05-Learn-spring-webpack
    • Wk-notes-02-04-props-drilling-virtual-list
    • Wk-notes-02-03-same-site-cookie
    • Wk-notes-01-31-g-recaptcha-npmshrinkwrap
    • Wk-notes-01-30-React-ref
    • Wk-notes-01-23-remote-android
    • Wk-notes-01-23-test-hook
    • Wk-notes-01-22-about-Hooks
    • Wk-notes-01-17-bundling-browser-module-treeshake-2
    • Wk-notes-01-16-Bundling-Treeshaking-1
    • Wk-notes-01-13-npm-script-css-scroll
    • Wk-notes-01-13-touchscreen-hover-and-apis
    • Wk-notes-01-13-emotion-x
    • Wk-notes-01-10-codemod
    • Wk-notes-01-08-live-region-react-test-lib
    • Wk-notes-01-06-eslint-finalise
  • 2019 Daily Notes
    • Wk-notes-12-11-eslint-dive-vscode-debug
    • Wk-notes-12-10-eslint-dive
    • Wk-notes-12-6-splunk
    • Wk-notes-12-3-react-function-memo
    • Wk-notes-12-2-agile-test-micro-frontend
    • Wk-notes-11-29-npm-fix-aem-datalayer-test
    • Wk-notes-11-28-adobe-dataLayer
    • Wk-notes-11-27-a11y
    • Wk-notes-11-25-upgrade-preact
    • Wk-notes-11-22-a11y-n-voice-over
    • Wk-notes-11-21-Add-Typescript
    • Wk-notes-11-20-JSDoc
    • Wk-notes-11-19-A11y-Polyfill
    • Wk-notes-11-18-jest-mock
    • Wk-notes-11-15-React-Portal
    • Wk-notes-11-14-iOS-simulator-git-hooks-All-hands-testing
    • Wk-notes-11-13-i18n
    • Wk-notes-11-12-safari-remote-debug
    • Wk-notes-11-11-migrating-typescript-git-remote-label-Emotion-controlled-component
    • Wk-notes-11-08-living-pricing-arch
    • Wk-notes-11-07-vitual-box-n-onblur-for-div
    • Wk-notes-11-06-bug-race-virtual-dom-diff
    • Wk-notes-11-05-babel-loader-eslint
Powered by GitBook
On this page
  • Issue
  • TL;DR
  • Take away:

Was this helpful?

  1. Featured
  2. Deep dive eslint

eslint with class property

How `babel-eslint` work with `eslint`, and the general workflow for linting and ast basics

PreviousDeep dive eslintNexteslint with fix

Last updated 5 years ago

Was this helpful?

On github:

Issue

If class property is used in class, eslint requires babel-eslint as parser (defaulted as espree) to parse the code before actual linting. For some reason, an error of eslint(no-undef) is always shown on the class property.

Firstly, I thought reason is @babel/plugin-proposal-class-properties is not provided for babel-eslint , while then I found actually babel-eslint always have class property as default plugin.

TL;DR

This should be solved by

{
    "eslint": ">=4.14.0",
    "babel-eslint": ">=8.1.0"
}

with fix from eslint/eslint , and fix from babel/babel-eslint . Thanks to for the hard work.

--------

Explanation: This is a issue caused by the 'scope analyze' in eslint. In the older version (<4.14.0), eslint analyze the scope by its own without passing in the correct childVisitorKeys attribute.

// eslint.js
// gather scope data that may be needed by the rules
scopeManager = escope.analyze(ast, {
    ignoreEval: true,
    nodejsScope: ecmaFeatures.globalReturn,
    impliedStrict: ecmaFeatures.impliedStrict,
    ecmaVersion,
    sourceType: currentConfig.parserOptions.sourceType || "script",
    fallback: Traverser.getKeys
});

After those two PRs, babel-eslint will generate the scopeManager with its own modification. eslint will consume the scopeManager (const scopeManager = parseResult.scopeManager;), and apply rules over it.

Take away:

  1. It costs time to locate the root cause for this kind of issue if you are not familiar with the massive project like eslint (or ast concept), not to mention it normally comes with several more issues together.

  2. If you really want to do the research, start from the rules folder and analyze specific rule to get two cents about what goes wrong, in this case, it's the scope. It would be much easier then to narrow down your research in scope-related logic in parse().

  3. The easy way to 'just make things work' maybe is always upgrade version.

How eslint(v4) compiles code

eslint.js(entry) -> CLIEngine(options) -> processWithText(text, options) -> linter.verify(text, options)

Inside verify(), sourceCode = parse(text, parser, parseOptions) -> analyze sourceCode.ast

  • load and analyze an ast for a 200 line file is not too practical

How linter analyse ast

  • sharedTraversalContext contains scope info

  • scope analyzer is important for rules to check scope and variables

A correct scope after parser.parse() requires corresponding childVisitorKeys defined by different parser, as explains

https://github.com/babel/babel-eslint/issues/487#issuecomment-564389834
PR#8755
PR#542
@mysticatea
https://github.com/eslint/eslint/blob/421aab44a9c167c82210bed52f68cf990b7edbea/lib/eslint.js#L892
PR#8755