eslint-config
Shared eslint config
·
Report Bug
·
Request Feature
·
About The Project
Shared eslint config for my projects. Utilizing ESLint.
Installation
npm i -D @beuluis/eslint-config
Usage
-
Install ESlint
npm i -D eslint
-
Create a
.eslintrc
file and pick one of the configs and paste it in.touch .eslintrc
-
Tweak the overrides to your used project structure. Also feel free to remove unused extends.
-
Install @beuluis/prettier-config
⚠️ Since this pack does not assume any particularly structure. It is necessary to configure the glob patterns according to your project structure.
Supported configs
- @beuluis/eslint-config - The JSMDG code style guide
- @beuluis/eslint-config/i18next - For projects that use i18next.
- @beuluis/eslint-config/browser - For projects that use DOM and other browser APIs.
- @beuluis/eslint-config/node - For projects using node.js
- @beuluis/eslint-config/typescript - For projects using TypeScript
- @beuluis/eslint-config/typescript-no-type-checking - For projects using TypeScript and don't want additional rules that require type information (rules using type information take longer to run)
- @beuluis/eslint-config/react - For projects using React
- @beuluis/eslint-config/json - For projects using JSON
- @beuluis/eslint-config/yaml - For projects using YAML
- @beuluis/eslint-config/jest - For projects using Jest
- @beuluis/eslint-config/module - For projects using ESM modules
- @beuluis/eslint-config/next - For projects using Next.js
- @beuluis/eslint-config/Zod - For projects using Zod
- @beuluis/eslint-config/prettier - Applies Prettier formatting
Configs
JavaScript
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
}
]
}
JavaScript & Browser environment
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": ["@beuluis/eslint-config/browser"],
"files": "*.js"
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
}
]
}
Node
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": ["@beuluis/eslint-config/node"],
"files": "*.js"
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.js",
"**/{__mocks__,__tests__}/**/*.js",
"**/jest.setup.js"
]
}
]
}
Node & modules
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": ["@beuluis/eslint-config/node", "@beuluis/eslint-config/module"],
"files": "*.js"
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.js",
"**/{__mocks__,__tests__}/**/*.js",
"**/jest.setup.js"
]
}
]
}
TypeScript
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": ["@beuluis/eslint-config/typescript"],
"files": "*.ts",
"parserOptions": {
"project": "tsconfig.json"
}
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.ts",
"**/{__mocks__,__tests__}/**/*.ts",
"**/jest.setup.ts"
]
}
]
}
TypeScript & Browser environment
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": [
"@beuluis/eslint-config/typescript",
"@beuluis/eslint-config/browser"
],
"files": "*.ts",
"parserOptions": {
"project": "tsconfig.json"
}
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.ts",
"**/{__mocks__,__tests__}/**/*.ts",
"**/jest.setup.ts"
]
}
]
}
React
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": [
"@beuluis/eslint-config/node",
"@beuluis/eslint-config/browser",
"@beuluis/eslint-config/i18next"
],
"files": "*.{js,jsx}"
},
{
"extends": ["@beuluis/eslint-config/react"],
"files": "*.jsx"
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.js",
"**/{__mocks__,__tests__}/**/*.js",
"**/jest.setup.js"
]
}
]
}
React & TypeScript
{
"extends": ["@beuluis/eslint-config"],
"root": true,
"overrides": [
{
"extends": [
"@beuluis/eslint-config/typescript",
"@beuluis/eslint-config/browser",
"@beuluis/eslint-config/i18next"
],
"files": "*.{ts,tsx}",
"parserOptions": {
"project": "tsconfig.json"
}
},
{
"extends": ["@beuluis/eslint-config/react"],
"files": "*.tsx"
},
{
"extends": ["@beuluis/eslint-config/json"],
"files": "*.json"
},
{
"extends": ["@beuluis/eslint-config/yaml"],
"files": "*.{yml,yaml}"
},
{
"extends": ["@beuluis/eslint-config/jest"],
"files": [
"*.?(component-){spec,test}.{ts,tsx}",
"**/{__mocks__,__tests__}/**/*.{ts,tsx}",
"**/jest.setup.ts"
]
}
]
}
Extend config
Your .eslintrc
file can be extended and overridden as normal.
However, one point is worth mentioning. You don't need to install plugins already listed in the dependencies. (See Tips and tricks for more info)
This means you only need to install plugins or configs if they are not provided by this pack.
typescript
config vs. typescript-no-type-checking
config
I decided to do a opt out approach in favor of type safety. The typescript
has the same rules enabled as the typescript-no-type-checking
but enables some more rules that need deeper type checking. In general this is a good thing thats why it is enabled in the default typescript
config but for some larger projects or projects with complex types this can be a performance issue.
If you experience such performance issues you have two points to consider:
- Refactor your complex types. Most of the time when eslint has trouble this is a hint that your types may not be well structure or can be optimized.
- Turn off this feature by using the
typescript-no-type-checking
config instead of thetypescript
config
Migrating to version 2.X.X
This version has prettier now build in and ignores prettier config files.
So make sure that prettier is run only for files eslint can not parse if it should run at all.
Editorconfig
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
[*.json]
indent_size = 2
[*.{yaml,yml}]
indent_size = 2
Development
Note on canonical/node
It is not used due to its usage of the outdated eslint-plugin-node pack. See this issue on GitHub.
It is replaced with eslint-plugin-n instead.
How it works
I make use of @rushstack/eslint-patch/modern-module-resolution to load all the packages defined in the package.json
. In doing so the consuming package doesn't have to install them as peerDependency.
All the rules get separated into fitting configurations. They can be later used alongside the base one.
So if you have a new technology/lib/etc. That need extra rules like react or jest? -> create a new configuration in configurations
.
Prettier integration
See Migrating to version 2.X.X.
Structure
Configurations need to be reexported on root level to be found by ESlint.
I use the subfolder configurations
to define the configurations as JSON and make use of the eslintrc schema for validation.
.
├── ...
├── configurations # All configurations to be used
│ ├── eslintrc.json # Base configuration. Should apply for all languages to be tested by eslint
│ ├── {{name}}.json # Specialized configuration for languages, tools, libs, etc.
│ └── ...
├── eslintrc.js # Base configuration export. Also loads https://www.npmjs.com/package/@rushstack/eslint-patch
├── {{name}}.js # Specialized configuration export. Can also be used to log warnings for deprecation or throw errors for other infos about the used configuration.
└── ...
Inside the files I try to keep this structure:
{
"first_all_rules_that_are_turned_off": "off",
"first_all_rules_that_are_configured_with_warn": "warn",
"first_all_rules_that_are_configured_with_error": "error"
}
Rule values
Rules should use the string value instead of the number to ensure easy reading:
-
"off"
instead of0
-
"warn"
instead of1
-
"error"
instead of2
Tips and tricks
-
You see a error like
'module' is not defined
or other node global variables missing?Add a
node
override for.js
(often still needed in TS projects for config files or so):{ "overrides": [ { "extends": ["@beuluis/eslint-config/node"], "files": ["*.js"] } ] }
-
One of the most confusing part is the override mechanism of eslint.
Some useful links for that are extending-configuration-files and how-do-overrides-work
-
Make sure to read the plugin documentations carefully. Most plugins recommended configs already enable all you need.
Example: The prettier recommended-configuration already expand to
{ "extends": ["prettier"], "plugins": ["prettier"], "rules": { "prettier/prettier": "error", "arrow-body-style": "off", "prefer-arrow-callback": "off" } }
so no need to redefine it.
-
Same goes for extended configs.
Example: canonical already enables the
import
plugin. So no need to redefine it. You can just use it
Contributing
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Contact
Luis Beu - me@luisbeu.de