DEV Community

Nick
Nick

Posted on • Edited on

New ESLint flat config file format example

This note does not pretend to be complete - in fact, I don’t even want to understand how this junk works under the hood. However, it might save someone a day of work.

For some reason, the ESLint developers once again changed (this 9.0.0 v. is the second or third time in my memory) the configuration file format and plugin packages, so now the old configs do not work, so adding a linter to a new project may cause a problem. In fact, thanks to the efforts of these wonderful people, even this note will most likely soon become useless.

Official way

To get started, you can use the command that is recommended to use for setup in the official guide:

npm init @eslint/config

However, after this, simply running the linter will most likely not produce any result. Even if you run the linter with the correct command specifying the files to check, it still won’t work:
ESLint does not work after installing

The most interesting thing here is that the official guide gives a completely empty example of the config, as if you did not execute their command npm init @eslint/config

After running this command, the config will look something like this (if they haven’t changed anything again, lol):



import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";

// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: pluginJs.configs.recommended
});

export default [
  ...compat.extends("standard-with-typescript")
];


Enter fullscreen mode Exit fullscreen mode

Example of the eslint.config.js for the new version

Another way

Since the official config, apparently, is quite crooked (and, to be honest, I don’t even know if it works correctly), you may want to install the linter yourself. For this config you will need to install the following packages in the project:



{
  "devDependencies": {
    ... // your other deps
    "@eslint/eslintrc": "^3.0.2",
    "@eslint/js": "^9.0.0",
    "@typescript-eslint/eslint-plugin": "^6.21.0",
    "eslint": "^8.57.0",
    "eslint-config-standard-with-typescript": "^43.0.1",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-n": "^16.6.2",
    "eslint-plugin-promise": "^6.1.1"
  }
}


Enter fullscreen mode Exit fullscreen mode

As i already said, just after install linter wouldn't work anyway, because you still need add files section in config and, possible add some your own rules to it.

I found out that if need to add rules to the config file, you must do it in a certain way: since we already have some rules created by config command, we don't need to just add new ones, but do it next way:



import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";

// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: pluginJs.configs.recommended
});

export default [
  ...compat.extends("standard-with-typescript").map(
    config => ({
      ...config,
      files: ["**/*.tsx"],
      rules: {
         ...config.rules,
         "semi": "off", // For some reason the old rule is buggy and needs to be disabled IDK
         "@typescript-eslint/semi": ["error", "always"],
         "no-unreachable": "error", // Already in ts, but perhaps it catches more cases
         "@typescript-eslint/explicit-function-return-type": "off",
         "@typescript-eslint/strict-boolean-expressions": "off", // Often works incorrectly
         "@typescript-eslint/no-floating-promises": "off",
      }
    })
  ),
];



Enter fullscreen mode Exit fullscreen mode

Working example of eslint.config.js with custom rules

Now you can start the linter with the following command (for some reason it is still necessary to additionally specify files in the console, i have no idea why):
npx eslint 'src/**/*.{ts,tsx}' --no-ignore

You can add it to your scripts section of package.json for easy launch via npm run.

What's next? Code formatting?

The next stage, which may throw you into frustration, is that it turns out that the new linter now does not know how to properly format code out of the box.

Now a linter is purely a linter. Wow! Such great idea!

You can read about it here (the indentation problem that no one wanted to fix) and here (about the integration between a linter and a formatter), and here is even more detailed information about the “problems” with using linters as formatters.

So, in addition to the file with the linter settings, you will also have to add a .prettierrc file with the prettier settings:



{
  "tabWidth": 4,
  "singleQuote": true
}


Enter fullscreen mode Exit fullscreen mode

...as well as install the prettier itself:



npm install --save-dev eslint-plugin-prettier eslint-config-prettier
npm install --save-dev --save-exact prettier


Enter fullscreen mode Exit fullscreen mode

Yes, and besides, you will once again have to correct the linter config. Here's the final version:



import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";
import prettierConfig from 'eslint-config-prettier';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: pluginJs.configs.recommended
});

export default [
  ...compat.extends("standard-with-typescript").map(
    config => ({
      ...config,
      files: ["**/*.tsx"],
      rules: {
         ...config.rules,
         // ...other your custom rules
      }
    })
  ),
  prettierConfig, // Turns off all ESLint rules that have the potential to interfere with Prettier rules.
  eslintPluginPrettierRecommended
];


Enter fullscreen mode Exit fullscreen mode

Note: While it is possible to pass options to Prettier via your ESLint configuration file, it is not recommended because editor extensions such as prettier-atom and prettier-vscode will read .prettierrc, but won't read settings from ESLint, which can lead to an inconsistent experience.

Well, now, after all these crutches and a bunch of new garbage wonderful files in the root of your project, you can now use the linter. I think those who have read to the end already understand why the linter is a lousy tool in general.

But everything should work now. I hope this is useful to someone.

As for my opinion, ESLint is absolute garbage, a perfect example of a garbage application, so if you have a choice, try looking for something else. In my company it is a standard tool, so for years i have had to deal with changing config formats, constant renaming of plugin packages (FOR THAT?) and compatibility problems caused by this junk software. ESLint you must burn in hell!

Top comments (5)

Collapse
 
sloan profile image
Sloan the DEV Moderator

Heyo!

Just a reminder that you likely want to add tags to your post to help with discoverability. Folks follow tags to discover posts in their "relevant" feed on the DEV homepage, so tags are really important for getting your posts seen.

You can add popular, established tags, more niche tags, or create a brand new tag if there's one that has yet to be created. Some tags are centered around a technology (#python, #javascript) and others are more functional (#discuss, #help, #tutorial)... you can use a combination of 4 tags on your post, so choose wisely.

Always make sure that the tags you choose fit the subject matter of your post. Different tags have submission guidelines set up for them which you can view on a tag's landing page. For example, view the landing page for #career - dev.to/t/career and you'll see that the submission guidelines read:

All articles and discussions should relate to careers in some way.

Pretty much everything on dev.to is about our careers in some way. Ideally, though, keep the tag related to getting, leaving, or maintaining a career or job.

Note that we recruit Tag Moderators to help us create submission guidelines and ensure that posts are properly tagged.

Those are some of the basics of tags! Feel free to visit DEV Help for other helpful information!

Collapse
 
psychosynthesis profile image
Nick

Thanks, I completely forgot about them

Collapse
 
mrgoonie profile image
Goon Nguyen

That small notes at the end of this article is such valuable! 😆

Collapse
 
tempestrock profile image
Tempest Rock

Not sure if I can follow your last comment about ESLint being absolute garbage. At least, I would expect to get some suggestions for alternative tools with similar capabilities.

Collapse
 
psychosynthesis profile image
Nick

I adhere to the following position: firstly (this is the most important thing), even ESLint will not protect you from serious bugs, no matter how you configure it. Secondly, using TypeScript correctly allows you to catch a huge number of errors (although i don't really like TypeScript, i can't help but admit that it actually works).

If you still want an alternative, I would advise you to look at Quick-lint-js or OxLint.