Eslint parsing error no babel config file detected for

I have a project where there is a top-level .eslintrc.json and another config inside a subdirectory. When I open a file located in that subdirectory, VSCode complains that ESLint can't find Bab...

I have a project where there is a top-level .eslintrc.json and another config inside a subdirectory. When I open a file located in that subdirectory, VSCode complains that ESLint can’t find Babel config:

Parsing error: No Babel config file detected for path/to/files.jsx. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.

But I do have .babelrc in both directories next to .eslintrc.json.

Here is my subdir configuration:

{
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true,
        "node": false
    },
    "parser": "@babel/eslint-parser",
    "parserOptions": {
        "ecmaVersion": 2018,
        "ecmaFeatures": {
            "jsx": true
        },
        "sourceType": "module"
    },
    "settings": {
        "react": {
            "version": "detect"
        }
    },
    "plugins": [
        "react"
    ],
    "extends": [
        "plugin:react/recommended"
    ],
    "rules": {
        "indent": ["warn", 4, {"SwitchCase": 1}],
        "brace-style": ["error", "1tbs"],
        "semi": ["error", "always"],
        "curly": ["error", "all"],
        "arrow-parens": ["error", "as-needed"],
        "comma-dangle": ["warn", "only-multiline"],
        "space-before-blocks": ["error", "always"],
        "space-before-function-paren": ["error", {
            "anonymous": "never",
            "named": "never",
            "asyncArrow": "always"
        }],
        "arrow-spacing": ["error", {
            "before": true,
            "after": true
        }],
        "keyword-spacing": ["error", {
            "before": true,
            "after": true
        }],
        "constructor-super": "warn",
        "valid-typeof": "warn",
        "no-const-assign": "warn",
        "no-this-before-super": "warn",
        "no-undef": "warn",
        "no-undefined": "error",
        "no-undef-init": "error",
        "no-unreachable": "warn",
        "no-unused-vars": ["warn", { "vars": "all", "args": "none"}],
        "no-invalid-regexp": "error",
        "no-multi-spaces": "warn",
        "no-multiple-empty-lines": ["warn", {"max": 1}],
        "react/prop-types": ["error", {"ignore": ["children"]}],
        "react/jsx-uses-react": "error",
        "react/jsx-uses-vars": "error",
        "react/button-has-type": "warn",
        "react/no-typos": "error",
        "react/no-array-index-key": "warn",
        "react/no-unused-state": "warn",
        "react/no-unused-prop-types": "warn",
        "react/self-closing-comp": "warn",
        "react/sort-comp": ["error", {
            "order": [
                "static-methods",
                "instance-variables",
                "lifecycle",
                "everything-else",
                "render"
            ]
        }],
        "react/void-dom-elements-no-children": "error",
        "react/jsx-pascal-case": "error",
        "react/jsx-props-no-multi-spaces": "warn",
        "react/jsx-tag-spacing": ["warn", {
            "closingSlash": "never",
            "beforeSelfClosing": "never",
            "afterOpening": "never",
            "beforeClosing": "allow"
        }]
    }
}

Top-level config:

{
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "parser": "@babel/eslint-parser",
    "parserOptions": {
        "sourceType": "module",
        "ecmaVersion": 2018
    },
    "rules": {
        "indent": ["warn", 4, {"SwitchCase": 1}],
        "brace-style": ["error", "1tbs"],
        "semi": ["error", "always"],
        "curly": ["error", "all"],
        "arrow-parens": ["error", "as-needed"],
        "comma-dangle": ["warn", "only-multiline"],
        "space-before-blocks": ["error", "always"],
        "space-before-function-paren": ["error", {
            "anonymous": "never",
            "named": "never",
            "asyncArrow": "always"
        }],
        "arrow-spacing": ["error", {
            "before": true,
            "after": true
        }],
        "keyword-spacing": ["error", {
            "before": true,
            "after": true
        }],
        "constructor-super": "warn",
        "valid-typeof": "warn",
        "no-const-assign": "warn",
        "no-this-before-super": "warn",
        "no-undef": "warn",
        "no-undefined": "error",
        "no-undef-init": "error",
        "no-unreachable": "warn",
        "no-unused-vars": ["warn", { "vars": "all", "args": "none"}],
        "no-invalid-regexp": "error",
        "no-multi-spaces": "warn",
        "no-multiple-empty-lines": ["warn", {"max": 1}]
    }
}

