Skip to content

Commit 8e1664f

Browse files
JoshuaKGoldbergjoeeames
authored andcommitted
chore: updated ESLint to v9 with flat config (nodejs#7032)
* chore: updated ESLint to v9 with flat config * chore: missed an .eslintjscache
1 parent d668f31 commit 8e1664f

15 files changed

+1000
-190
lines changed

.github/workflows/lint-and-tests.yml

-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ jobs:
8282
.turbo/cache
8383
node_modules/.cache
8484
.eslintmdcache
85-
.eslintjscache
8685
.stylelintcache
8786
.prettiercache
8887
# We want to restore Turborepo Cache and ESlint and Prettier Cache
@@ -136,7 +135,6 @@ jobs:
136135
.turbo/cache
137136
node_modules/.cache
138137
.eslintmdcache
139-
.eslintjscache
140138
.stylelintcache
141139
.prettiercache
142140
key: cache-lint-${{ hashFiles('package-lock.json') }}-${{ hashFiles('.turbo/cache/**') }}

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ build-storybook.log
2424
cache
2525

2626
# Cache Files
27-
.eslintjscache
2827
.eslintmdcache
2928
.stylelintcache
3029
.prettiercache

.prettierignore

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ build-storybook.log
2626
cache
2727

2828
# Cache Files
29-
.eslintjscache
3029
.eslintmdcache
3130
.stylelintcache
3231
.prettiercache

apps/site/.eslintignore

-18
This file was deleted.

apps/site/.eslintrc.json

-100
This file was deleted.

apps/site/.storybook/main.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import classNames from 'classnames';
21
import type { StorybookConfig } from '@storybook/nextjs';
2+
import classNames from 'classnames';
33

44
const rootClasses = classNames(
55
// note: this is hard-coded sadly as next/font can only be loaded within next.js context

apps/site/.storybook/preview.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { NextIntlClientProvider } from 'next-intl';
2-
31
import { withThemeByDataAttribute } from '@storybook/addon-themes';
4-
import { NotificationProvider } from '@/providers/notificationProvider';
5-
import { STORYBOOK_MODES, STORYBOOK_SIZES } from '@/.storybook/constants';
62
import type { Preview, ReactRenderer } from '@storybook/react';
3+
import { NextIntlClientProvider } from 'next-intl';
74

5+
import { STORYBOOK_MODES, STORYBOOK_SIZES } from '@/.storybook/constants';
86
import englishLocale from '@/i18n/locales/en.json';
7+
import { NotificationProvider } from '@/providers/notificationProvider';
98

109
import '../next.fonts';
1110
import '../styles/index.css';

apps/site/components/withChangelogModal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const WithChangelogModal: FC<WithChangelogModalProps> = ({
6262
}
6363
);
6464
}
65-
} catch (_) {
65+
} catch {
6666
throw new Error(`Failed to fetch changelog for, ${versionWithPrefix}`);
6767
}
6868
};

