|
| 1 | +## v2.0.0 (TBD) |
| 2 | + |
| 3 | +### 💥 Breaking Changes |
| 4 | + |
| 5 | +**Target Environment Updates: Now ESM and ESLint Flat Config Only** |
| 6 | + |
| 7 | +- Drop support for CommonJS (CJS) module format, packages are now distributed only as ECMAScript Modules (ESM) |
| 8 | +- Drop support for ESLint legacy config system, packages now support only ESLint Flat Config (`eslint.config.js`) |
| 9 | +- Drop support for Node.js 16 and 18, minimum required version is now Node.js 20 |
| 10 | +- Drop support for ESLint 8, minimum required version is now ESLint 9.3.6 |
| 11 | +- Drop support for TypeScript 4, minimum required version is now TypeScript 5.9.2 |
| 12 | + |
| 13 | +**Removed Rules** |
| 14 | + |
| 15 | +| Rule | Replaced by | Reason | |
| 16 | +| :--------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :----------- | |
| 17 | +| react-x/avoid-shorthand-boolean | [`react-x/jsx-shorthand-boolean`](/docs/rules/jsx-shorthand-boolean) | consolidated | |
| 18 | +| react-x/avoid-shorthand-fragment | [`react-x/jsx-shorthand-fragment`](/docs/rules/jsx-shorthand-fragment) | consolidated | |
| 19 | +| react-x/ensure-forward-ref-using-ref | [`react-x/no-useless-forward-ref`](/docs/rules/no-useless-forward-ref) | renamed | |
| 20 | +| react-x/jsx-no-duplicate-props | [`react-x/jsx-no-duplicate-props`](/docs/rules/jsx-no-duplicate-props) | renamed | |
| 21 | +| react-x/no-comment-textnodes | [`react-x/jsx-no-comment-textnodes`](/docs/rules/jsx-no-comment-textnodes) | renamed | |
| 22 | +| react-x/no-complicated-conditional-rendering | | discontinued | |
| 23 | +| react-x/no-nested-components | [`react-x/no-nested-component-definitions`](/docs/rules/no-nested-component-definitions) | renamed | |
| 24 | +| react-x/prefer-react-namespace-import | [`react-x/prefer-namespace-import`](/docs/rules/prefer-namespace-import) | renamed | |
| 25 | +| react-x/prefer-shorthand-boolean | [`react-x/jsx-shorthand-boolean`](/docs/rules/jsx-shorthand-boolean) | consolidated | |
| 26 | +| react-x/prefer-shorthand-fragment | [`react-x/jsx-shorthand-fragment`](/docs/rules/jsx-shorthand-fragment) | consolidated | |
| 27 | +| react-x/use-jsx-vars | [`react-x/jsx-uses-vars`](/docs/rules/jsx-uses-vars) | renamed | |
| 28 | +| react-dom/no-children-in-void-dom-elements | [`react-dom/no-void-elements-with-children`](/docs/rules/dom-no-void-elements-with-children) | renamed | |
| 29 | +| react-hooks-extra/no-direct-set-state-in-use-layout-effect | [`react-hooks-extra/no-direct-set-state-in-use-effect`](/docs/rules/hooks-extra-no-direct-set-state-in-use-effect) | consolidated | |
| 30 | +| react-hooks-extra/no-unnecessary-use-callback | [`react-x/no-unnecessary-use-callback`](/docs/rules/no-unnecessary-use-callback) | relocated | |
| 31 | +| react-hooks-extra/no-unnecessary-use-memo | [`react-x/no-unnecessary-use-memo`](/docs/rules/no-unnecessary-use-memo) | relocated | |
| 32 | +| react-hooks-extra/no-unnecessary-use-prefix | [`react-x/no-unnecessary-use-prefix`](/docs/rules/no-unnecessary-use-prefix) | relocated | |
| 33 | +| react-hooks-extra/prefer-use-state-lazy-initialization | [`react-x/prefer-use-state-lazy-initialization`](/docs/rules/prefer-use-state-lazy-initialization) | relocated | |
| 34 | + |
| 35 | +**Removed Presets** |
| 36 | + |
| 37 | +| Preset | Replaced by | Reason | |
| 38 | +| :-------------------------------- | :------------ | :----------- | |
| 39 | +| `core` | `x` | renamed | |
| 40 | +| `core-legacy` | | discontinued | |
| 41 | +| `off-dom` | `disable-dom` | renamed | |
| 42 | +| `off-dom-legacy` | | discontinued | |
| 43 | +| `x-legacy` | | discontinued | |
| 44 | +| `dom-legacy` | | discontinued | |
| 45 | +| `web-api-legacy` | | discontinued | |
| 46 | +| `recommended-legacy` | | discontinued | |
| 47 | +| `recommended-typescript-legacy` | | discontinued | |
| 48 | +| `recommended-type-checked-legacy` | | discontinued | |
| 49 | + |
| 50 | +**Removed Settings** |
| 51 | + |
| 52 | +| Setting | Replaced by | Reason | |
| 53 | +| :--------------------- | :---------- | :----------- | |
| 54 | +| `additionalComponents` | | discontinued | |
| 55 | +| `additionalHooks` | | discontinued | |
| 56 | +| `skipImportCheck` | | discontinued | |
| 57 | + |
| 58 | +The rule implementations have been refactored to improve performance and maintainability. |
| 59 | + |
| 60 | +### ✨ New |
| 61 | + |
| 62 | +**Added the following new rules:** |
| 63 | + |
| 64 | +- `react-x/jsx-shorthand-boolean`: Enforces a consistent style for boolean attributes |
| 65 | +- `react-x/jsx-shorthand-fragment`: Enforces a consistent style for React Fragments |
| 66 | +- `react-x/no-forbidden-props`: Disallows specific props on components |
| 67 | +- `react-x/no-unnecessary-key`: Reports unnecessary `key` props on elements |
| 68 | +- `react-x/no-unused-props`: Reports unused props in components |
| 69 | +- `react-dom/no-string-style-prop`: Disallows string values for the `style` prop |
| 70 | +- `react-dom/prefer-namespace-import`: Enforces using a namespace import for `react-dom` |
| 71 | + |
| 72 | +**Added the following new rule to the `recommended-type-checked` preset:** |
| 73 | + |
| 74 | +- `react-x/no-unused-props`: Reports unused props in components |
| 75 | + |
| 76 | +**The following rules now support Codemod features:** |
| 77 | + |
| 78 | +- `react-x/no-component-did-update` |
| 79 | +- `react-x/no-component-will-receive-props` |
| 80 | +- `react-x/no-component-will-update` |
| 81 | +- `react-x/no-context-provider` |
| 82 | +- `react-x/no-forward-ref` |
| 83 | +- `react-x/no-string-refs` |
| 84 | + |
| 85 | +**The following rules now support auto-fix:** |
| 86 | + |
| 87 | +- `react-x/prefer-namespace-import` |
| 88 | +- `react-dom/prefer-namespace-import` |
| 89 | + |
| 90 | +**The following rules now support suggestion fixes:** |
| 91 | + |
| 92 | +- `react-dom/no-missing-button-type` |
| 93 | +- `react-dom/no-missing-iframe-sandbox` |
| 94 | +- `react-dom/no-unsafe-target-blank` |
| 95 | + |
| 96 | +**New configuration preset added:** |
| 97 | + |
| 98 | +- `disable-conflict-eslint-plugin-react`: Disable rules in `eslint-plugin-react` that conflict with rules in our plugins |
| 99 | + |
| 100 | +### 🐞 Fixes |
| 101 | + |
| 102 | +- fix(react-x/no-unnecessary-use-prefix): fix false positive of React Hooks defined within the callback function of `vi.mock(...)` in Vitest test files |
| 103 | +- fix(react-web-api/no-leaked-event-listener): fix `useEffect` setup function check to handle `React.useEffect()` calls correctly |
| 104 | +- fix(react-naming-convention/filename): fix false positive on well-known filenames like `404.tsx`, `_app.tsx`, `[slug].tsx` |
| 105 | + |
| 106 | +### 🪄 Improvements |
| 107 | + |
| 108 | +- refactor: simplify React APIs detection logic |
| 109 | +- refactor: cleanup utilities and simplify rule implementations |
| 110 | +- docs: add comparison table between `eslint-plugin-react` and `eslint-react` rules |
| 111 | +- docs: replace `tseslint.config` with `defineConfig` in all examples |
| 112 | +- build: migrate build system from `tsup` to `tsdown` for better performance |
| 113 | + |
| 114 | +**Full Changelog**: https://github.com/Rel1cx/eslint-react/compare/v1.53.1...v2.0.0 |
| 115 | + |
1 | 116 | ## v1.53.1 (2025-09-11) |
2 | 117 |
|
3 | 118 | ### 🐞 Fixes |
|
0 commit comments