Cover image for Setting up ESLint to work with new or proposed JavaScript features such as private class fields.

George Griffiths

Some members in my team this week wanted to make use of Private class fields in a NodeJS server. This proposal is currently shipped in Chrome, Edge, Firefox and NodeJS, with Safari notably absent. In this instance, we wanted to get them working for a backend server application, so support since Node 12, we’re good to go, or so I thought, turns out linters aren’t always here to save you time.

I summed my feelings on the whole process of figuring this out on Twitter.

Man trying to configure eslint to understand private class fields is a fucking hellscape

14:27 PM — 01 Dec 2020

Twitter reply action

Twitter retweet action

Twitter like action

Feel free if you want to skip ahead past the story, and to head right to Configuring ESLint.

For this article, i’ll be using this code example of using Private class fields, the code used is irrelevant.

export class Animal {
    // this is a private class field!
    #noise = '';

    constructor(noise) {
        this.#noise = noise;
    }

    makeNoise() {
        console.log(this.#noise);
    }
}

Enter fullscreen mode

Exit fullscreen mode

The first issue we hit when writing this new code, was of course, the linter started failing, so off to Google we went!

Struggling to finding a solution

A quick search for: eslint private class fields you will most likely end up in this Stack Overflow issue.
It will tell you that ESLint does not support experimental stage 3 features, which is indeed correct, and to:

npm install eslint babel-eslint --save-dev

Enter fullscreen mode

Exit fullscreen mode

and to update your ESLint config file over to use:

  "parser": "babel-eslint",

Enter fullscreen mode

Exit fullscreen mode

Sadly, it seems this is not an entire solution, it seems to make a couple of assumptions:

  • You have babel-core installed
  • You have a babel configuration file set up that knows how to transform code with a preset.
  • Its possible that when the answer was posted babel-eslint did indeed solve al the problems.

If you are in a NodeJS server module, a lot of these assumptions are probably not met.

If you are a developer that has never had to use Babel because you work on the backend or on a build-less frontend, all this stuff can get daunting very fast.

Additionally, it seems since this answer was posted, things have moved on and the recommended parser now lives at:

    "parser": "@babel/eslint-parser",

Enter fullscreen mode

Exit fullscreen mode

The ESLint website does have some information about the Past, Present and Future of the babel-eslint over on its website.

Finding this information out was a bit of an adventure, and even on the official babel or ESLint website, it’s super unclear that you need to set up a babel config, and then still, what to put in it. I’m pretty sure the only reason I managed to figure it out in the end was because i’m familiar with the mess that is configuring Webpack, Jest and Babel.

Configuring ESLint

Let’s get our new syntax working!

First off, lets do the npm install dance:

npm i eslint @babel/core @babel/eslint-parser @babel/preset-env -D

Enter fullscreen mode

Exit fullscreen mode

It’s nice to set up a linter task in your package json so you can run npm run lint

