From 6d5bba5f6d10c90199453f4f23c1383745e9fb40 Mon Sep 17 00:00:00 2001 From: Rel1cx Date: Thu, 9 Oct 2025 17:21:38 +0800 Subject: [PATCH 1/3] Add strict config presets --- apps/website/content/docs/community.tsx | 1 + examples/next/eslint.config.js | 2 +- examples/next/package.json | 2 +- examples/react-dom/eslint.config.js | 2 +- .../eslint-plugin/src/configs/_strict.ts | 22 ++ .../src/configs/_type-checked.ts | 6 + .../eslint-plugin/src/configs/_typescript.ts | 9 + .../plugins/eslint-plugin/src/configs/dom.ts | 6 +- .../src/configs/strict-type-checked.ts | 19 ++ .../src/configs/strict-typescript.ts | 19 ++ .../plugins/eslint-plugin/src/configs/x.ts | 22 -- packages/plugins/eslint-plugin/src/index.ts | 11 + pnpm-lock.yaml | 245 +----------------- 13 files changed, 96 insertions(+), 270 deletions(-) create mode 100644 packages/plugins/eslint-plugin/src/configs/_strict.ts create mode 100644 packages/plugins/eslint-plugin/src/configs/_type-checked.ts create mode 100644 packages/plugins/eslint-plugin/src/configs/_typescript.ts create mode 100644 packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts create mode 100644 packages/plugins/eslint-plugin/src/configs/strict-typescript.ts diff --git a/apps/website/content/docs/community.tsx b/apps/website/content/docs/community.tsx index 687add6e4..195e913d0 100644 --- a/apps/website/content/docs/community.tsx +++ b/apps/website/content/docs/community.tsx @@ -29,6 +29,7 @@ export const projects = [ { owner: "tisoap", repo: "react-flow-smart-edge" }, { owner: "toss", repo: "suspensive" }, { owner: "XYOracleNetwork", repo: "sdk-xyo-react-js" }, + { owner: "yjs", repo: "yjs-inspector" }, ]; export const presets = [ diff --git a/examples/next/eslint.config.js b/examples/next/eslint.config.js index 7e10ac9b4..bc7350e82 100644 --- a/examples/next/eslint.config.js +++ b/examples/next/eslint.config.js @@ -42,7 +42,7 @@ export default defineConfig([ { files: TSCONFIG.include, extends: [ - eslintReact.configs["recommended-type-checked"], + eslintReact.configs["strict-type-checked"], eslintPluginReactRefresh.configs.recommended, ], plugins: { diff --git a/examples/next/package.json b/examples/next/package.json index 3eb858886..2cbe463c6 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -15,7 +15,7 @@ "react-dom": "^19.2.0" }, "devDependencies": { - "@eslint-react/eslint-plugin": "2.0.6", + "@eslint-react/eslint-plugin": "workspace:*", "@eslint/compat": "^1.4.0", "@eslint/config-inspector": "^1.3.0", "@eslint/js": "^9.37.0", diff --git a/examples/react-dom/eslint.config.js b/examples/react-dom/eslint.config.js index a5a33f9d6..ce7fad225 100644 --- a/examples/react-dom/eslint.config.js +++ b/examples/react-dom/eslint.config.js @@ -53,7 +53,7 @@ export default defineConfig([ { files: TSCONFIG_APP.include, extends: [ - eslintReact.configs["recommended-type-checked"], + eslintReact.configs["strict-type-checked"], eslintPluginReactRefresh.configs.recommended, ], plugins: { diff --git a/packages/plugins/eslint-plugin/src/configs/_strict.ts b/packages/plugins/eslint-plugin/src/configs/_strict.ts new file mode 100644 index 000000000..2a381fc36 --- /dev/null +++ b/packages/plugins/eslint-plugin/src/configs/_strict.ts @@ -0,0 +1,22 @@ +import type { RuleConfig } from "@eslint-react/kit"; + +export const rules = { + "@eslint-react/jsx-no-iife": "error", + "@eslint-react/jsx-no-undef": "error", + "@eslint-react/no-children-prop": "warn", + "@eslint-react/no-class-component": "error", + "@eslint-react/no-misused-capture-owner-stack": "error", + "@eslint-react/no-unnecessary-key": "warn", + "@eslint-react/no-unnecessary-use-callback": "warn", + "@eslint-react/no-unnecessary-use-memo": "warn", + "@eslint-react/no-unstable-context-value": "warn", + "@eslint-react/no-unstable-default-props": "warn", + "@eslint-react/no-unused-props": "warn", + "@eslint-react/no-unused-state": "warn", + "@eslint-react/no-useless-fragment": "warn", + "@eslint-react/prefer-destructuring-assignment": "warn", + + "@eslint-react/dom/no-missing-button-type": "warn", + "@eslint-react/dom/no-missing-iframe-sandbox": "warn", + "@eslint-react/dom/no-unsafe-target-blank": "warn", +} as const satisfies Record; diff --git a/packages/plugins/eslint-plugin/src/configs/_type-checked.ts b/packages/plugins/eslint-plugin/src/configs/_type-checked.ts new file mode 100644 index 000000000..ee834fd9e --- /dev/null +++ b/packages/plugins/eslint-plugin/src/configs/_type-checked.ts @@ -0,0 +1,6 @@ +import type { RuleConfig } from "@eslint-react/kit"; + +export const rules = { + "@eslint-react/no-leaked-conditional-rendering": "warn", + "@eslint-react/no-unused-props": "warn", +} as const satisfies Record; diff --git a/packages/plugins/eslint-plugin/src/configs/_typescript.ts b/packages/plugins/eslint-plugin/src/configs/_typescript.ts new file mode 100644 index 000000000..8585253cc --- /dev/null +++ b/packages/plugins/eslint-plugin/src/configs/_typescript.ts @@ -0,0 +1,9 @@ +import type { RuleConfig } from "@eslint-react/kit"; + +export const rules = { + "@eslint-react/dom/no-string-style-prop": "off", + "@eslint-react/dom/no-unknown-property": "off", + "@eslint-react/jsx-no-duplicate-props": "off", + "@eslint-react/jsx-uses-react": "off", + "@eslint-react/jsx-uses-vars": "off", +} as const satisfies Record; diff --git a/packages/plugins/eslint-plugin/src/configs/dom.ts b/packages/plugins/eslint-plugin/src/configs/dom.ts index 63414781f..dfc06a93c 100644 --- a/packages/plugins/eslint-plugin/src/configs/dom.ts +++ b/packages/plugins/eslint-plugin/src/configs/dom.ts @@ -9,14 +9,14 @@ export const rules = { "@eslint-react/dom/no-find-dom-node": "error", "@eslint-react/dom/no-flush-sync": "error", "@eslint-react/dom/no-hydrate": "error", - "@eslint-react/dom/no-missing-button-type": "warn", - "@eslint-react/dom/no-missing-iframe-sandbox": "warn", + "@eslint-react/dom/no-missing-button-type": "off", + "@eslint-react/dom/no-missing-iframe-sandbox": "off", "@eslint-react/dom/no-namespace": "error", "@eslint-react/dom/no-render": "error", "@eslint-react/dom/no-render-return-value": "error", "@eslint-react/dom/no-script-url": "warn", "@eslint-react/dom/no-unsafe-iframe-sandbox": "warn", - "@eslint-react/dom/no-unsafe-target-blank": "warn", + "@eslint-react/dom/no-unsafe-target-blank": "off", "@eslint-react/dom/no-use-form-state": "error", "@eslint-react/dom/no-void-elements-with-children": "error", } as const satisfies Record; diff --git a/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts b/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts new file mode 100644 index 000000000..9deced5df --- /dev/null +++ b/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts @@ -0,0 +1,19 @@ +import type { RuleConfig } from "@eslint-react/kit"; + +import * as typeChecked from "./_type-checked"; +import * as strictTypescript from "./strict-typescript"; + +export const name = "@eslint-react/strict-type-checked"; + +export const rules = { + ...strictTypescript.rules, + ...typeChecked.rules, +} as const satisfies Record; + +export const plugins = { + ...strictTypescript.plugins, +}; + +export const settings = { + ...strictTypescript.settings, +}; diff --git a/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts b/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts new file mode 100644 index 000000000..bfb9727b8 --- /dev/null +++ b/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts @@ -0,0 +1,19 @@ +import type { RuleConfig } from "@eslint-react/kit"; + +import * as strict from "./_strict"; +import * as recommendedTypescript from "./recommended-typescript"; + +export const name = "@eslint-react/strict-typescript"; + +export const rules = { + ...recommendedTypescript.rules, + ...strict.rules, +} as const satisfies Record; + +export const plugins = { + ...recommendedTypescript.plugins, +}; + +export const settings = { + ...recommendedTypescript.settings, +}; diff --git a/packages/plugins/eslint-plugin/src/configs/x.ts b/packages/plugins/eslint-plugin/src/configs/x.ts index c11039d3f..cdfb064cf 100644 --- a/packages/plugins/eslint-plugin/src/configs/x.ts +++ b/packages/plugins/eslint-plugin/src/configs/x.ts @@ -7,10 +7,6 @@ export const name = "@eslint-react/x"; export const rules = { "@eslint-react/jsx-no-comment-textnodes": "warn", "@eslint-react/jsx-no-duplicate-props": "warn", - "@eslint-react/jsx-no-iife": "off", - "@eslint-react/jsx-no-undef": "off", - "@eslint-react/jsx-shorthand-boolean": "off", - "@eslint-react/jsx-shorthand-fragment": "off", "@eslint-react/jsx-uses-react": "warn", "@eslint-react/jsx-uses-vars": "warn", "@eslint-react/no-access-state-in-setstate": "error", @@ -19,9 +15,7 @@ export const rules = { "@eslint-react/no-children-for-each": "warn", "@eslint-react/no-children-map": "warn", "@eslint-react/no-children-only": "warn", - "@eslint-react/no-children-prop": "off", "@eslint-react/no-children-to-array": "warn", - "@eslint-react/no-class-component": "off", "@eslint-react/no-clone-element": "warn", "@eslint-react/no-component-will-mount": "error", "@eslint-react/no-component-will-receive-props": "error", @@ -31,14 +25,9 @@ export const rules = { "@eslint-react/no-default-props": "error", "@eslint-react/no-direct-mutation-state": "error", "@eslint-react/no-duplicate-key": "error", - "@eslint-react/no-forbidden-props": "off", "@eslint-react/no-forward-ref": "warn", "@eslint-react/no-implicit-key": "warn", - "@eslint-react/no-leaked-conditional-rendering": "off", - "@eslint-react/no-missing-component-display-name": "off", - "@eslint-react/no-missing-context-display-name": "off", "@eslint-react/no-missing-key": "error", - "@eslint-react/no-misused-capture-owner-stack": "off", "@eslint-react/no-nested-component-definitions": "error", "@eslint-react/no-nested-lazy-component-declarations": "error", "@eslint-react/no-prop-types": "error", @@ -47,24 +36,13 @@ export const rules = { "@eslint-react/no-set-state-in-component-did-update": "warn", "@eslint-react/no-set-state-in-component-will-update": "warn", "@eslint-react/no-string-refs": "error", - "@eslint-react/no-unnecessary-key": "off", - "@eslint-react/no-unnecessary-use-callback": "off", - "@eslint-react/no-unnecessary-use-memo": "off", "@eslint-react/no-unnecessary-use-prefix": "warn", "@eslint-react/no-unsafe-component-will-mount": "warn", "@eslint-react/no-unsafe-component-will-receive-props": "warn", "@eslint-react/no-unsafe-component-will-update": "warn", - "@eslint-react/no-unstable-context-value": "warn", - "@eslint-react/no-unstable-default-props": "warn", "@eslint-react/no-unused-class-component-members": "warn", - "@eslint-react/no-unused-props": "off", - "@eslint-react/no-unused-state": "warn", "@eslint-react/no-use-context": "warn", "@eslint-react/no-useless-forward-ref": "warn", - "@eslint-react/no-useless-fragment": "off", - "@eslint-react/prefer-destructuring-assignment": "off", - "@eslint-react/prefer-namespace-import": "off", - "@eslint-react/prefer-read-only-props": "off", "@eslint-react/prefer-use-state-lazy-initialization": "warn", } as const satisfies Record; diff --git a/packages/plugins/eslint-plugin/src/index.ts b/packages/plugins/eslint-plugin/src/index.ts index 419d27e00..5bbb1f56d 100644 --- a/packages/plugins/eslint-plugin/src/index.ts +++ b/packages/plugins/eslint-plugin/src/index.ts @@ -21,7 +21,10 @@ import * as offConfig from "./configs/off"; import * as recommendedConfig from "./configs/recommended"; import * as recommendedTypeCheckedConfig from "./configs/recommended-type-checked"; import * as recommendedTypeScriptConfig from "./configs/recommended-typescript"; +import * as strictTypeCheckedConfig from "./configs/strict-type-checked"; +import * as strictTypescriptConfig from "./configs/strict-typescript"; import * as xConfig from "./configs/x"; + import { padKeysLeft } from "./utils"; const plugin: CompatiblePlugin = { @@ -96,6 +99,14 @@ export default { * Same as the `recommended` preset but disables rules that can be enforced by TypeScript */ ["recommended-typescript"]: recommendedTypeScriptConfig, + /** + * More strict version of the `recommended-type-checked` preset + */ + ["strict-type-checked"]: strictTypeCheckedConfig, + /** + * More strict version of the `recommended-typescript` preset + */ + ["strict-typescript"]: strictTypescriptConfig, /** * Enable rules for `"react"` */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f3ed530e..c7238eb82 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -423,8 +423,8 @@ importers: version: 19.2.0(react@19.2.0) devDependencies: '@eslint-react/eslint-plugin': - specifier: 2.0.6 - version: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) + specifier: workspace:* + version: link:../../packages/plugins/eslint-plugin '@eslint/compat': specifier: ^1.4.0 version: 1.4.0(eslint@9.37.0(jiti@2.6.1)) @@ -2168,33 +2168,14 @@ packages: resolution: {integrity: sha512-i72EzCOYQo+CKnxKRPuguRM0FPIpA/ojDhK0XZI++nO6fG67ggKMSf2DZTIbScus30GsluhaYLpN8R2rppeVJA==} engines: {node: '>=20.19.0'} - '@eslint-react/core@2.0.6': - resolution: {integrity: sha512-VbyrfHT3CK22WrYszjXR38tWudlkwDn1G72i/qArWIDppJCFCxfUfNvpM63TaPEUjY/fWWLfsDn9DWltpAvuYw==} - engines: {node: '>=20.19.0'} - '@eslint-react/eff@2.0.6': resolution: {integrity: sha512-hBXZg93uB8L8UxjAbgSMQA/27qKeNokXy3Dfkhr6I2gQ4A+IjdXBqbI6hHGlyxyGRmkUpk3RLDELZ/0uqqtysg==} engines: {node: '>=20.19.0'} - '@eslint-react/eslint-plugin@2.0.6': - resolution: {integrity: sha512-g+Wz8gr+J0rJVVr4y5DilXroPtZGart1phFWZtcuKPsdPEfINCEyHPzBrscOOzXFa26D5HKQOIxGb/IzYrjVSw==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - '@eslint-react/kit@2.0.6': resolution: {integrity: sha512-7Vz4GcKAsUVwpJMBBxEiHI/kXfUlTTTN71YGmvbgBsHpsXRQRQC1+yl3Q3FNsabd8909ww1eay2uIuigfVUkaQ==} engines: {node: '>=20.19.0'} - '@eslint-react/shared@2.0.6': - resolution: {integrity: sha512-yhRcipMwhzhYuJMWXHZVVnlAPntpMSUIvMtUYvplKeQvnEX+/awWobZSKqxWzB2QouBWSo5W3Sp2kb4vZonsig==} - engines: {node: '>=20.19.0'} - - '@eslint-react/var@2.0.6': - resolution: {integrity: sha512-fWx7HZ4vpm3woyoclxbtN/Swz7Qgm4LU3mYDs+pHj4ZSOvtqPCTOACMIFR/MwRwEWBAthUyMMZfxFpWz/8RJmA==} - engines: {node: '>=20.19.0'} - '@eslint/compat@1.4.0': resolution: {integrity: sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4682,59 +4663,17 @@ packages: peerDependencies: eslint: '>=8.45.0' - eslint-plugin-react-debug@2.0.6: - resolution: {integrity: sha512-uUqjSApa9nGQh9VEVktp7j4T/wK0WbJVQ5phHwcFQcSVOfEr9G6ISjpjFG/lJ70SIX3v3rAOrF7GvEZWA7MxcQ==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - - eslint-plugin-react-dom@2.0.6: - resolution: {integrity: sha512-PQzi+KksafJsoRN9gyM+a9JMJsvHxy6vCzr2c/eZvSluRDFxyWWwIRPCHijus0I8hlh0fyOOhR1S3DU2c05Zuw==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - - eslint-plugin-react-hooks-extra@2.0.6: - resolution: {integrity: sha512-Dg82EIM+4J+Ideb61Hc+vnwGS5icBVB+D2uqINqEngxmDCDhubM+zTsjYJd9qeuiAQ3e7qM8A1GPHkHyrGW5bQ==} - engines: {node: '>=20.0.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - eslint-plugin-react-hooks@6.1.1: resolution: {integrity: sha512-St9EKZzOAQF704nt2oJvAKZHjhrpg25ClQoaAlHmPZuajFldVLqRDW4VBNAS01NzeiQF0m0qhG1ZA807K6aVaQ==} engines: {node: '>=18'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-naming-convention@2.0.6: - resolution: {integrity: sha512-BWgXnegBQU0GbOIvQRVKjXak//hOQLfiNXGO7vJ7MBN2DVEOEL8UK52YfxWW4dQYa7q4NNTqy7UOkK9sgpVw6g==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - eslint-plugin-react-refresh@0.4.23: resolution: {integrity: sha512-G4j+rv0NmbIR45kni5xJOrYvCtyD3/7LjpVH8MPPcudXDcNu8gv+4ATTDXTtbRR8rTCM5HxECvCSsRmxKnWDsA==} peerDependencies: eslint: '>=8.40' - eslint-plugin-react-web-api@2.0.6: - resolution: {integrity: sha512-NGH3mUJ/L3OD12g0RaNQP5ofripIFnVuGGbOrENw9ret6Q7XGNDALHjsLxYCmFJAcHXun0W4DKmH1mHm8hyrIQ==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - - eslint-plugin-react-x@2.0.6: - resolution: {integrity: sha512-x8i52RElVgIUxSneM4uC+nkQcBGEFkiXAD8/QgxBbrfm0VKZ1748IBuNrp7125Ubx3JDlqJfJz1iEPJCyhvdAA==} - engines: {node: '>=20.19.0'} - peerDependencies: - eslint: ^9.36.0 - typescript: ^5.9.3 - eslint-plugin-regexp@2.10.0: resolution: {integrity: sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==} engines: {node: ^18 || >=20} @@ -5509,6 +5448,7 @@ packages: lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -8056,46 +7996,8 @@ snapshots: - supports-color - typescript - '@eslint-react/core@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - birecord: 0.1.1 - ts-pattern: 5.8.0 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - '@eslint-react/eff@2.0.6': {} - '@eslint-react/eslint-plugin@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) - eslint-plugin-react-debug: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-react-dom: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-react-hooks-extra: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-react-naming-convention: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-react-web-api: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-react-x: 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@eslint-react/kit@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-react/eff': 2.0.6 @@ -8105,31 +8007,6 @@ snapshots: - supports-color - typescript - '@eslint-react/shared@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - ts-pattern: 5.8.0 - zod: 4.1.12 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - - '@eslint-react/var@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)': - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - ts-pattern: 5.8.0 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - '@eslint/compat@1.4.0(eslint@9.37.0(jiti@2.6.1))': dependencies: '@eslint/core': 0.16.0 @@ -10642,63 +10519,6 @@ snapshots: - supports-color - typescript - eslint-plugin-react-debug@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) - string-ts: 2.2.1 - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - eslint-plugin-react-dom@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - compare-versions: 6.1.1 - eslint: 9.37.0(jiti@2.6.1) - string-ts: 2.2.1 - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - eslint-plugin-react-hooks-extra@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) - string-ts: 2.2.1 - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - eslint-plugin-react-hooks@6.1.1(eslint@9.37.0(jiti@2.6.1)): dependencies: '@babel/core': 7.28.4 @@ -10709,69 +10529,10 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-naming-convention@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) - string-ts: 2.2.1 - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - eslint-plugin-react-refresh@0.4.23(eslint@9.37.0(jiti@2.6.1)): dependencies: eslint: 9.37.0(jiti@2.6.1) - eslint-plugin-react-web-api@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.37.0(jiti@2.6.1) - string-ts: 2.2.1 - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - eslint-plugin-react-x@2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - '@eslint-react/ast': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/core': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/eff': 2.0.6 - '@eslint-react/kit': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/shared': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@eslint-react/var': 2.0.6(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - compare-versions: 6.1.1 - eslint: 9.37.0(jiti@2.6.1) - is-immutable-type: 5.0.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) - string-ts: 2.2.1 - ts-api-utils: 2.1.0(typescript@5.9.3) - ts-pattern: 5.8.0 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - eslint-plugin-regexp@2.10.0(eslint@9.37.0(jiti@2.6.1)): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)) From a0760f2a4bdd2ec56809e3d68d92e71733398717 Mon Sep 17 00:00:00 2001 From: Rel1cx Date: Thu, 9 Oct 2025 17:38:41 +0800 Subject: [PATCH 2/3] Add strict presets and reorganize config files The commit adds new strict presets for both regular and TypeScript configurations while cleaning up the config file organization and naming. --- README.md | 9 +++++++++ apps/website/content/docs/presets.mdx | 9 +++++++++ packages/plugins/eslint-plugin/README.md | 13 +++++++++++-- .../src/configs/{_type-checked.ts => _tc.ts} | 0 .../src/configs/{_typescript.ts => _ts.ts} | 0 .../src/configs/recommended-type-checked.ts | 4 ++-- .../src/configs/recommended-typescript.ts | 7 ++----- .../src/configs/strict-type-checked.ts | 12 ++++++------ .../eslint-plugin/src/configs/strict-typescript.ts | 10 +++++----- .../src/configs/{_strict.ts => strict.ts} | 13 +++++++++++++ 10 files changed, 57 insertions(+), 20 deletions(-) rename packages/plugins/eslint-plugin/src/configs/{_type-checked.ts => _tc.ts} (100%) rename packages/plugins/eslint-plugin/src/configs/{_typescript.ts => _ts.ts} (100%) rename packages/plugins/eslint-plugin/src/configs/{_strict.ts => strict.ts} (81%) diff --git a/README.md b/README.md index a435ce62c..2cdffcdcb 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,9 @@ export default defineConfig([ Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects.\ _This preset includes the `x`, `dom`, and `web-api` presets._ +- `strict`\ + Same as the `recommended` preset but enables additional strict rules. + ### TypeScript Specialized - `recommended-typescript`\ @@ -135,6 +138,12 @@ export default defineConfig([ - `recommended-type-checked`\ Same as the `recommended-typescript` preset but enables additional rules that require type information. +- `strict-typescript`\ + Same as the `strict` preset but disables rules that can be enforced by TypeScript. + +- `strict-type-checked`\ + Same as the `strict-typescript` preset but enables additional rules that require type information. + ### Other - `disable-dom`\ diff --git a/apps/website/content/docs/presets.mdx b/apps/website/content/docs/presets.mdx index cac3f11a5..764f1d104 100644 --- a/apps/website/content/docs/presets.mdx +++ b/apps/website/content/docs/presets.mdx @@ -19,6 +19,9 @@ The following presets are available in `@eslint-react/eslint-plugin`: Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects.\ _This preset includes the `x`, `dom`, and `web-api` presets._ +- `strict`\ + Same as the `recommended` preset but enables additional strict rules. + ## TypeScript Specialized - `recommended-typescript`\ @@ -27,6 +30,12 @@ The following presets are available in `@eslint-react/eslint-plugin`: - `recommended-type-checked`\ Same as the `recommended-typescript` preset but enables additional rules that require type information. +- `strict-typescript`\ + Same as the `strict` preset but disables rules that can be enforced by TypeScript. + +- `strict-type-checked`\ + Same as the `strict-typescript` preset but enables additional rules that require type information. + ### Combined (beta) - `no-deprecated`\ diff --git a/packages/plugins/eslint-plugin/README.md b/packages/plugins/eslint-plugin/README.md index 49e89c16e..0411baaaa 100644 --- a/packages/plugins/eslint-plugin/README.md +++ b/packages/plugins/eslint-plugin/README.md @@ -127,6 +127,9 @@ export default defineConfig([ Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects.\ _This preset includes the `x`, `dom`, and `web-api` presets._ +- `strict`\ + Same as the `recommended` preset but enables additional strict rules. + ### TypeScript Specialized - `recommended-typescript`\ @@ -135,6 +138,12 @@ export default defineConfig([ - `recommended-type-checked`\ Same as the `recommended-typescript` preset but enables additional rules that require type information. +- `strict-typescript`\ + Same as the `strict` preset but disables rules that can be enforced by TypeScript. + +- `strict-type-checked`\ + Same as the `strict-typescript` preset but enables additional rules that require type information. + ### Other - `disable-dom`\ @@ -174,8 +183,8 @@ ESLint React is not affiliated with Meta Corporation or [facebook/react](https:/ Contributions are welcome! -Please follow our [contributing guidelines](https://github.com/Rel1cx/eslint-react/tree/main/.github/CONTRIBUTING.md). +Please follow our [contributing guidelines](https://github.com/Rel1cx/eslint-react/tree/add-strict-presets/.github/CONTRIBUTING.md). ## License -This project is licensed under the MIT License - see the [LICENSE](https://github.com/Rel1cx/eslint-react/tree/main/LICENSE) file for details. +This project is licensed under the MIT License - see the [LICENSE](https://github.com/Rel1cx/eslint-react/tree/add-strict-presets/LICENSE) file for details. diff --git a/packages/plugins/eslint-plugin/src/configs/_type-checked.ts b/packages/plugins/eslint-plugin/src/configs/_tc.ts similarity index 100% rename from packages/plugins/eslint-plugin/src/configs/_type-checked.ts rename to packages/plugins/eslint-plugin/src/configs/_tc.ts diff --git a/packages/plugins/eslint-plugin/src/configs/_typescript.ts b/packages/plugins/eslint-plugin/src/configs/_ts.ts similarity index 100% rename from packages/plugins/eslint-plugin/src/configs/_typescript.ts rename to packages/plugins/eslint-plugin/src/configs/_ts.ts diff --git a/packages/plugins/eslint-plugin/src/configs/recommended-type-checked.ts b/packages/plugins/eslint-plugin/src/configs/recommended-type-checked.ts index 649bc5b19..ca36a4d4d 100644 --- a/packages/plugins/eslint-plugin/src/configs/recommended-type-checked.ts +++ b/packages/plugins/eslint-plugin/src/configs/recommended-type-checked.ts @@ -1,13 +1,13 @@ import type { RuleConfig } from "@eslint-react/kit"; +import * as tc from "./_tc"; import * as recommendedTypeScript from "./recommended-typescript"; export const name = "@eslint-react/recommended-type-checked"; export const rules = { ...recommendedTypeScript.rules, - "@eslint-react/no-leaked-conditional-rendering": "warn", - "@eslint-react/no-unused-props": "warn", + ...tc.rules, } as const satisfies Record; export const plugins = { diff --git a/packages/plugins/eslint-plugin/src/configs/recommended-typescript.ts b/packages/plugins/eslint-plugin/src/configs/recommended-typescript.ts index ce441c91f..f1549bda3 100644 --- a/packages/plugins/eslint-plugin/src/configs/recommended-typescript.ts +++ b/packages/plugins/eslint-plugin/src/configs/recommended-typescript.ts @@ -1,16 +1,13 @@ import type { RuleConfig } from "@eslint-react/kit"; +import * as ts from "./_ts"; import * as recommended from "./recommended"; export const name = "@eslint-react/recommended-typescript"; export const rules = { ...recommended.rules, - "@eslint-react/dom/no-string-style-prop": "off", - "@eslint-react/dom/no-unknown-property": "off", - "@eslint-react/jsx-no-duplicate-props": "off", - "@eslint-react/jsx-uses-react": "off", - "@eslint-react/jsx-uses-vars": "off", + ...ts.rules, } as const satisfies Record; export const plugins = { diff --git a/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts b/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts index 9deced5df..b099320ae 100644 --- a/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts +++ b/packages/plugins/eslint-plugin/src/configs/strict-type-checked.ts @@ -1,19 +1,19 @@ import type { RuleConfig } from "@eslint-react/kit"; -import * as typeChecked from "./_type-checked"; -import * as strictTypescript from "./strict-typescript"; +import * as tc from "./_tc"; +import * as strictTypeScript from "./strict-typescript"; export const name = "@eslint-react/strict-type-checked"; export const rules = { - ...strictTypescript.rules, - ...typeChecked.rules, + ...strictTypeScript.rules, + ...tc.rules, } as const satisfies Record; export const plugins = { - ...strictTypescript.plugins, + ...strictTypeScript.plugins, }; export const settings = { - ...strictTypescript.settings, + ...strictTypeScript.settings, }; diff --git a/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts b/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts index bfb9727b8..94085fa2b 100644 --- a/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts +++ b/packages/plugins/eslint-plugin/src/configs/strict-typescript.ts @@ -1,19 +1,19 @@ import type { RuleConfig } from "@eslint-react/kit"; -import * as strict from "./_strict"; -import * as recommendedTypescript from "./recommended-typescript"; +import * as ts from "./recommended-typescript"; +import * as strict from "./strict"; export const name = "@eslint-react/strict-typescript"; export const rules = { - ...recommendedTypescript.rules, ...strict.rules, + ...ts.rules, } as const satisfies Record; export const plugins = { - ...recommendedTypescript.plugins, + ...strict.plugins, }; export const settings = { - ...recommendedTypescript.settings, + ...strict.settings, }; diff --git a/packages/plugins/eslint-plugin/src/configs/_strict.ts b/packages/plugins/eslint-plugin/src/configs/strict.ts similarity index 81% rename from packages/plugins/eslint-plugin/src/configs/_strict.ts rename to packages/plugins/eslint-plugin/src/configs/strict.ts index 2a381fc36..04314ee88 100644 --- a/packages/plugins/eslint-plugin/src/configs/_strict.ts +++ b/packages/plugins/eslint-plugin/src/configs/strict.ts @@ -1,6 +1,11 @@ import type { RuleConfig } from "@eslint-react/kit"; +import * as recommended from "./recommended"; + +export const name = "@eslint-react/strict"; + export const rules = { + ...recommended.rules, "@eslint-react/jsx-no-iife": "error", "@eslint-react/jsx-no-undef": "error", "@eslint-react/no-children-prop": "warn", @@ -20,3 +25,11 @@ export const rules = { "@eslint-react/dom/no-missing-iframe-sandbox": "warn", "@eslint-react/dom/no-unsafe-target-blank": "warn", } as const satisfies Record; + +export const plugins = { + ...recommended.plugins, +}; + +export const settings = { + ...recommended.settings, +}; From 7882773dd1c98f603b217c5e03a2929f7ca7343b Mon Sep 17 00:00:00 2001 From: Rel1cx Date: Fri, 10 Oct 2025 00:48:23 +0800 Subject: [PATCH 3/3] Mark beta presets in ESLint React docs --- apps/website/content/docs/presets.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/website/content/docs/presets.mdx b/apps/website/content/docs/presets.mdx index 764f1d104..213699153 100644 --- a/apps/website/content/docs/presets.mdx +++ b/apps/website/content/docs/presets.mdx @@ -19,7 +19,7 @@ The following presets are available in `@eslint-react/eslint-plugin`: Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects.\ _This preset includes the `x`, `dom`, and `web-api` presets._ -- `strict`\ +- `strict` (beta)\ Same as the `recommended` preset but enables additional strict rules. ## TypeScript Specialized @@ -30,10 +30,10 @@ The following presets are available in `@eslint-react/eslint-plugin`: - `recommended-type-checked`\ Same as the `recommended-typescript` preset but enables additional rules that require type information. -- `strict-typescript`\ +- `strict-typescript` (beta)\ Same as the `strict` preset but disables rules that can be enforced by TypeScript. -- `strict-type-checked`\ +- `strict-type-checked` (beta)\ Same as the `strict-typescript` preset but enables additional rules that require type information. ### Combined (beta)