Skip to content

Commit 6f18664

Browse files
authoredApr 23, 2024··
eslint-plugin-react-hooks: Add support for ESLint v9 (#28773)
1 parent a94838d commit 6f18664

File tree

6 files changed

+618
-91
lines changed

6 files changed

+618
-91
lines changed
 

‎packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js

+143-51
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
*
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-environment node
68
*/
79

810
'use strict';
911

10-
const ESLintTester = require('eslint').RuleTester;
12+
const ESLintTesterV7 = require('eslint-v7').RuleTester;
13+
const ESLintTesterV9 = require('eslint-v9').RuleTester;
1114
const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks');
1215
const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['exhaustive-deps'];
1316

@@ -4673,17 +4676,8 @@ const tests = {
46734676
return <div ref={myRef} />;
46744677
}
46754678
`,
4676-
output: `
4677-
function MyComponent() {
4678-
const myRef = useRef();
4679-
useLayoutEffect_SAFE_FOR_SSR(() => {
4680-
const handleMove = () => {};
4681-
myRef.current.addEventListener('mousemove', handleMove);
4682-
return () => myRef.current.removeEventListener('mousemove', handleMove);
4683-
});
4684-
return <div ref={myRef} />;
4685-
}
4686-
`,
4679+
// No changes
4680+
output: null,
46874681
errors: [
46884682
`The ref value 'myRef.current' will likely have changed by the time ` +
46894683
`this effect cleanup function runs. If this ref points to a node ` +
@@ -7101,6 +7095,19 @@ const tests = {
71017095
message:
71027096
"React Hook useEffect has a missing dependency: 'local'. " +
71037097
'Either include it or remove the dependency array.',
7098+
suggestions: [
7099+
{
7100+
desc: 'Update the dependencies array to be: [local]',
7101+
output: normalizeIndent`
7102+
function MyComponent() {
7103+
const local = {};
7104+
useEffect(() => {
7105+
console.log(local);
7106+
}, [local]);
7107+
}
7108+
`,
7109+
},
7110+
],
71047111
},
71057112
],
71067113
// Keep this until major IDEs and VS Code FB ESLint plugin support Suggestions API.
@@ -8217,30 +8224,45 @@ if (!process.env.CI) {
82178224
testsTypescript.invalid = testsTypescript.invalid.filter(predicate);
82188225
}
82198226

8220-
describe('react-hooks', () => {
8221-
const parserOptions = {
8227+
describe('rules-of-hooks/exhaustive-deps', () => {
8228+
const parserOptionsV7 = {
82228229
ecmaFeatures: {
82238230
jsx: true,
82248231
},
82258232
ecmaVersion: 6,
82268233
sourceType: 'module',
82278234
};
8235+
const languageOptionsV9 = {
8236+
ecmaVersion: 6,
8237+
sourceType: 'module',
8238+
parserOptions: {
8239+
ecmaFeatures: {
8240+
jsx: true,
8241+
},
8242+
},
8243+
};
82288244

82298245
const testsBabelEslint = {
82308246
valid: [...testsFlow.valid, ...tests.valid],
82318247
invalid: [...testsFlow.invalid, ...tests.invalid],
82328248
};
82338249

8234-
new ESLintTester({
8250+
new ESLintTesterV7({
82358251
parser: require.resolve('babel-eslint'),
8236-
parserOptions,
8237-
}).run('parser: babel-eslint', ReactHooksESLintRule, testsBabelEslint);
8252+
parserOptions: parserOptionsV7,
8253+
}).run(
8254+
'eslint: v7, parser: babel-eslint',
8255+
ReactHooksESLintRule,
8256+
testsBabelEslint
8257+
);
82388258

8239-
new ESLintTester({
8240-
parser: require.resolve('@babel/eslint-parser'),
8241-
parserOptions,
8259+
new ESLintTesterV9({
8260+
languageOptions: {
8261+
...languageOptionsV9,
8262+
parser: require('@babel/eslint-parser'),
8263+
},
82428264
}).run(
8243-
'parser: @babel/eslint-parser',
8265+
'eslint: v9, parser: @babel/eslint-parser',
82448266
ReactHooksESLintRule,
82458267
testsBabelEslint
82468268
);
@@ -8250,49 +8272,119 @@ describe('react-hooks', () => {
82508272
invalid: [...testsTypescript.invalid, ...tests.invalid],
82518273
};
82528274

8253-
new ESLintTester({
8275+
new ESLintTesterV7({
82548276
parser: require.resolve('@typescript-eslint/parser-v2'),
8255-
parserOptions,
8277+
parserOptions: parserOptionsV7,
8278+
}).run(
8279+
'eslint: v7, parser: @typescript-eslint/parser@2.x',
8280+
ReactHooksESLintRule,
8281+
testsTypescriptEslintParser
8282+
);
8283+
8284+
new ESLintTesterV9({
8285+
languageOptions: {
8286+
...languageOptionsV9,
8287+
parser: require('@typescript-eslint/parser-v2'),
8288+
},
82568289
}).run(
8257-
'parser: @typescript-eslint/parser@2.x',
8290+
'eslint: v9, parser: @typescript-eslint/parser@2.x',
82588291
ReactHooksESLintRule,
82598292
testsTypescriptEslintParser
82608293
);
82618294

8262-
new ESLintTester({
8295+
new ESLintTesterV7({
82638296
parser: require.resolve('@typescript-eslint/parser-v3'),
8264-
parserOptions,
8297+
parserOptions: parserOptionsV7,
82658298
}).run(
8266-
'parser: @typescript-eslint/parser@3.x',
8299+
'eslint: v7, parser: @typescript-eslint/parser@3.x',
82678300
ReactHooksESLintRule,
82688301
testsTypescriptEslintParser
82698302
);
82708303

8271-
new ESLintTester({
8304+
new ESLintTesterV9({
8305+
languageOptions: {
8306+
...languageOptionsV9,
8307+
parser: require('@typescript-eslint/parser-v3'),
8308+
},
8309+
}).run(
8310+
'eslint: v9, parser: @typescript-eslint/parser@3.x',
8311+
ReactHooksESLintRule,
8312+
testsTypescriptEslintParser
8313+
);
8314+
8315+
new ESLintTesterV7({
82728316
parser: require.resolve('@typescript-eslint/parser-v4'),
8273-
parserOptions,
8274-
}).run('parser: @typescript-eslint/parser@4.x', ReactHooksESLintRule, {
8275-
valid: [
8276-
...testsTypescriptEslintParserV4.valid,
8277-
...testsTypescriptEslintParser.valid,
8278-
],
8279-
invalid: [
8280-
...testsTypescriptEslintParserV4.invalid,
8281-
...testsTypescriptEslintParser.invalid,
8282-
],
8283-
});
8317+
parserOptions: parserOptionsV7,
8318+
}).run(
8319+
'eslint: v7, parser: @typescript-eslint/parser@4.x',
8320+
ReactHooksESLintRule,
8321+
{
8322+
valid: [
8323+
...testsTypescriptEslintParserV4.valid,
8324+
...testsTypescriptEslintParser.valid,
8325+
],
8326+
invalid: [
8327+
...testsTypescriptEslintParserV4.invalid,
8328+
...testsTypescriptEslintParser.invalid,
8329+
],
8330+
}
8331+
);
82848332

8285-
new ESLintTester({
8333+
new ESLintTesterV9({
8334+
languageOptions: {
8335+
...languageOptionsV9,
8336+
parser: require('@typescript-eslint/parser-v4'),
8337+
},
8338+
}).run(
8339+
'eslint: v9, parser: @typescript-eslint/parser@4.x',
8340+
ReactHooksESLintRule,
8341+
{
8342+
valid: [
8343+
...testsTypescriptEslintParserV4.valid,
8344+
...testsTypescriptEslintParser.valid,
8345+
],
8346+
invalid: [
8347+
...testsTypescriptEslintParserV4.invalid,
8348+
...testsTypescriptEslintParser.invalid,
8349+
],
8350+
}
8351+
);
8352+
8353+
new ESLintTesterV7({
82868354
parser: require.resolve('@typescript-eslint/parser-v5'),
8287-
parserOptions,
8288-
}).run('parser: @typescript-eslint/parser@^5.0.0-0', ReactHooksESLintRule, {
8289-
valid: [
8290-
...testsTypescriptEslintParserV4.valid,
8291-
...testsTypescriptEslintParser.valid,
8292-
],
8293-
invalid: [
8294-
...testsTypescriptEslintParserV4.invalid,
8295-
...testsTypescriptEslintParser.invalid,
8296-
],
8297-
});
8355+
parserOptions: parserOptionsV7,
8356+
}).run(
8357+
'eslint: v7, parser: @typescript-eslint/parser@^5.0.0-0',
8358+
ReactHooksESLintRule,
8359+
{
8360+
valid: [
8361+
...testsTypescriptEslintParserV4.valid,
8362+
...testsTypescriptEslintParser.valid,
8363+
],
8364+
invalid: [
8365+
...testsTypescriptEslintParserV4.invalid,
8366+
...testsTypescriptEslintParser.invalid,
8367+
],
8368+
}
8369+
);
8370+
8371+
new ESLintTesterV9({
8372+
languageOptions: {
8373+
...languageOptionsV9,
8374+
parser: require('@typescript-eslint/parser-v5'),
8375+
},
8376+
}).run(
8377+
'eslint: v9, parser: @typescript-eslint/parser@^5.0.0-0',
8378+
ReactHooksESLintRule,
8379+
{
8380+
valid: [
8381+
...testsTypescriptEslintParserV4.valid,
8382+
...testsTypescriptEslintParser.valid,
8383+
],
8384+
invalid: [
8385+
...testsTypescriptEslintParserV4.invalid,
8386+
...testsTypescriptEslintParser.invalid,
8387+
],
8388+
}
8389+
);
82988390
});

‎packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js

+22-11
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@
33
*
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-environment node
68
*/
79

810
'use strict';
911

10-
const ESLintTester = require('eslint').RuleTester;
12+
const ESLintTesterV7 = require('eslint-v7').RuleTester;
13+
const ESLintTesterV9 = require('eslint-v9').RuleTester;
1114
const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks');
15+
const BabelEslintParser = require('@babel/eslint-parser');
1216
const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['rules-of-hooks'];
1317

14-
ESLintTester.setDefaultConfig({
15-
parser: require.resolve('babel-eslint'),
16-
parserOptions: {
17-
ecmaVersion: 6,
18-
sourceType: 'module',
19-
},
20-
});
21-
2218
/**
2319
* A string template tag that removes padding from the left side of multi-line strings
2420
* @param {Array} strings array of code strings (only one expected)
@@ -1461,5 +1457,20 @@ if (!process.env.CI) {
14611457
tests.invalid = tests.invalid.filter(predicate);
14621458
}
14631459

1464-
const eslintTester = new ESLintTester();
1465-
eslintTester.run('react-hooks', ReactHooksESLintRule, tests);
1460+
describe('rules-of-hooks/rules-of-hooks', () => {
1461+
new ESLintTesterV7({
1462+
parser: require.resolve('babel-eslint'),
1463+
parserOptions: {
1464+
ecmaVersion: 6,
1465+
sourceType: 'module',
1466+
},
1467+
}).run('eslint: v7', ReactHooksESLintRule, tests);
1468+
1469+
new ESLintTesterV9({
1470+
languageOptions: {
1471+
parser: BabelEslintParser,
1472+
ecmaVersion: 6,
1473+
sourceType: 'module',
1474+
},
1475+
}).run('eslint: v9', ReactHooksESLintRule, tests);
1476+
});

‎packages/eslint-plugin-react-hooks/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@
2828
},
2929
"homepage": "https://react.dev/",
3030
"peerDependencies": {
31-
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
31+
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
3232
},
3333
"devDependencies": {
3434
"@babel/eslint-parser": "^7.11.4",
3535
"@typescript-eslint/parser-v2": "npm:@typescript-eslint/parser@^2.26.0",
3636
"@typescript-eslint/parser-v3": "npm:@typescript-eslint/parser@^3.10.0",
3737
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@^4.1.0",
3838
"@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.0.0-0",
39-
"babel-eslint": "^10.0.3"
39+
"babel-eslint": "^10.0.3",
40+
"eslint-v7": "npm:eslint@^7.7.0",
41+
"eslint-v9": "npm:eslint@^9.0.0"
4042
}
4143
}

0 commit comments

Comments
 (0)
Please sign in to comment.