  "scripts": {
    "lint": "eslint ./"
  },

Enter fullscreen mode

Exit fullscreen mode

I’m opting to use @babel/preset-env because it has an easy way to enabled proposals that are shipped in Browsers/Node. Other presets/plugins are available.

Next we need to construct an .eslintrc file.
You can generate one using: ./node_modules/.bin/eslint --init or just copy this starter:

{
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": "eslint:recommended",
    "parser": "@babel/eslint-parser",
    "parserOptions": {
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "rules": {
    }
}

Enter fullscreen mode

Exit fullscreen mode

Now if you run npm run lint You will hit the following error:

/path/to/code/Animal.js
  0:0  error  Parsing error: No Babel config file detected for /path/to/code/Animal.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files

 1 problem (1 error, 0 warnings)

Enter fullscreen mode

Exit fullscreen mode

It’s telling you we need to configure babel for @babel/eslint-parser to work.

Lets set up a babel config file.

Create a file called .babelrc and populate it with:

{
  "presets": [
    ["@babel/preset-env"]
  ]
}

Enter fullscreen mode

Exit fullscreen mode

You can read about @babel/preset-env on the Babel website.

Now if you run npm run lint again you will hit the final error:

/path/to/code/Animal.js
  2:4  error  Parsing error: /path/to/code/Animal.js: Support for the experimental syntax 'classPrivateProperties' isn't currently enabled (2:5):

  1 | export class Animal {
> 2 |     #noise = '';
    |     ^
  3 | 
  4 |     constructor(noise) {
  5 |         this.#noise = noise;

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
If you want to leave it as-is, add @babel/plugin-syntax-class-properties (https://git.io/vb4yQ) to the 'plugins' section to enable parsing

✖ 1 problem (1 error, 0 warnings)

Enter fullscreen mode

Exit fullscreen mode

You could proceed to add plugins for each of the proposals as the instructions say, alternatively you can opt to say I want all shipped proposals.

To do this change your .babelrc over to:

{
    "presets": [
      ["@babel/preset-env",
      {
        "shippedProposals": true
      }]
    ]
  }

Enter fullscreen mode

Exit fullscreen mode

From the Babel docs: «set the shippedProposals option to true. This will enable polyfills and transforms for proposal which have already been shipped in browsers for a while.»

If you are using Jest

If you are using Jest, it will automatically pick up .babelrc files, this might be problematic, as it will very helpfully start to try to transpile things like async/await, potentially leading you down even more rabbit holes. With really helpful messages like:

ReferenceError: regeneratorRuntime is not defined

Enter fullscreen mode

Exit fullscreen mode

By dumb luck, i’ve been through the pain of this message many times, and knew exactly what was wrong, Jest was trying to transform the perfectly valid code.

It’s almost 2021, and this is a server app, I certainly do not want to transpile async/await especially not in unit tests!

One way to work around this is to use a non-standard name for your .babelrc file e.g. .babel-eslintrc. There may be better solutions, but I certainly don’t want Jest unnecessarily transforming code.

In your .eslintrc file you can update babelOptions to use a custom configFile

"babelOptions": {
    "configFile": "./.babel-eslintrc"
 }

Enter fullscreen mode

Exit fullscreen mode

And there we go, Jest is now happy again because it’s not using the Babel configuration.

Summary

All in all this was a lot harder than I thought it would be, my guess is that many people don’t hit this issue because they happen to already have Babel configured. But in the case of backend dev, getting along happily, just trying to make use of a shipped JavaScript feature in a server, you can get dragged into the hellscape of frontend development tooling, and no one has fun there.

I hope this was a good read, if you feel like reading more of my work, please follow me on Twitter @griffadev, or get me a coffee if you feel like it ☕.

Recommend Projects

  • React photo

    React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo

    Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo

    Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo

    TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo

    Django

    The Web framework for perfectionists with deadlines.

  • Laravel photo

    Laravel

    A PHP framework for web artisans

  • D3 photo

    D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Visualization

    Some thing interesting about visualization, use data art

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo

    Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo

    Microsoft

    Open source projects and samples from Microsoft.

  • Google photo

    Google

    Google ❤️ Open Source for everyone.

  • Alibaba photo

    Alibaba

    Alibaba Open Source for everyone

  • D3 photo

    D3

    Data-Driven Documents codes.

  • Tencent photo

    Tencent

    China tencent open source team.

Понравилась статья? Поделить с друзьями:
  • Eslint parsing error import and export may appear only with sourcetype module
  • Eslint optional chaining parsing error unexpected token
  • Eslint npm error
  • Esl4550ro ошибка i20
  • Esia1 код ошибки