iCrawl / eslint-config-neon

The ultimate ESLint shareable config
Apache License 2.0
57 stars 6 forks source link

Neon ESLint Config


npm version npm downloads

Installation

neon comes as a complete package, none of the configs require any additional dependecies.

npm install eslint eslint-config-neon
yarn add eslint eslint-config-neon
pnpm add eslint eslint-config-neon

Usage

This package includes the following configurations:

Notes

Flat Config only

It is important to note that this package only exports ESLint Flat Config! This means that you have to use eslint.config.js, eslint.config.mjs, or eslint.config.cjs to use this package. See the ESLint documentation on flat config for more information.

Importing Configs

Instead of importing from eslint-config-neon, you can also import each individual config from subpaths, e.g.

import common from "eslint-config-neon/common";

instead of

import { common } from "eslint-config-neon";

Merging Configs

In the examples below you will often see lodash.merge being used. This is of vital importance as objects often have to be deeply merged when using ESLint Flat Config. If you don't merge the objects, you will overwrite the previous object with the new one, and your config will be invalid.

This package ships ships a transient dependency to lodash.merge and @types/lodash.merge to make sure it is available in your project.

Reducing downloaded bundle size

Because this eslint config has a lot of transient dependencies to offer different eslint configs the bundle size of this package will be quite large. To alleviate this somewhat you can configure your package manager to skip the dependencies that you do not need through the resolutions (yarn) or overrides (npm / pnpm) fields.

Following is an example of excluding eslint-plugin-vue, which you can safely do if you're not using eslint-config-neon/vue nor eslint-config-neon/vue-typescript.

Yarn

{
    "resolutions": {
        "eslint-plugin-vue": "npm:@favware/skip-dependency@latest"
    }
}

Pnpm and npm

{
    "overrides": {
        "eslint-plugin-vue": "npm:@favware/skip-dependency@latest"
    }
}

Configuration

import { common, typescript, prettier } from "eslint-config-neon";

export default [
    {
        ignore: ["**/dist/*"],
    },
    ...common,
    ...typescript,
    ...prettier,
    {
        languageOptions: {
            project: "./tsconfig.json",
        },
    },
];
Node.js
```js import { common, prettier, typescript } from "eslint-config-neon"; import merge from "lodash.merge"; /** * @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.ConfigArray} */ const config = [ ...[...common, ...typescript, ...prettier].map((config) => merge(config, { files: ["src/**/*.ts"], languageOptions: { parserOptions: { project: "tsconfig.eslint.json", }, }, }), ), ]; export default config; ```
React / Next
React: ```js import { common, browser, node, typescript, react, edge, prettier } from "eslint-config-neon"; export default [ { ignore: ["**/dist/*"], }, ...common, ...browser, ...node, ...typescript, ...react, ...edge, ...prettier, { settings: { react: { version: "detect", }, }, languageOptions: { parserOptions: { project: "./tsconfig.json", }, }, rules: { "react/react-in-jsx-scope": 0, "react/jsx-filename-extension": [1, { extensions: [".tsx"] }], }, }, ]; ``` Next: Note: For Vite this is the same setup, just exclude the next config. ```js import { browser, common, edge, next, node, prettier, react, typescript } from "eslint-config-neon"; import merge from "lodash.merge"; /** * @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.ConfigArray} */ const config = [ ...[...common, ...browser, ...node, ...typescript, ...react, ...next, ...edge, ...prettier].map((config) => merge(config, { files: ["src/**/*.ts"], settings: { react: { version: "detect", }, }, languageOptions: { parserOptions: { project: "tsconfig.json", }, }, }), ), ]; export default config; ```
Astro
```js import { common, browser, node, typescript, react, astro, prettier } from "eslint-config-neon"; export default [ { ignore: ["**/dist/*"], }, ...common, ...browser, ...node, ...typescript, ...react, ...astro, ...prettier, { settings: { react: { version: "detect", }, }, languageOptions: { project: "./tsconfig.json", parserOptions: { project: "./tsconfig.json", }, }, rules: { "react/jsx-filename-extension": [1, { extensions: [".tsx"] }], }, }, ]; ```
Vue 2/3 / Nuxt
```js import { common, browser, node, typescript, vue, vuetypescript, prettier } from "eslint-config-neon"; export default [ { ignore: ["**/dist/*"], }, ...common, ...browser, ...node, ...typescript, ...vue, ...vuetypescript, ...prettier, { languageOptions: { parserOptions: { project: "./tsconfig.json", }, }, }, ]; ```
Angular / NX
```js import { angular, browser, common, node, prettier, rxjs, rxjsangular, typescript } from "eslint-config-neon"; import merge from "lodash.merge"; /** * @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.ConfigArray} */ const config = [ ...[...common, ...browser, ...node, ...typescript, ...angular, ...rxjs, ...rxjsangular, ...prettier].map((config) => merge(config, { files: ["src/**/*.ts"], languageOptions: { parserOptions: { project: "tsconfig.json", }, }, }), ), ...angular.map((config) => merge(config, { files: ["src/**/*.html"], languageOptions: { parserOptions: { project: "tsconfig.json", }, }, }), ), ]; export default config; ```

Usage with Prettier

Prettier and neon are already compatible. Just add it as the last config in your extends configuration, e.g.

import { prettier } from "eslint-config-neon";

export default [...prettier];

This configuration disables all neon rules that conflict with Prettier.