Skip to content

Commit 1859245

Browse files
pipopotamasumeta-codesync[bot]
authored andcommitted
Add support for Flat Config (eslint v9) (#54297)
Summary: Implements: #42996 Add support for Flat config (eslint v9) to `eslint-config-react-native`. To achieve this, I created `packages/eslint-config-react-native/flat.js` to export flat config as well as maintain legacy config for backward compatibility. I recognize we have had [the PR for supporting Flat config](#42996) already, but it looks stale and doesn't seem likely to move forward. That's why I created this PR. I also updated `eslint-plugin-react-native` and `eslint-plugin-specs` so that they comply with the current eslint plugin format. ## Changelog: [GENERAL] [ADDED] - Add support for Flat Config (eslint v9) Pull Request resolved: #54297 Test Plan: 1. Pull this branch into your local machine 2. `cd packages/eslint-config-react-native` 3. `yarn link` 4. Clone https://github.com/pipopotamasu/rn-eslint-config-test in your local machine 5. `cd path/to/rn-eslint-config-test` 6. `yarn install` 7. `yarn link "react-native/eslint-config"` 8. `yarn lint` 9. Confirm that eslint rules from `react-native/eslint-config` are applied <img width="1470" height="628" alt="image" src="https://github.com/user-attachments/assets/955fd655-8a79-4dd4-9031-e505d218d63a" /> Reviewed By: vzaidman Differential Revision: D85851077 Pulled By: huntie fbshipit-source-id: 9c78ecc4f5c3b10175a89417628b599735f95215
1 parent 8101b7f commit 1859245

File tree

11 files changed

+541
-335
lines changed

11 files changed

+541
-335
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
"eslint-plugin-jest": "^29.0.1",
8282
"eslint-plugin-jsx-a11y": "^6.6.0",
8383
"eslint-plugin-react": "^7.30.1",
84-
"eslint-plugin-react-native": "^4.0.0",
84+
"eslint-plugin-react-native": "^5.0.0",
8585
"eslint-plugin-redundant-undefined": "^0.4.0",
8686
"eslint-plugin-relay": "^1.8.3",
8787
"fb-dotslash": "0.5.8",

packages/eslint-config-react-native/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,32 @@ yarn add --dev eslint prettier @react-native/eslint-config
1212

1313
## Usage
1414

15+
### For ESLint 9+ (Flat Config)
16+
17+
Add to your `eslint.config.js`:
18+
19+
```javascript
20+
const reactNativeConfig = require('@react-native/eslint-config/flat');
21+
22+
module.exports = [
23+
...reactNativeConfig,
24+
// Your custom config here
25+
];
26+
```
27+
28+
Or with ES modules:
29+
30+
```javascript
31+
import reactNativeConfig from '@react-native/eslint-config/flat';
32+
33+
export default [
34+
...reactNativeConfig,
35+
// Your custom config here
36+
];
37+
```
38+
39+
### For ESLint 8 (Legacy Config)
40+
1541
Add to your eslint config (`.eslintrc`, or `eslintConfig` field in `package.json`):
1642

1743
```json
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @noflow
9+
*/
10+
11+
const sharedConfig = require('./shared.js');
12+
const babelParser = require('@babel/eslint-parser');
13+
const reactNativePlugin = require('@react-native/eslint-plugin');
14+
const typescriptPlugin = require('@typescript-eslint/eslint-plugin');
15+
const typescriptParser = require('@typescript-eslint/parser');
16+
const prettierConfig = require('eslint-config-prettier');
17+
const eslintCommentsPlugin = require('eslint-plugin-eslint-comments');
18+
const ftFlowPlugin = require('eslint-plugin-ft-flow');
19+
const jestPlugin = require('eslint-plugin-jest');
20+
const reactPlugin = require('eslint-plugin-react');
21+
const reactHooksPlugin = require('eslint-plugin-react-hooks');
22+
const reactNativeExternalPlugin = require('eslint-plugin-react-native');
23+
24+
// Convert globals from legacy format (true/false) to flat config format ('readonly'/'writable')
25+
const convertGlobals = globals => {
26+
const converted = {};
27+
for (const [key, value] of Object.entries(globals)) {
28+
converted[key] = value ? 'writable' : 'readonly';
29+
}
30+
return converted;
31+
};
32+
33+
// Flat Config for ESLint 9+
34+
module.exports = [
35+
// Apply prettier config first (to disable conflicting rules)
36+
prettierConfig,
37+
38+
// Base configuration for all files
39+
{
40+
languageOptions: {
41+
ecmaVersion: 'latest',
42+
sourceType: 'module',
43+
parserOptions: sharedConfig.parserOptions,
44+
globals: convertGlobals(sharedConfig.globals),
45+
},
46+
plugins: {
47+
'eslint-comments': eslintCommentsPlugin,
48+
react: reactPlugin,
49+
'react-hooks': reactHooksPlugin,
50+
'react-native': reactNativeExternalPlugin,
51+
'@react-native': reactNativePlugin,
52+
jest: jestPlugin,
53+
},
54+
settings: sharedConfig.settings,
55+
rules: sharedConfig.rules,
56+
},
57+
58+
// JavaScript files with Babel parser and Flow
59+
{
60+
...sharedConfig.overrides.flow,
61+
files: ['**/*.js'],
62+
languageOptions: {
63+
parser: babelParser,
64+
},
65+
plugins: {
66+
'ft-flow': ftFlowPlugin,
67+
},
68+
},
69+
70+
// JSX files with Babel parser
71+
{
72+
files: ['**/*.jsx'],
73+
languageOptions: {
74+
parser: babelParser,
75+
},
76+
},
77+
78+
// All JS/TS files - React Native specific rules
79+
{
80+
...sharedConfig.overrides.reactNative,
81+
files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
82+
},
83+
84+
// TypeScript files
85+
{
86+
...sharedConfig.overrides.typescript,
87+
files: ['**/*.ts', '**/*.tsx'],
88+
languageOptions: {
89+
parser: typescriptParser,
90+
parserOptions: {
91+
ecmaFeatures: {
92+
jsx: true,
93+
},
94+
},
95+
},
96+
plugins: {
97+
'@typescript-eslint': typescriptPlugin,
98+
},
99+
},
100+
101+
// Test files
102+
{
103+
...sharedConfig.overrides.jest,
104+
files: [
105+
'**/*.{spec,test}.{js,ts,tsx}',
106+
'**/__{mocks,tests}__/**/*.{js,ts,tsx}',
107+
],
108+
languageOptions: {
109+
globals: {
110+
...jestPlugin.environments.globals.globals,
111+
},
112+
},
113+
},
114+
];

0 commit comments

Comments
 (0)