upgrade to ESLint 9 flat config
upgrade dependencies
This commit is contained in:
parent
74127dab53
commit
b3615e6f55
57
README.md
57
README.md
@ -1,41 +1,48 @@
|
||||
# @vchikalkin/eslint-config-awesome
|
||||
# @vchikalkin/eslint-config-awesome 🎉
|
||||
|
||||
- 🛠️ Most rules autofixable
|
||||
- 🎯 Designed to work with TypeScript, Nextjs, React projects
|
||||
- 🎯 Designed to work with TypeScript, NextJS, React projects
|
||||
- 🏆 Powered by [Canonical](https://github.com/gajus/eslint-config-canonical), [SonarJS](https://github.com/SonarSource/eslint-plugin-sonarjs)
|
||||
- ⚙️ Using ESLint **Flat** config
|
||||
|
||||
## Requirements
|
||||
|
||||
- [ESLint 9](https://github.com/eslint/eslint)
|
||||
- [TypeScript 5](https://www.typescriptlang.org/)
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
### 📥 Install
|
||||
|
||||
```bash
|
||||
yarn add -D eslint @vchikalkin/eslint-config-awesome
|
||||
pnpm add -D eslint typescript @vchikalkin/eslint-config-awesome
|
||||
```
|
||||
|
||||
### ⚙️ Config `.eslintrc.js`
|
||||
### ⚙️ Config `eslint.config.js`
|
||||
|
||||
For Next.js
|
||||
Common usage:
|
||||
|
||||
```js
|
||||
const { createConfig } = require('@vchikalkin/eslint-config-awesome');
|
||||
const config = require('@vchikalkin/eslint-config-awesome');
|
||||
|
||||
module.exports = createConfig('next-typescript'); // or module.exports = createConfig('next');
|
||||
module.exports = config['react-typescript'];
|
||||
```
|
||||
|
||||
For React
|
||||
Extend config:
|
||||
|
||||
```js
|
||||
const { createConfig } = require('@vchikalkin/eslint-config-awesome');
|
||||
const config = require('@vchikalkin/eslint-config-awesome');
|
||||
|
||||
module.exports = createConfig('react-typescript'); // or module.exports = createConfig('react');
|
||||
```
|
||||
|
||||
For TypeScript
|
||||
|
||||
```js
|
||||
const { createConfig } = require('@vchikalkin/eslint-config-awesome');
|
||||
|
||||
module.exports = createConfig('typescript');
|
||||
module.exports = [
|
||||
...config['react-typescript'],
|
||||
{
|
||||
rules: {
|
||||
'rule-name': 'off',
|
||||
},
|
||||
ignores: ['node_modules'],
|
||||
},
|
||||
//...other configs
|
||||
];
|
||||
```
|
||||
|
||||
### ➕ Add script for package.json
|
||||
@ -57,13 +64,14 @@ Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?it
|
||||
|
||||
```json
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit",
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.removeUnusedImports": "explicit"
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true,
|
||||
"source.fixAll.eslint": true,
|
||||
"source.removeUnusedImports": true
|
||||
},
|
||||
"eslint.lintTask.enable": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
@ -71,7 +79,6 @@ Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?it
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"yaml"
|
||||
],
|
||||
"eslint.lintTask.enable": true
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
36
configs/react-typescript.js
vendored
Normal file
36
configs/react-typescript.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
const { fixupConfigRules } = require('@eslint/compat');
|
||||
const { FlatCompat } = require('@eslint/eslintrc');
|
||||
const auto = require('eslint-config-canonical/configurations/auto');
|
||||
const sonarjs = require('eslint-plugin-sonarjs');
|
||||
const rules = require('../rules');
|
||||
|
||||
const flatCompat = new FlatCompat();
|
||||
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = [
|
||||
{ name: 'ESLint config awesome' },
|
||||
...auto,
|
||||
sonarjs.configs.recommended,
|
||||
{
|
||||
plugins: {
|
||||
import: require('eslint-plugin-import'),
|
||||
react: require('eslint-plugin-react'),
|
||||
},
|
||||
},
|
||||
...fixupConfigRules(flatCompat.extends('plugin:@next/next/core-web-vitals')),
|
||||
rules.common,
|
||||
rules.react,
|
||||
rules.sonar,
|
||||
{
|
||||
ignores: [
|
||||
'**/node_modules',
|
||||
'**/package-lock.json',
|
||||
'**/pnpm-lock.yaml',
|
||||
'**/package.json',
|
||||
'**/tsconfig.json',
|
||||
'**/eslint.config.js',
|
||||
],
|
||||
},
|
||||
];
|
||||
4
index.js
4
index.js
@ -1,3 +1,3 @@
|
||||
const createConfig = require('./utils/create-config');
|
||||
const reactTypescript = require('./configs/react-typescript');
|
||||
|
||||
module.exports = { createConfig };
|
||||
module.exports = { 'react-typescript': reactTypescript };
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
globals: {
|
||||
React: true,
|
||||
JSX: true,
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2022: true,
|
||||
node: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'canonical',
|
||||
'plugin:sonarjs/recommended',
|
||||
'canonical/next',
|
||||
'prettier',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
extends: ['canonical/typescript'],
|
||||
files: '*.ts',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/react', 'canonical/typescript'],
|
||||
files: '*.tsx',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/react'],
|
||||
files: '*.jsx',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/graphql'],
|
||||
files: ['*.graphql'],
|
||||
},
|
||||
// {
|
||||
// files: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
// extends: ['plugin:testing-library/react', 'canonical/jest'],
|
||||
// },
|
||||
],
|
||||
plugins: [
|
||||
'sonarjs',
|
||||
'prettier',
|
||||
// 'testing-library',
|
||||
],
|
||||
};
|
||||
@ -1,15 +0,0 @@
|
||||
const javascript = require('../rules/javascript');
|
||||
const typescript = require('../rules/typescript');
|
||||
const sonar = require('../rules/sonar');
|
||||
const react = require('../rules/react');
|
||||
const next = require('../rules/next');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
...javascript.rules,
|
||||
...typescript.rules,
|
||||
...sonar.rules,
|
||||
...react.rules,
|
||||
...next.rules,
|
||||
},
|
||||
};
|
||||
@ -1,37 +0,0 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
globals: {
|
||||
React: true,
|
||||
JSX: true,
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2022: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
'canonical',
|
||||
'plugin:sonarjs/recommended',
|
||||
'canonical/next',
|
||||
'prettier',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
extends: ['canonical/react'],
|
||||
files: '*.jsx',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/graphql'],
|
||||
files: ['*.graphql'],
|
||||
},
|
||||
// {
|
||||
// files: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
// extends: ['plugin:testing-library/react', 'canonical/jest'],
|
||||
// },
|
||||
],
|
||||
plugins: [
|
||||
'sonarjs',
|
||||
'prettier',
|
||||
// 'testing-library',
|
||||
],
|
||||
};
|
||||
@ -1,13 +0,0 @@
|
||||
const javascript = require('../rules/javascript');
|
||||
const sonar = require('../rules/sonar');
|
||||
const react = require('../rules/react');
|
||||
const next = require('../rules/next');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
...javascript.rules,
|
||||
...sonar.rules,
|
||||
...react.rules,
|
||||
...next.rules,
|
||||
},
|
||||
};
|
||||
22
package.json
22
package.json
@ -1,18 +1,21 @@
|
||||
{
|
||||
"name": "@vchikalkin/eslint-config-awesome",
|
||||
"version": "1.1.6",
|
||||
"version": "2.0.0",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/parser": "^6.19.0",
|
||||
"eslint-config-canonical": "^42.3.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-canonical": "^4.15.1",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"eslint-plugin-sonarjs": "^0.22.0"
|
||||
"@typescript-eslint/parser": "^8.16.0",
|
||||
"eslint-config-canonical": "^44.3.31",
|
||||
"eslint-plugin-sonarjs": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.2.2"
|
||||
"@eslint/compat": "^1.2.3",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@next/eslint-plugin-next": "^15.0.3",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint-config-next": "^15.0.3",
|
||||
"next": "^15.0.3",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@ -32,7 +35,6 @@
|
||||
"zod"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@babel/eslint-plugin": "^7.22.10",
|
||||
"eslint": "^8.52.0"
|
||||
"@next/eslint-plugin-next": "^15.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
6422
pnpm-lock.yaml
generated
Normal file
6422
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
react-typescript/config.js
vendored
28
react-typescript/config.js
vendored
@ -1,28 +0,0 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
globals: {
|
||||
JSX: true,
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2022: true,
|
||||
node: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: ['canonical', 'plugin:sonarjs/recommended', 'prettier'],
|
||||
overrides: [
|
||||
{
|
||||
extends: ['canonical/typescript'],
|
||||
files: '*.ts',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/react', 'canonical/typescript'],
|
||||
files: '*.tsx',
|
||||
},
|
||||
{
|
||||
extends: ['canonical/react'],
|
||||
files: '*.jsx',
|
||||
},
|
||||
],
|
||||
plugins: ['sonarjs', 'prettier'],
|
||||
};
|
||||
13
react-typescript/rules.js
vendored
13
react-typescript/rules.js
vendored
@ -1,13 +0,0 @@
|
||||
const javascript = require('../rules/javascript');
|
||||
const typescript = require('../rules/typescript');
|
||||
const sonar = require('../rules/sonar');
|
||||
const react = require('../rules/react');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
...javascript.rules,
|
||||
...typescript.rules,
|
||||
...sonar.rules,
|
||||
...react.rules,
|
||||
},
|
||||
};
|
||||
20
rules/common.js
Normal file
20
rules/common.js
Normal file
@ -0,0 +1,20 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
name: 'Common rules override',
|
||||
rules: {
|
||||
'canonical/filename-match-exported': 'off',
|
||||
'func-style': [
|
||||
'warn',
|
||||
'declaration',
|
||||
{
|
||||
allowArrowFunctions: true,
|
||||
},
|
||||
],
|
||||
'import/no-unassigned-import': [
|
||||
2,
|
||||
{
|
||||
allow: ['**/*.css'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
9
rules/index.js
Normal file
9
rules/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
const common = require('./common');
|
||||
const sonar = require('./sonar');
|
||||
const react = require('./react');
|
||||
|
||||
module.exports = {
|
||||
common,
|
||||
react,
|
||||
sonar,
|
||||
};
|
||||
@ -1,98 +0,0 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
// Disabled
|
||||
'brace-style': 'off',
|
||||
'comma-dangle': 'off',
|
||||
'comma-spacing': 'off',
|
||||
'func-call-spacing': 'off',
|
||||
indent: 'off',
|
||||
'keyword-spacing': 'off',
|
||||
'lines-between-class-members': 'off',
|
||||
'no-extra-parens': 'off',
|
||||
'object-curly-spacing': 'off',
|
||||
'padding-line-between-statements': 'off',
|
||||
quotes: 'off',
|
||||
semi: 'off',
|
||||
'space-before-blocks': 'off',
|
||||
'space-before-function-paren': 'off',
|
||||
'space-infix-ops': 'off',
|
||||
|
||||
// Config
|
||||
'linebreak-style': ['error', 'windows'],
|
||||
'import/extensions': 'off',
|
||||
'newline-before-return': 'warn',
|
||||
'function-paren-newline': 'off',
|
||||
'promise/prefer-await-to-then': 'off',
|
||||
'id-length': 'warn',
|
||||
'import/no-unassigned-import': 'off',
|
||||
'import/no-named-as-default-member': 'warn',
|
||||
|
||||
// Unicorn
|
||||
'unicorn/no-array-for-each': 'off',
|
||||
'unicorn/prevent-abbreviations': 'off',
|
||||
'unicorn/prefer-node-protocol': 'off',
|
||||
'unicorn/no-array-reduce': 'off',
|
||||
'unicorn/prefer-module': 'off',
|
||||
'unicorn/text-encoding-identifier-case': 'off',
|
||||
'unicorn/filename-case': [
|
||||
'error',
|
||||
{
|
||||
case: 'kebabCase',
|
||||
ignore: ['^.*.(jsx|tsx)$'],
|
||||
},
|
||||
],
|
||||
'unicorn/numeric-separators-style': [
|
||||
'warn',
|
||||
{
|
||||
onlyIfContainsSeparator: false,
|
||||
hexadecimal: {
|
||||
minimumDigits: 0,
|
||||
groupLength: 2,
|
||||
},
|
||||
binary: {
|
||||
minimumDigits: 0,
|
||||
groupLength: 4,
|
||||
},
|
||||
octal: {
|
||||
minimumDigits: 0,
|
||||
groupLength: 4,
|
||||
},
|
||||
number: {
|
||||
minimumDigits: 5,
|
||||
groupLength: 3,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// Canonical
|
||||
'canonical/prefer-inline-type-import': 'off',
|
||||
'@babel/object-curly-spacing': ['off'],
|
||||
'canonical/filename-match-exported': ['off'],
|
||||
'canonical/import-specifier-newline': ['off'],
|
||||
'canonical/destructuring-property-newline': ['off'],
|
||||
'canonical/export-specifier-newline': 'off',
|
||||
'canonical/sort-keys': [
|
||||
'warn',
|
||||
'asc',
|
||||
{
|
||||
natural: true,
|
||||
},
|
||||
],
|
||||
'canonical/id-match': ['off'],
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
groups: [],
|
||||
'newlines-between': 'always',
|
||||
},
|
||||
],
|
||||
'func-style': ['warn', 'declaration', { allowArrowFunctions: true }],
|
||||
'arrow-body-style': [
|
||||
'error',
|
||||
'as-needed',
|
||||
{
|
||||
requireReturnForObjectLiteral: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@ -1,15 +0,0 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
// Disabled
|
||||
|
||||
// Unicorn
|
||||
|
||||
// Canonical
|
||||
|
||||
// Ignore
|
||||
'@next/next/link-passhref': 'off',
|
||||
'@next/next/no-script-in-document': 'off',
|
||||
'@next/next/no-script-in-head': 'off',
|
||||
'@next/next/no-server-import-in-page': 'off',
|
||||
},
|
||||
};
|
||||
4
rules/react.js
vendored
4
rules/react.js
vendored
@ -1,7 +1,7 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
name: 'React rules override',
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'react/jsx-sort-props': 'off',
|
||||
'react/function-component-definition': [
|
||||
'error',
|
||||
{
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
name: 'Sonar rules override',
|
||||
rules: {
|
||||
// Sonar
|
||||
'sonarjs/no-duplicate-string': 'warn',
|
||||
// fix
|
||||
'sonarjs/no-empty-function': 'off',
|
||||
'sonarjs/no-unused-expressions': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
// Disabled
|
||||
'@typescript-eslint/brace-style': 'off',
|
||||
'@typescript-eslint/comma-dangle': 'off',
|
||||
'@typescript-eslint/comma-spacing': 'off',
|
||||
'@typescript-eslint/func-call-spacing': 'off',
|
||||
'@typescript-eslint/indent': 'off',
|
||||
'@typescript-eslint/keyword-spacing': 'off',
|
||||
'@typescript-eslint/lines-between-class-members': 'off',
|
||||
'@typescript-eslint/member-delimiter-style': 'off',
|
||||
'@typescript-eslint/no-extra-parens': 'off',
|
||||
'@typescript-eslint/object-curly-spacing': 'off',
|
||||
'@typescript-eslint/padding-line-between-statements': 'off',
|
||||
'@typescript-eslint/quotes': 'off',
|
||||
'@typescript-eslint/semi': 'off',
|
||||
'@typescript-eslint/space-before-blocks': 'off',
|
||||
'@typescript-eslint/space-before-function-paren': 'off',
|
||||
'@typescript-eslint/space-infix-ops': 'off',
|
||||
'@typescript-eslint/type-annotation-spacing': 'off',
|
||||
|
||||
// Config
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-member-accessibility': [
|
||||
'warn',
|
||||
{
|
||||
accessibility: 'explicit',
|
||||
overrides: {
|
||||
constructors: 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/naming-convention': 'warn',
|
||||
|
||||
// Unicorn
|
||||
|
||||
// Canonical
|
||||
},
|
||||
};
|
||||
@ -1,30 +0,0 @@
|
||||
const { resolve } = require('node:path');
|
||||
|
||||
const project = resolve(process.cwd(), 'tsconfig.json');
|
||||
|
||||
/**
|
||||
* @param {'next'|'next-typescript'|'react'|'react-typescript'|'typescript'} name
|
||||
* @param {import('eslint').Linter.Config} overrideConfig
|
||||
*/
|
||||
function createConfig(name, overrideConfig) {
|
||||
return {
|
||||
extends: [
|
||||
`@vchikalkin/eslint-config-awesome/${name}/config`,
|
||||
`@vchikalkin/eslint-config-awesome/${name}/rules`,
|
||||
],
|
||||
parserOptions: {
|
||||
project,
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: {
|
||||
project,
|
||||
},
|
||||
},
|
||||
},
|
||||
ignorePatterns: ['node_modules/', 'dist/'],
|
||||
...overrideConfig,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = createConfig;
|
||||
Loading…
x
Reference in New Issue
Block a user