Skip to content

Commit 353f09b

Browse files
committed
chore(ws): show ESLint errors from local rules on IDE
1 parent f23af69 commit 353f09b

File tree

8 files changed

+96
-11
lines changed

8 files changed

+96
-11
lines changed

workspaces/frontend/.eslintrc.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const noReactHookNamespace = require('./eslint-local-rules/no-react-hook-namespace');
2-
31
module.exports = {
42
parser: '@typescript-eslint/parser',
53
env: {
@@ -13,7 +11,7 @@ module.exports = {
1311
js: true,
1412
useJSXTextNode: true,
1513
project: './tsconfig.json',
16-
tsconfigRootDir: '.',
14+
tsconfigRootDir: __dirname,
1715
},
1816
// includes the typescript specific rules found here: https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#supported-rules
1917
plugins: [
@@ -24,6 +22,7 @@ module.exports = {
2422
'no-only-tests',
2523
'no-relative-import-paths',
2624
'prettier',
25+
'local-rules',
2726
],
2827
extends: [
2928
'eslint:recommended',
@@ -200,6 +199,17 @@ module.exports = {
200199
'no-lone-blocks': 'error',
201200
'no-lonely-if': 'error',
202201
'no-promise-executor-return': 'error',
202+
'no-restricted-imports': [
203+
'error',
204+
{
205+
paths: [
206+
{
207+
name: 'react-router',
208+
message: 'Use react-router-dom instead.',
209+
},
210+
],
211+
},
212+
],
203213
'no-restricted-globals': [
204214
'error',
205215
{
@@ -221,7 +231,8 @@ module.exports = {
221231
'symbol-description': 'error',
222232
yoda: 'error',
223233
'func-names': 'warn',
224-
'no-react-hook-namespace': 'error',
234+
'local-rules/no-react-hook-namespace': 'error',
235+
'local-rules/no-raw-react-router-hook': 'error',
225236
},
226237
overrides: [
227238
{
@@ -270,7 +281,20 @@ module.exports = {
270281
{
271282
files: ['**/*.{js,jsx,ts,tsx}'],
272283
rules: {
273-
'no-react-hook-namespace': 'error',
284+
'local-rules/no-react-hook-namespace': 'error',
285+
'local-rules/no-raw-react-router-hook': 'error',
286+
},
287+
},
288+
{
289+
files: ['.eslintrc.js'],
290+
parserOptions: {
291+
project: null,
292+
},
293+
},
294+
{
295+
files: ['eslint-local-rules/**/*.js'],
296+
rules: {
297+
'@typescript-eslint/no-require-imports': 'off',
274298
},
275299
},
276300
],
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
'no-react-hook-namespace': require('./no-react-hook-namespace'),
3+
'no-raw-react-router-hook': require('./no-raw-react-router-hook'),
4+
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module.exports = {
2+
meta: {
3+
type: 'problem',
4+
docs: {
5+
description: 'Disallow use of raw react-router-dom hooks. Use typed wrappers instead.',
6+
},
7+
messages: {
8+
avoidRawHook:
9+
'Use "{{typedHook}}" from `~/app/routerHelper` instead of raw React Router hook "{{rawHook}}".',
10+
},
11+
schema: [],
12+
},
13+
14+
create(context) {
15+
const forbiddenHooks = {
16+
useNavigate: 'useTypedNavigate',
17+
useParams: 'useTypedParams',
18+
useSearchParams: 'useTypedSearchParams',
19+
useLocation: 'useTypedLocation',
20+
};
21+
22+
return {
23+
ImportDeclaration(node) {
24+
if (node.source.value !== 'react-router-dom') {
25+
return;
26+
}
27+
28+
for (const specifier of node.specifiers) {
29+
if (
30+
specifier.type === 'ImportSpecifier' &&
31+
Object.prototype.hasOwnProperty.call(forbiddenHooks, specifier.imported.name)
32+
) {
33+
context.report({
34+
node: specifier,
35+
messageId: 'avoidRawHook',
36+
data: {
37+
rawHook: specifier.imported.name,
38+
typedHook: forbiddenHooks[specifier.imported.name],
39+
},
40+
});
41+
}
42+
}
43+
},
44+
};
45+
},
46+
};

workspaces/frontend/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

workspaces/frontend/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
"test:unit": "npm run test:jest -- --silent",
2525
"test:watch": "jest --watch",
2626
"test:coverage": "jest --coverage",
27-
"test:fix": "eslint --rulesdir eslint-local-rules --ext .js,.ts,.jsx,.tsx ./src --fix",
28-
"test:lint": "eslint --rulesdir eslint-local-rules --max-warnings 0 --ext .js,.ts,.jsx,.tsx ./src",
27+
"test:fix": "eslint --ext .js,.ts,.jsx,.tsx ./src --fix",
28+
"test:lint": "eslint --max-warnings 0 --ext .js,.ts,.jsx,.tsx ./src",
2929
"cypress:open": "cypress open --project src/__tests__/cypress",
3030
"cypress:open:mock": "CY_MOCK=1 CY_WS_PORT=9002 npm run cypress:open -- ",
3131
"cypress:run": "cypress run -b chrome --project src/__tests__/cypress",
@@ -106,6 +106,7 @@
106106
"@patternfly/react-tokens": "^6.2.0",
107107
"@types/js-yaml": "^4.0.9",
108108
"date-fns": "^4.1.0",
109+
"eslint-plugin-local-rules": "^3.0.2",
109110
"js-yaml": "^4.1.0",
110111
"npm-run-all": "^4.1.5",
111112
"react": "^18",

workspaces/frontend/src/app/NavSidebar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react';
2-
import { NavLink, useLocation } from 'react-router-dom';
2+
import { NavLink } from 'react-router-dom';
33
import {
44
Brand,
55
Nav,
@@ -9,11 +9,12 @@ import {
99
PageSidebar,
1010
PageSidebarBody,
1111
} from '@patternfly/react-core';
12+
import { useTypedLocation } from '~/app/routerHelper';
1213
import { useNavData, isNavDataGroup, NavDataHref, NavDataGroup } from './AppRoutes';
1314
import { isMUITheme, LOGO_LIGHT } from './const';
1415

1516
const NavHref: React.FC<{ item: NavDataHref }> = ({ item }) => {
16-
const location = useLocation();
17+
const location = useTypedLocation();
1718

1819
// With the redirect in place, we can now use a simple path comparison.
1920
const isActive = location.pathname === item.path;

workspaces/frontend/src/app/hooks/useCurrentRouteKey.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { useLocation, matchPath } from 'react-router-dom';
1+
import { matchPath } from 'react-router-dom';
22
import { AppRouteKey, AppRoutePaths } from '~/app/routes';
3+
import { useTypedLocation } from '~/app/routerHelper';
34

45
export function useCurrentRouteKey(): AppRouteKey | undefined {
5-
const location = useLocation();
6+
const location = useTypedLocation();
67
const { pathname } = location;
78

89
const matchEntries = Object.entries(AppRoutePaths) as [AppRouteKey, string][];

workspaces/frontend/src/app/routerHelper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable local-rules/no-raw-react-router-hook */
2+
13
import {
24
generatePath,
35
Location,

0 commit comments

Comments
 (0)