apps/site/components/withDownloadCategories.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const WithDownloadCategories: FC<PropsWithChildren> = async ({ children }) => {
1313
const t = await getTranslations();
1414
const releases = await getReleaseData();
1515

16+
// eslint-disable-next-line react-hooks/rules-of-hooks
1617
const { pathname } = useClientContext();
1718
const { page, category, subCategory } = getDownloadCategory(pathname);
1819

apps/site/eslint.config.js

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { fixupPluginRules } from '@eslint/compat';
2+
import { FlatCompat } from '@eslint/eslintrc';
3+
import js from '@eslint/js';
4+
import importX from 'eslint-plugin-import-x';
5+
import * as mdx from 'eslint-plugin-mdx';
6+
import noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';
7+
import react from 'eslint-plugin-react';
8+
import storybook from 'eslint-plugin-storybook';
9+
import tseslint from 'typescript-eslint';
10+
11+
const compat = new FlatCompat();
12+
const pluginToPatch = '@next/next';
13+
14+
const compatConfig = compat
15+
.config({
16+
extends: [
17+
// https://github.com/vercel/next.js/discussions/49337
18+
'plugin:@next/eslint-plugin-next/core-web-vitals',
19+
20+
// https://github.com/facebook/react/issues/28313
21+
'plugin:react-hooks/recommended',
22+
],
23+
})
24+
.map(entry => {
25+
if (Object.hasOwn(entry.plugins, pluginToPatch)) {
26+
entry.plugins[pluginToPatch] = fixupPluginRules(
27+
entry.plugins[pluginToPatch]
28+
);
29+
}
30+
31+
return entry;
32+
});
33+
34+
export default tseslint.config(
35+
{
36+
ignores: [
37+
'.next',
38+
'.swc',
39+
'.turbo',
40+
'build',
41+
'coverage',
42+
'global.d.ts',
43+
'junit.xml',
44+
'storybook-static/**',
45+
],
46+
},
47+
{
48+
extends: [
49+
js.configs.recommended,
50+
importX.flatConfigs.recommended,
51+
importX.flatConfigs.typescript,
52+
react.configs.flat['jsx-runtime'],
53+
...tseslint.configs.recommended,
54+
...compatConfig,
55+
],
56+
files: ['**/*.{js,md,mdx,mjs,ts,tsx}'],
57+
plugins: {
58+
'no-relative-import-paths': noRelativeImportPaths,
59+
},
60+
rules: {
61+
'@typescript-eslint/array-type': ['error', { default: 'generic' }],
62+
'@typescript-eslint/consistent-type-imports': 'error',
63+
'@typescript-eslint/no-require-imports': 'off',
64+
'import-x/namespace': 'off',
65+
'import-x/no-named-as-default-member': 'off',
66+
'import-x/no-unresolved': 'off',
67+
'import-x/order': [
68+
'error',
69+
{
70+
groups: [
71+
'builtin',
72+
'external',
73+
'internal',
74+
['sibling', 'parent'],
75+
'index',
76+
'unknown',
77+
],
78+
'newlines-between': 'always',
79+
alphabetize: {
80+
order: 'asc',
81+
caseInsensitive: true,
82+
},
83+
},
84+
],
85+
'no-relative-import-paths/no-relative-import-paths': [
86+
'warn',
87+
{ allowSameFolder: true, prefix: '@' },
88+
],
89+
},
90+
settings: {
91+
react: {
92+
version: 'detect',
93+
},
94+
},
95+
},
96+
{
97+
files: ['**/*.{md,mdx}'],
98+
extends: [mdx.configs.flat],
99+
rules: {
100+
'no-irregular-whitespace': 'off',
101+
'@next/next/no-img-element': 'off',
102+
103+
// https://github.com/typescript-eslint/typescript-eslint/issues/9860
104+
'@typescript-eslint/consistent-type-imports': 'off',
105+
},
106+
},
107+
{
108+
files: ['**/*.{mdx,tsx}'],
109+
rules: {
110+
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
111+
'react/no-unescaped-entities': 'off',
112+
'react/function-component-definition': [
113+
'error',
114+
{
115+
namedComponents: 'arrow-function',
116+
unnamedComponents: 'arrow-function',
117+
},
118+
],
119+
'no-restricted-syntax': [
120+
'error',
121+
{
122+
selector:
123+
"ImportDeclaration[source.value='react'][specifiers.0.type='ImportDefaultSpecifier']",
124+
message:
125+
'Default React import not allowed since we use the TypeScript jsx-transform. If you need a global type that collides with a React named export (such as `MouseEvent`), try using `globalThis.MouseHandler`',
126+
},
127+
{
128+
selector:
129+
"ImportDeclaration[source.value='react'] :matches(ImportNamespaceSpecifier)",
130+
message:
131+
'Named * React import is not allowed. Please import what you need from React with Named Imports',
132+
},
133+
],
134+
},
135+
},
136+
{
137+
files: ['.storybook/**', '**/*.mjs', '**/*.test.*'],
138+
rules: {
139+
'no-relative-import-paths/no-relative-import-paths': 'off',
140+
},
141+
},
142+
{
143+
files: ['components/**/*.stories.tsx'],
144+
extends: [...storybook.configs['flat/recommended']],
145+
}
146+
);

apps/site/layouts/Download.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import styles from './layouts.module.css';
1010
const DownloadLayout: FC<PropsWithChildren> = async ({ children }) => {
1111
const {
1212
frontmatter: { title, subtitle },
13+
// eslint-disable-next-line react-hooks/rules-of-hooks
1314
} = useClientContext();
1415

1516
return (

apps/site/package.json

+13-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"start": "cross-env NODE_NO_WARNINGS=1 next start",
2424
"deploy": "cross-env NEXT_PUBLIC_STATIC_EXPORT=true npm run build",
2525
"check-types": "tsc --noEmit",
26-
"lint:js": "eslint \"**/*.{js,mjs,ts,tsx}\" --cache --cache-strategy=content --cache-location=.eslintjscache",
26+
"lint:js": "eslint \"**/*.{js,mjs,ts,tsx}\"",
2727
"lint:md": "eslint \"**/*.md?(x)\" --cache --cache-strategy=content --cache-location=.eslintmdcache",
2828
"lint:css": "stylelint \"**/*.css\" --allow-empty-input --cache --cache-strategy=content --cache-location=.stylelintcache",
2929
"lint": "turbo run lint:md lint:js lint:css",
@@ -89,6 +89,8 @@
8989
"vfile-matter": "~5.0.0"
9090
},
9191
"devDependencies": {
92+
"@eslint/compat": "^1.1.1",
93+
"@next/eslint-plugin-next": "^14.2.8",
9294
"@storybook/addon-controls": "~8.2.7",
9395
"@storybook/addon-interactions": "~8.2.7",
9496
"@storybook/addon-themes": "~8.2.7",
@@ -101,14 +103,16 @@
101103
"@types/react": "^18.3.5",
102104
"@types/react-dom": "^18.3.0",
103105
"@types/semver": "~7.5.8",
104-
"@typescript-eslint/eslint-plugin": "7.11.0",
105-
"@typescript-eslint/parser": "7.11.0",
106-
"eslint": "8.57.0",
106+
"eslint": "^9.9.1",
107107
"eslint-config-next": "~14.2.3",
108108
"eslint-config-prettier": "9.1.0",
109+
"eslint-import-resolver-typescript": "^3.6.3",
110+
"eslint-plugin-import-x": "^4.2.1",
109111
"eslint-plugin-mdx": "3.1.5",
110112
"eslint-plugin-no-relative-import-paths": "^1.5.3",
111-
"eslint-plugin-storybook": "0.8.0",
113+
"eslint-plugin-react": "^7.35.2",
114+
"eslint-plugin-react-hooks": "5.1.0-rc-4c58fce7-20240904",
115+
"eslint-plugin-storybook": "0.9.0--canary.156.da7873a.0",
112116
"handlebars": "4.7.8",
113117
"jest": "29.7.0",
114118
"jest-environment-jsdom": "29.7.0",
@@ -120,6 +124,10 @@
120124
"stylelint-config-standard": "36.0.0",
121125
"stylelint-order": "6.0.4",
122126
"stylelint-selector-bem-pattern": "4.0.0",
127+
"typescript-eslint": "^8.4.0",
123128
"user-agent-data-types": "0.4.2"
129+
},
130+
"overrides": {
131+
"eslint": "$eslint"
124132
}
125133
}

0 commit comments

Comments
 (0)