Skip to content

Commit

Permalink
ESLint v9 support (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
zemd authored Dec 25, 2024
1 parent 5c65564 commit 263188c
Show file tree
Hide file tree
Showing 27 changed files with 502 additions and 479 deletions.
5 changes: 5 additions & 0 deletions .changeset/pretty-trains-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zemd/eslint-flat-config": major
---

supporting eslint v9
14 changes: 11 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
name: Release

permissions:
id-token: write
contents: write
packages: write
pull-requests: write
issues: read

on:
push:
branches:
Expand All @@ -21,16 +28,17 @@ jobs:
node-version: 20.x

- name: Setup bun
uses: oven-sh/setup-bun@v1
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1

- name: Install Dependencies
run: bun install

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
uses: changesets/action@c8bada60c408975afd1a20b3db81d6eee6789308 # v1.4.9
with:
publish: bun run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bun run format
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.8.1
22.11.0
365 changes: 201 additions & 164 deletions LICENSE

Large diffs are not rendered by default.

90 changes: 52 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,55 @@

[![npm](https://img.shields.io/npm/v/@zemd/eslint-flat-config?color=0000ff&label=npm&labelColor=000)](https://npmjs.com/package/@zemd/eslint-flat-config)


> [!WARNING]
> The package does not support ESLint v9 yet. Please use v8+ until all underlying plugins support new ESLint version.
![Alt](https://repobeats.axiom.co/api/embed/51fb05f4ccf63c09485cba8bd64c33aa00b7c025.svg "Repobeats analytics image")

- Easy,
- Helps to code and find bugs with only necessary rules, and less stress,
- Provides everything out of the box,
- Configurable
- Simple,
- Helps to code with less stress,
- Helps find bugs using only necessary rules,
- If needed includes additional configs for 3d party libraries out of the box,
- Configurable,
- **DOES NOT** sort imports,
- [ESLint Flat config](https://eslint.org/docs/latest/use/configure/configuration-files-new)
- Works with eslint v9+

## Usage

```sh
npm install eslint @zemd/eslint-flat-config --save-dev
npm install --save-dev eslint @zemd/eslint-flat-config
bun add --dev eslint @zemd/eslint-flat-config
# see more https://eslint.org/docs/latest/use/getting-started#manual-set-up
```

## Configuration

```typescript
// eslint.config.js
const { createEslintConfig } = require("@zemd/eslint-flat-config");
const { createESLintConfig } = require("@zemd/eslint-flat-config");
export default [
{
ignores: [".next/**", ".turbo/**", "node_modules/**"],
},
...createEslintConfig({
...createESLintConfig({
useNextjs: true,
useTailwind: true,
useTurbo: true,
}),
];
```

<!-- prettier-ignore -->
> [!NOTE]
> All groups of rules are named, so you can filter out by name if you want to disable some of the rules.
<!-- prettier-ignore -->
> [!NOTE]
> All optional rules are disabled by default. If you need you should explicitly enable it within `createESLintConfig({ ... })` options.
### Debug your rules

A fantastic tool called `eslint-flat-config-viewer` can show all your applied rules, display links to the documentation, and group rules by the provider. I recommend using it to dig deeper into your project's rules.
Debug your rules locally using [`@eslint/config-inspector`](https://github.com/eslint/config-inspector) package.

```bash
npx @eslint/config-inspector@latest
# or bunx @eslint/config-inspector@latest
```

## Goal

Expand All @@ -49,40 +59,44 @@ The purpose of this package is to develop confidently without pressure from tool
Some key points behind this package include:

- developer should not be blocked by the tool and should be able to use language features,
- no or minimum warnings, without compromises, just errors that don't mess up output,
- no or minimum warnings, without compromises, just errors that don't mess up output (still can be exist since recommended configs can include warnings),
- minimum formatting rules or none, this should be handled by formatter without blocking your flow,
- no configuration, plug the rules and start working; otherwise, override in your config,
- batteries included by default: typescript, prettier, react, nextjs, tailwind, vitest, playwright, storybook
- simple configuration, plug the rules and start working; otherwise, override in your config,
- batteries included by default: typescript, react, nextjs, tailwind, vitest, playwright, storybook etc.
- rules should not force you to use a specific programming style but help you catch bugs

## Rules

- Recommended rules from `@eslint/js`,
- **strict-type-checked** and **stylistic-type-checked** rules from `@typescript-eslint/eslint-plugin`
- Additional stylistic rules from `@typescript-eslint/eslint-plugin`
- Recommended rules from `eslint-plugin-sonarjs`
- Carefully hand-picked rules from `eslint-plugin-unicorn`
- Recommended rules from `eslint-plugin-jsx-a11y` and `eslint-plugin-react-hooks`
- Carefully hand-picked rules from `eslint-plugin-react`
- Single rule for **lodash** imports
- Recommended and **core-web-vitals** configs from `@next/eslint-plugin-next`
- Recommended rules from `eslint-plugin-playwright`
- Recommended rules from `eslint-plugin-vitest`
- Recommended rules from `eslint-config-prettier` that turn off rules which overlap with `@typescript-eslint` and prettier
- Recommended rules from `eslint-config-turbo`
### Enabled as recommended by default

- **Recommended** rules from `@eslint/js` (~61 rules),
- Carefully hand-picked additional rules from `@eslint/js` that were not included in the recommended set (~29 rules),
- Carefully hand-picked rules from `eslint-plugin-unicorn` avoiding some style relating rules (~70 rules)
- **Recommended** rules from `eslint-plugin-sonarjs` (~204 rules)
- Typescript support is covered by `typescript-eslint` importing **strict-type-checked** configs and configuring some rules (~73 rules)
- JSX and react.js is supported out of the box by leveraging `eslint-plugin-react`, `eslint-plugin-react-hooks`, `eslint-plugin-react-compiler` and `eslint-plugin-jsx-a11y` (~69 rules)

### Available as optional

- Storybook rules included using `eslint-plugin-storybook` package and `flat/recommended`, `flat/csf` and `flat/csf-strict` (~13 rules)
- **Recommended** and **core-web-vitals** configs from `@next/eslint-plugin-next` (~21 rules)
- **Recommended** rules from `eslint-plugin-playwright` (~24 rules)
- **Recommended** rules from `eslint-plugin-vitest` (~8 rules)
- **Recommended** rules from `eslint-config-turbo` (~1 rule)
- Tailwind **recommended** rules from unofficial `eslint-plugin-tailwindcss` except `tailwindcss/classnames-order`, since the official prettier plugin sorts classes differently. (~8 rules)
- GraphQL `schema-recommended` and `operations-recommended` rules from the `@graphql-eslint/eslint-plugin` (~46 rules)

## Inspirations and alternatives

- [Sheriff](https://www.eslint-config-sheriff.dev/) -- Great set of rules, but with some style restrictions
- [Antfu config](https://github.com/antfu/eslint-config) -- Another great set of rules
- [XO](https://github.com/spence-s/flat-xo) -- Flat version of popular set `xo`, still in beta, includes some restrictive rules that I don't always agree with
- [Sheriff](https://www.eslint-config-sheriff.dev/) -- Great set of rules, but with some style restrictions
- [Antfu config](https://github.com/antfu/eslint-config) -- Another great set of rules
- [XO](https://github.com/spence-s/flat-xo) -- Flat version of popular set `xo`, still in beta, includes some restrictive rules that I don't always agree with

## License
## License

The `@zemd/eslint-flat-config` is licensed under the LGPLv3 license.
The `@zemd/eslint-flat-config` is licensed under the Apache-2.0 license.

## Donate
## Donate

[![](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://www.patreon.com/red_rabbit)
[![](https://img.shields.io/static/v1?label=UNITED24&message=support%20Ukraine&color=blue)](https://u24.gov.ua/)

Binary file modified bun.lockb
Binary file not shown.
14 changes: 11 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import config from "./src/";
import { createESLintConfig } from "./src/";

export default [
...config
];
...createESLintConfig({
useStorybook: true,
useGraphQL: true,
useNextjs: true,
usePlaywright: true,
useTailwind: true,
useTurbo: true,
useVitest: true,
}),
];
69 changes: 37 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zemd/eslint-flat-config",
"version": "2.0.6",
"license": "LGPL-3.0-or-later",
"license": "Apache-2.0",
"description": "Shared zemd ESLint flat config",
"keywords": [
"eslint-config",
Expand All @@ -14,13 +14,13 @@
"email": "[email protected]",
"url": "https://codeandgin.co"
},
"homepage": "https://github.com/zemd/eslint-config",
"homepage": "https://github.com/zemd/eslint-flat-config",
"repository": {
"type": "git",
"url": "https://github.com/zemd/eslint-config.git"
"url": "https://github.com/zemd/eslint-flat-config.git"
},
"bugs": {
"url": "https://github.com/zemd/eslint-config/issues"
"url": "https://github.com/zemd/eslint-flat-config/issues"
},
"files": [
"dist"
Expand All @@ -39,44 +39,49 @@
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup",
"dev": "eslint-flat-config-viewer",
"release": "bun run build && changeset publish"
"dev": "bunx @eslint/config-inspector@latest",
"release": "bun run build && changeset publish",
"prepare": "husky",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"peerDependencies": {
"eslint": ">=8.53.0"
"eslint": ">=9.2.0"
},
"dependencies": {
"@eslint/js": "^8.57.0",
"@graphql-eslint/eslint-plugin": "^3.20.1",
"@next/eslint-plugin-next": "^14.1.1",
"@stylistic/eslint-plugin": "^1.6.3",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@eslint/js": "^9.17.0",
"@graphql-eslint/eslint-plugin": "^4.3.0",
"@next/eslint-plugin-next": "^15.1.2",
"@typescript-eslint/eslint-plugin": "^8.18.2",
"@typescript-eslint/experimental-utils": "^5.62.0",
"@typescript-eslint/parser": "^7.1.0",
"@typescript-eslint/parser": "^8.18.2",
"eslint-define-config": "^2.1.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-lodash-f": "^7.5.3",
"eslint-plugin-playwright": "^1.5.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-sonarjs": "^0.24.0",
"eslint-plugin-playwright": "^2.1.0",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-react-compiler": "^19.0.0-beta-b2e8e9c-20241220",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-sonarjs": "^3.0.1",
"eslint-plugin-sort-keys": "^2.3.5",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-tailwindcss": "^3.14.3",
"eslint-plugin-turbo": "^1.12.4",
"eslint-plugin-unicorn": "^51.0.1",
"eslint-plugin-vitest": "^0.3.22"
"eslint-plugin-storybook": "^0.11.1",
"eslint-plugin-tailwindcss": "^3.17.5",
"eslint-plugin-turbo": "^2.3.3",
"eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-vitest": "^0.5.4",
"typescript-eslint": "^8.18.2"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@swc/core": "^1.4.2",
"@types/eslint": "^8.56.5",
"@changesets/cli": "^2.27.11",
"@eslint/config-inspector": "^0.6.0",
"@swc/core": "^1.10.1",
"@types/eslint": "^9.6.1",
"@types/eslint__js": "^8.42.3",
"@types/node": "^20.11.24",
"@zemd/tsconfig": "^1.2.0",
"eslint": "^8.57.0",
"eslint-flat-config-viewer": "^0.1.11",
"tsup": "^8.0.2",
"typescript": "^5.3.3"
"@types/node": "^22.10.2",
"@zemd/tsconfig": "^1.3.0",
"eslint": "^9.17.0",
"husky": "^9.1.7",
"prettier": "^3.4.2",
"tsup": "^8.3.5",
"typescript": "^5.7.2"
}
}
22 changes: 7 additions & 15 deletions src/createEslintConfig.ts → src/createESLintConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,35 @@ import { type Linter } from "eslint";

import { rules as storybookRules } from "./features/storybook.js";
import { rules as reactjsRules } from "./features/reactjs.js";
import { rules as lodashRules } from "./features/lodash.js";
import { rules as nextjsRules } from "./features/nextjs.js";
import { rules as playwrightRules } from "./features/playwright.js";
import { rules as vitestRules } from "./features/vitest.js";
import { rules as turboRules } from "./features/turbo.js";
import { rules as tailwindRules } from "./features/tailwind.js";
import { rules as typescriptRules } from "./features/typescript.js";
import { rules as recommendedRules } from "./features/recommended.js";
import { rules as stylisticRules } from "./features/stylistic.js";
import { rules as graphqlRules } from "./features/graphql.js";

type CreateEslintConfigOptions = {
type CreateESLintConfigOptions = {
useStorybook: boolean;
useLodash: boolean;
useNextjs: boolean;
usePlaywright: boolean;
useVitest: boolean;
useTurbo: boolean;
useTailwind: boolean;
useAsFormatter: boolean;
useGraphQL: boolean;
};

export const createEslintConfig = (
opts: Partial<CreateEslintConfigOptions>
): Array<Linter.FlatConfig> => {
const options: CreateEslintConfigOptions = {
export const createESLintConfig = (
opts: Partial<CreateESLintConfigOptions>,
): Array<Linter.Config> => {
const options: CreateESLintConfigOptions = {
useStorybook: false,
useLodash: true,
useNextjs: false,
usePlaywright: false,
useVitest: true,
useTurbo: true,
useVitest: false,
useTurbo: false,
useTailwind: false,
useAsFormatter: false,
useGraphQL: false,
...opts,
};
Expand All @@ -47,9 +41,7 @@ export const createEslintConfig = (
...recommendedRules,
...typescriptRules,
...reactjsRules,
...(options.useAsFormatter ? stylisticRules : []),
...(options.useStorybook ? storybookRules : []),
...(options.useLodash ? lodashRules : []),
...(options.useNextjs ? nextjsRules : []),
...(options.usePlaywright ? playwrightRules : []),
...(options.useVitest ? vitestRules : []),
Expand Down
10 changes: 5 additions & 5 deletions src/features/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as graphql from "@graphql-eslint/eslint-plugin";

const GQL_FILES = ["**/*.{graphql,gql}"];

export const rules: Array<Linter.FlatConfig> = [
export const rules: Array<Linter.Config> = [
{
files: GQL_FILES,
plugins: {
Expand All @@ -14,14 +14,14 @@ export const rules: Array<Linter.FlatConfig> = [
parser: graphql,
},
},
// @ts-ignore
{
name: "graphql-schema:rules",
files: GQL_FILES,
...graphql.flatConfigs["schema-recommended"],
...graphql.configs["flat/schema-recommended"],
},
// @ts-ignore
{
name: "graphql-operations:rules",
files: GQL_FILES,
...graphql.flatConfigs["operations-recommended"],
...graphql.configs["flat/operations-recommended"],
},
];
Loading

0 comments on commit 263188c

Please sign in to comment.