Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/gentle-taxis-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eddeee888/eslint-plugin': major
---

Convert to flat config
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"devDependencies": {
"@changesets/cli": "2.27.1",
"@eslint/js": "9.37.0",
"@graphql-codegen/cli": "5.0.0",
"@nx/devkit": "20.3.0",
"@nx/eslint": "20.3.0",
Expand All @@ -24,11 +25,15 @@
"@swc-node/register": "1.9.2",
"@swc/cli": "0.3.14",
"@swc/core": "1.5.7",
"@types/eslint-plugin-jsx-a11y": "6.10.1",
"@types/jest": "29.5.14",
"@types/node": "22.10.5",
"@types/semver": "7.5.6",
"eslint": "9.37.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "7.0.0",
"graphql": "16.10.0",
"jest": "29.7.0",
"jsonc-eslint-parser": "2.4.0",
Expand Down
133 changes: 38 additions & 95 deletions packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,113 +4,56 @@ This plugin contains extendable ESLint configs.

## Installation

1. Install the plugin and TypeScript config

```
yarn add -DE eslint @eddeee888/eslint-plugin @typescript-eslint/eslint-plugin @typescript-eslint/parser
```

2. Install React plugins - only if you are planning to work with React files

```
yarn add -DE eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
```bash
yarn add -DE eslint @eddeee888/eslint-plugin
```

## Usage

### Normal repo

```json
// .eslintrc.json
{
"plugins": ["@eddeee888"],
"parserOptions": {
"project": ["tsconfig.json"]
},
"overrides": [
{
// 👇 Omit ".tsx" if you don't use React TypeScript
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@eddeee888/typescript"],
"rules": {}
```js
// eslint.config.mjs
import { defineConfig } from 'eslint/config';
import ed from '@eddeee888/eslint-plugin';

export default defineConfig(
...ed.configs['base-typescript'],
...ed.configs.typescript,
...ed.configs['react-typescript'], // 👈 Omit this line if you don't use React TypeScript
{
languageOptions: {
parserOptions: {
projectService: true,
},
},
// 👇 Omit this block if you don't use React TypeScript
{
"files": ["*.tsx"],
"extends": ["plugin:@eddeee888/react-typescript"],
"rules": {}
}
]
}
}
);
```

### Nx monorepo

```json
// Root .eslintrc.json
{
// ... other options
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"extends": [
"plugin:@nx/typescript",
// 👇 Add this line for TypeScript files
"plugin:@eddeee888/typescript"
],
"rules": {}
},
{
"files": ["*.tsx"],
"extends": [
"plugin:@nx/react-typescript",
// 👇 Add this line if you use React TypeScript
"plugin:@eddeee888/react-typescript"
],
"rules": {}
}
]
}

// Project .eslintrc.json
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
// ... other config
{
"files": ["*.ts", "*.tsx"],
// 👇 Add parserOptions.project that points to your project tsconfig.json file
"parserOptions": {
"project": ["pathto/project/tsconfig(.*)?.json"]
```js
// eslint.config.mjs
import { defineConfig } from 'eslint/config';
import nx from '@nx/eslint-plugin';
import ed from '@eddeee888/eslint-plugin';

export default defineConfig(
...nx.configs['flat/base'],
...nx.configs['flat/typescript'],
...nx.configs['flat/javascript'],
...ed.configs.typescript,
{
languageOptions: {
parserOptions: {
projectService: true,
},
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
],
"env": {
"jest": true
}
}

// (Optional) Choose files to lint by using `project.json` 's `lintFilePatterns`
//
// Sometimes, the patterns set in a project's .eslintrc.json may not work correctly,
// especially when running Nx CLI: `nx lint <project>`
// In such case, try using `lintFilePatterns` in the project's `project.json`
{
// ... other configs
"targets": {
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["{projectRoot}/app/**/*.tsx", "{projectRoot}/app/**/*.ts"]
}
},
},
{
ignores: ['**/dist', 'eslint.config.mjs'],
}
}
// Other configs below...
);
```
8 changes: 7 additions & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
"main": "./src/index.js",
"typings": "./src/index.d.ts",
"dependencies": {
"tslib": "^2.3.0"
"@eslint/js": "^9.37.0",
"eslint": "^9.0.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.0",
"tslib": "^2.4.1",
"typescript-eslint": "^8.46.1"
},
"publishConfig": {
"directory": "../../dist/packages/eslint-plugin"
Expand Down
17 changes: 17 additions & 0 deletions packages/eslint-plugin/src/configs/base-typescript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from 'eslint/config';
import * as eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export const baseTypescriptConfig = defineConfig(
{
name: '@eddeee888/eslint-plugin/base-typescript',
plugins: { '@typescript-eslint': tseslint.plugin },
languageOptions: {
parser: tseslint.parser,
ecmaVersion: 2020,
sourceType: 'module',
},
},
eslint.configs.recommended,
tseslint.configs.recommended
);
35 changes: 28 additions & 7 deletions packages/eslint-plugin/src/configs/react-typescript.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
export const reactTypescriptConfig = {
settings: { react: { version: 'detect' } },
plugins: ['jsx-a11y', 'react'],
extends: ['plugin:react-hooks/recommended', 'plugin:jsx-a11y/recommended'],
rules: {
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
import { defineConfig } from 'eslint/config';
import * as jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
import * as reactPlugin from 'eslint-plugin-react';
const reactHooksPlugin = require('eslint-plugin-react-hooks'); // We must use require() here because react-hooks is cjs, and import will use `default` instead of the cjs module.exports

export const reactTypescriptConfig = defineConfig(
{
name: '@eddeee888/eslint-plugin/react-typescript/hooks',
files: ['**/*.ts', '**/*.cts', '**/*.mts', '**/*.tsx', '**/*.js', '**/*.cjs', '**/*.mjs', '**/*.jsx'],
plugins: {
'react-hooks': reactHooksPlugin,
},
rules: reactHooksPlugin.configs.recommended.rules,
},
};
{
name: '@eddeee888/eslint-plugin/react-typescript/react',
files: ['**/*.ts', '**/*.cts', '**/*.mts', '**/*.tsx', '**/*.js', '**/*.cjs', '**/*.mjs', '**/*.jsx'],
settings: { react: { version: 'detect' } },
plugins: {
'jsx-a11y': jsxA11yPlugin,
react: reactPlugin,
},
rules: {
...jsxA11yPlugin.flatConfigs.recommended.rules,
...reactPlugin.configs.recommended.rules,
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
},
}
);
15 changes: 6 additions & 9 deletions packages/eslint-plugin/src/configs/typescript.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
export const typescriptConfig = {
plugins: ['@typescript-eslint'],
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
import { defineConfig } from 'eslint/config';

export const typescriptConfig = defineConfig({
name: '@eddeee888/eslint-plugin/typescript',
files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'],
rules: {
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/await-thenable': 'error',
Expand All @@ -29,4 +26,4 @@ export const typescriptConfig = {
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
},
};
});
14 changes: 8 additions & 6 deletions packages/eslint-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { baseTypescriptConfig } from './configs/base-typescript';
import { typescriptConfig } from './configs/typescript';
import { reactTypescriptConfig } from './configs/react-typescript';

module.exports = {
configs: {
typescript: typescriptConfig,
['react-typescript']: reactTypescriptConfig,
},
rules: {},
export const configs = {
['base-typescript']: baseTypescriptConfig,
typescript: typescriptConfig,
['react-typescript']: reactTypescriptConfig,
};
export const rules = {};

export default { configs, rules };
Loading