Skip to content

Commit d5bd798

Browse files
author
Brijesh Bittu
committed
Make all config exports as factory functions
1 parent da2c6db commit d5bd798

File tree

10 files changed

+348
-322
lines changed

10 files changed

+348
-322
lines changed

eslint.config.mjs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { includeIgnoreFile } from '@eslint/compat';
22
import { defineConfig, globalIgnores } from 'eslint/config';
33
import * as path from 'node:path';
4-
import baseConfig from '@mui/infra/eslint';
5-
import testConfig from '@mui/infra/eslint-test';
4+
import { createBaseConfig, createTestConfig } from '@mui/infra/eslint';
65
import { fileURLToPath } from 'url';
76

87
const filename = fileURLToPath(import.meta.url);
@@ -14,7 +13,7 @@ export default defineConfig(
1413
globalIgnores(['packages/mui-infra/src/eslint/material-ui/rules/*.test.*'], 'Global ignores'),
1514
{
1615
name: 'Base config',
17-
extends: baseConfig,
16+
extends: createBaseConfig(),
1817
settings: {
1918
'import/resolver': {
2019
typescript: {
@@ -35,7 +34,7 @@ export default defineConfig(
3534
// matching the pattern of the test runner
3635
'**/*.test.?(c|m)[jt]s?(x)',
3736
],
38-
extends: testConfig,
37+
extends: createTestConfig(),
3938
},
4039
{
4140
files: ['**/*.mjs'],

packages/mui-infra/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
"./eslint-docs": {
2323
"types": "./src/eslint/index.d.ts",
2424
"default": "./src/eslint/docs.mjs"
25-
},
26-
"./eslint-test": {
27-
"types": "./src/eslint/test.d.ts",
28-
"default": "./src/eslint/test.mjs"
2925
}
3026
},
3127
"dependencies": {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import type { ConfigArray } from 'typescript-eslint';
2+
3+
declare function createDocsConfig(): ConfigArray;
4+
5+
export { createDocsConfig };
Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1+
/**
2+
* This is an export on a separate path so that users of the package
3+
* can use this config optionally by installing the `@next/eslint-plugin-next` package.
4+
*/
15
import nextjs from '@next/eslint-plugin-next';
26
import * as tselint from 'typescript-eslint';
37

48
/**
5-
* @type {import('typescript-eslint').ConfigArray}
9+
* @returns {import('typescript-eslint').ConfigArray}
610
*/
7-
export default tselint.config(nextjs.flatConfig.recommended, {
8-
settings: {
9-
next: {
10-
rootDir: 'docs',
11+
export function createDocsConfig() {
12+
return tselint.config(nextjs.flatConfig.recommended, {
13+
settings: {
14+
next: {
15+
rootDir: 'docs',
16+
},
17+
},
18+
rules: {
19+
// We're not using the Image component at the moment
20+
'@next/next/no-img-element': 'off',
21+
'no-irregular-whitespace': ['error', { skipJSXText: true, skipStrings: true }],
1122
},
12-
},
13-
rules: {
14-
// We're not using the Image component at the moment
15-
'@next/next/no-img-element': 'off',
16-
'no-irregular-whitespace': ['error', { skipJSXText: true, skipStrings: true }],
17-
},
18-
});
23+
});
24+
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { ConfigArray } from 'typescript-eslint';
22

3-
declare const config: ConfigArray;
3+
type BaseConfigOptions = {
4+
enableReactCompiler?: boolean;
5+
};
46

5-
export default config;
7+
declare function createBaseConfig(options?: BaseConfigOptions): ConfigArray;
8+
declare function createTestConfig(): ConfigArray;
9+
10+
export { createBaseConfig, createTestConfig };
Lines changed: 138 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,156 @@
11
import prettier from 'eslint-config-prettier/flat';
22
import { flatConfigs as importFlatConfigs } from 'eslint-plugin-import';
3+
import mochaPlugin from 'eslint-plugin-mocha';
4+
import reactCompilerPlugin from 'eslint-plugin-react-compiler';
35
import { configs as reactHookConfigs } from 'eslint-plugin-react-hooks';
6+
import testingLibrary from 'eslint-plugin-testing-library';
47
import globals from 'globals';
58
import * as tseslint from 'typescript-eslint';
69

710
import airbnbBase from './airbnb/base.mjs';
811
import airbnbReact from './airbnb/react.mjs';
912
import airbnbTs from './airbnb/typescript.mjs';
1013

14+
import { createCoreConfig } from './material-ui/config.mjs';
1115
import muiPlugin from './material-ui/index.mjs';
12-
import muiConfig from './material-ui/config.mjs';
16+
17+
export const specBaseRules = {
18+
files: ['**/*.spec.*'],
19+
rules: {
20+
'no-alert': 'off',
21+
'no-console': 'off',
22+
'no-empty-pattern': 'off',
23+
'no-lone-blocks': 'off',
24+
'no-shadow': 'off',
25+
26+
'@typescript-eslint/no-unused-expressions': 'off',
27+
'@typescript-eslint/no-unused-vars': 'off',
28+
'@typescript-eslint/no-use-before-define': 'off',
29+
30+
'import/prefer-default-export': 'off',
31+
32+
'jsx-a11y/anchor-has-content': 'off',
33+
'jsx-a11y/anchor-is-valid': 'off',
34+
'jsx-a11y/tabindex-no-positive': 'off',
35+
36+
'react/default-props-match-prop-types': 'off',
37+
'react/no-access-state-in-setstate': 'off',
38+
'react/no-unused-prop-types': 'off',
39+
'react/prefer-stateless-function': 'off',
40+
'react/prop-types': 'off',
41+
'react/require-default-props': 'off',
42+
'react/state-in-constructor': 'off',
43+
'react/static-property-placement': 'off',
44+
'react/function-component-definition': 'off',
45+
},
46+
};
1347

1448
/**
15-
* @type {import('typescript-eslint').ConfigArray}
49+
* @param {Object} [params]
50+
* @param {boolean} [params.enableReactCompiler] - Whether the config is for spec files.
51+
* @returns {import('typescript-eslint').ConfigArray}
1652
*/
17-
export default tseslint.config(
18-
importFlatConfigs.recommended,
19-
importFlatConfigs.typescript,
20-
reactHookConfigs.recommended,
21-
airbnbBase,
22-
airbnbReact,
23-
airbnbTs,
24-
prettier,
25-
{
26-
name: 'typescript-eslint-parser',
27-
languageOptions: {
28-
parser: tseslint.parser,
29-
ecmaVersion: 7,
30-
globals: {
31-
...globals.es2020,
32-
...globals.browser,
33-
...globals.node,
53+
export function createBaseConfig({ enableReactCompiler = false } = {}) {
54+
return tseslint.config(
55+
importFlatConfigs.recommended,
56+
importFlatConfigs.typescript,
57+
reactHookConfigs.recommended,
58+
enableReactCompiler ? reactCompilerPlugin.configs.recommended : {},
59+
airbnbBase,
60+
airbnbReact,
61+
airbnbTs,
62+
prettier,
63+
{
64+
name: 'typescript-eslint-parser',
65+
languageOptions: {
66+
parser: tseslint.parser,
67+
ecmaVersion: 7,
68+
globals: {
69+
...globals.es2020,
70+
...globals.browser,
71+
...globals.node,
72+
},
3473
},
74+
plugins: {
75+
'@typescript-eslint': tseslint.plugin,
76+
'material-ui': muiPlugin,
77+
},
78+
settings: {
79+
'import/parsers': {
80+
'@typescript-eslint/parser': ['.ts', '.tsx'],
81+
},
82+
},
83+
extends: createCoreConfig({ reactCompilerEnabled: enableReactCompiler }),
3584
},
36-
plugins: {
37-
'@typescript-eslint': tseslint.plugin,
38-
'material-ui': muiPlugin,
39-
},
40-
settings: {
41-
'import/parsers': {
42-
'@typescript-eslint/parser': ['.ts', '.tsx'],
85+
);
86+
}
87+
88+
/**
89+
* @returns {import('typescript-eslint').ConfigArray}
90+
*/
91+
export function createTestConfig() {
92+
return tseslint.config(
93+
mochaPlugin.configs.recommended,
94+
testingLibrary.configs['flat/dom'],
95+
testingLibrary.configs['flat/react'],
96+
{
97+
languageOptions: {
98+
parser: tseslint.parser,
99+
parserOptions: {
100+
ecmaVersion: 7,
101+
},
102+
globals: globals.mocha,
103+
},
104+
settings: {
105+
'import/resolver': {
106+
typescript: {
107+
project: ['tsconfig.node.json', 'apps/*/tsconfig.json', 'packages/*/tsconfig.json'],
108+
},
109+
},
110+
},
111+
rules: {
112+
// does not work with wildcard imports. Mistakes will throw at runtime anyway
113+
'import/named': 'off',
114+
'material-ui/disallow-active-element-as-key-event-target': 'error',
115+
'mocha/consistent-spacing-between-blocks': 'off',
116+
117+
// upgraded level from recommended
118+
'mocha/no-pending-tests': 'error',
119+
120+
// no rationale provided in /recommended
121+
'mocha/no-mocha-arrows': 'off',
122+
// definitely a useful rule but too many false positives
123+
// due to `describeConformance`
124+
// "If you're using dynamically generated tests, you should disable this rule.""
125+
'mocha/no-setup-in-describe': 'off',
126+
// `beforeEach` for a single case is optimized for change
127+
// when we add a test we don't have to refactor the existing
128+
// test to `beforeEach`.
129+
// `beforeEach`+`afterEach` also means that the `beforeEach`
130+
// is cleaned up in `afterEach` if the test causes a crash
131+
'mocha/no-hooks-for-single-case': 'off',
132+
133+
// disable eslint-plugin-jsx-a11y
134+
// tests are not driven by assistive technology
135+
// add `jsx-a11y` rules once you encounter them in tests
136+
'jsx-a11y/click-events-have-key-events': 'off',
137+
'jsx-a11y/control-has-associated-label': 'off',
138+
'jsx-a11y/iframe-has-title': 'off',
139+
'jsx-a11y/label-has-associated-control': 'off',
140+
'jsx-a11y/mouse-events-have-key-events': 'off',
141+
'jsx-a11y/no-noninteractive-tabindex': 'off',
142+
'jsx-a11y/no-static-element-interactions': 'off',
143+
'jsx-a11y/tabindex-no-positive': 'off',
144+
145+
// In tests this is generally intended.
146+
'react/button-has-type': 'off',
147+
// They are accessed to test custom validator implementation with PropTypes.checkPropTypes
148+
'react/forbid-foreign-prop-types': 'off',
149+
// components that are defined in test are isolated enough
150+
// that they don't need type-checking
151+
'react/prop-types': 'off',
152+
'react/no-unused-prop-types': 'off',
43153
},
44154
},
45-
extends: muiConfig,
46-
},
47-
);
155+
);
156+
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import type { InfiniteDepthConfigWithExtends } from 'typescript-eslint';
22

3-
declare const config: InfiniteDepthConfigWithExtends[];
4-
export default config;
3+
type BaseConfigOptions = {
4+
reactCompilerEnabled?: boolean;
5+
};
6+
7+
declare function createCoreConfig(options?: BaseConfigOptions): InfiniteDepthConfigWithExtends[];
8+
9+
export { createCoreConfig };

0 commit comments

Comments
 (0)