Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ jobs:
- run:
name: TypeScript
command: pnpm typescript
- run:
name: JSON
command: pnpm code-infra jsonlint --silent
test_static:
<<: *default-job
steps:
Expand Down
15 changes: 4 additions & 11 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { defineConfig } from 'eslint/config';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
createBaseConfig,
createTestConfig,
Expand All @@ -9,15 +7,10 @@ import {
} from '@mui/internal-code-infra/eslint';
import nPlugin from 'eslint-plugin-n';

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

export default defineConfig(
createBaseConfig({ baseDirectory: import.meta.dirname }),
{
name: 'Base config',
extends: createBaseConfig({
baseDirectory: dirname,
}),
files: [`**/*.${EXTENSION_TS}`],
plugins: {
n: nPlugin,
},
Expand All @@ -42,7 +35,7 @@ export default defineConfig(
{
files: [
// matching the pattern of the test runner
`**/*${EXTENSION_TEST_FILE}`,
`**/*.${EXTENSION_TEST_FILE}`,
],
extends: createTestConfig(),
},
Expand All @@ -59,7 +52,7 @@ export default defineConfig(
},
},
{
files: ['packages/bundle-size-checker/**/*'],
files: [`packages/bundle-size-checker/**/*.${EXTENSION_TS}`],
rules: {
// Allow .js file extensions in import statements for ESM compatibility
'import/extensions': [
Expand Down
1 change: 1 addition & 0 deletions packages/code-infra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@babel/preset-typescript": "^7.27.1",
"@eslint/compat": "^1.3.2",
"@eslint/js": "^9.35.0",
"@eslint/json": "^0.13.2",
"@mui/internal-babel-plugin-display-name": "workspace:*",
"@mui/internal-babel-plugin-minify-errors": "workspace:*",
"@mui/internal-babel-plugin-resolve-imports": "workspace:*",
Expand Down
69 changes: 0 additions & 69 deletions packages/code-infra/src/cli/cmdJsonLint.mjs

This file was deleted.

2 changes: 0 additions & 2 deletions packages/code-infra/src/cli/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import cmdArgosPush from './cmdArgosPush.mjs';
import cmdBuild from './cmdBuild.mjs';
import cmdCopyFiles from './cmdCopyFiles.mjs';
import cmdExtractErrorCodes from './cmdExtractErrorCodes.mjs';
import cmdJsonLint from './cmdJsonLint.mjs';
import cmdListWorkspaces from './cmdListWorkspaces.mjs';
import cmdPublish from './cmdPublish.mjs';
import cmdPublishCanary from './cmdPublishCanary.mjs';
Expand All @@ -21,7 +20,6 @@ yargs()
.command(cmdBuild)
.command(cmdCopyFiles)
.command(cmdExtractErrorCodes)
.command(cmdJsonLint)
.command(cmdListWorkspaces)
.command(cmdPublish)
.command(cmdPublishCanary)
Expand Down
146 changes: 70 additions & 76 deletions packages/code-infra/src/eslint/baseConfig.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,94 +8,88 @@ import reactPlugin from 'eslint-plugin-react';
import { configs as reactCompilerPluginConfigs } from 'eslint-plugin-react-compiler';
import { configs as reactHookConfigs } from 'eslint-plugin-react-hooks';
import globals from 'globals';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as tseslint from 'typescript-eslint';

import { createCoreConfig } from './material-ui/config.mjs';
import muiPlugin from './material-ui/index.mjs';
import { EXTENSION_TS } from './extensions.mjs';
import { createJsonConfig } from './jsonConfig.mjs';
/**
* @param {Object} [params]
* @param {boolean} [params.enableReactCompiler] - Whether the config is for spec files.
* @param {string} params.baseDirectory - The base directory for the configuration.
* @param {string} [params.baseDirectory] - The base directory for the configuration.
* @returns {import('eslint').Linter.Config[]}
*/
export function createBaseConfig(
{ enableReactCompiler = false, baseDirectory } = { baseDirectory: process.cwd() },
) {
const ignoreRules = /** @type {import('@eslint/compat').FlatConfig[]} */ (
// All repos should use .lintignore going forward.
// .eslintignore is for backward compatibility. Should be removed in future.
['.gitignore', '.lintignore', '.eslintignore']
.map((file) => {
if (fs.existsSync(`${baseDirectory}/${file}`)) {
return includeIgnoreFile(path.join(baseDirectory, file), `Ignore rules from ${file}`);
}
return null;
})
.filter(Boolean)
);

return defineConfig(
...ignoreRules,
eslintJs.configs.recommended,
importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.react,
jsxA11yPlugin.flatConfigs.recommended,
reactPlugin.configs.flat.recommended,
reactHookConfigs.recommended,
tseslint.configs.recommended,
importPlugin.flatConfigs.typescript,
enableReactCompiler ? reactCompilerPluginConfigs.recommended : {},
export function createBaseConfig({
enableReactCompiler = false,
baseDirectory = process.cwd(),
} = {}) {
return defineConfig([
includeIgnoreFile(path.join(baseDirectory, '.lintignore'), `Ignore rules from .lintignore`),
createJsonConfig(),
prettier,
{
name: 'typescript-eslint-parser',
languageOptions: {
ecmaVersion: 7,
globals: {
...globals.es2020,
...globals.browser,
...globals.node,
files: [`**/*.${EXTENSION_TS}`],
extends: defineConfig([
eslintJs.configs.recommended,
importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.react,
jsxA11yPlugin.flatConfigs.recommended,
reactPlugin.configs.flat.recommended,
reactHookConfigs.recommended,
tseslint.configs.recommended,
importPlugin.flatConfigs.typescript,
enableReactCompiler ? reactCompilerPluginConfigs.recommended : {},
{
name: 'typescript-eslint-parser',
languageOptions: {
ecmaVersion: 7,
globals: {
...globals.es2020,
...globals.browser,
...globals.node,
},
},
plugins: {
'material-ui': muiPlugin,
},
extends: createCoreConfig({ reactCompilerEnabled: enableReactCompiler }),
},
},
plugins: {
'material-ui': muiPlugin,
},
extends: createCoreConfig({ reactCompilerEnabled: enableReactCompiler }),
},
{
files: ['**/*.mjs'],
rules: {
'import/extensions': [
'error',
'ignorePackages',
{
js: 'always',
mjs: 'always',
{
files: ['**/*.mjs'],
rules: {
'import/extensions': [
'error',
'ignorePackages',
{
js: 'always',
mjs: 'always',
},
],
},
],
},
},
// Lint rule to disallow usage of typescript namespaces.We've seen at least two problems with them:
// * Creates non-portable types in base ui. [1]
// * This pattern [2] leads to broken bundling in codesandbox [3].
// Gauging the ecosystem it also looks like support for namespaces in tooling is poor and tends to
// be treated as a deprecated feature.
// [1] https://github.com/mui/base-ui/pull/2324
// [2] https://github.com/mui/mui-x/blob/1cf853ed45cf301211ece1c0ca21981ea208edfb/packages/x-virtualizer/src/models/core.ts#L4-L10
// [3] https://codesandbox.io/embed/kgylpd?module=/src/Demo.tsx&fontsize=12
{
rules: {
'@typescript-eslint/no-namespace': 'error',
},
},
// Part of the migration away from airbnb config. Turned of initially.
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unsafe-function-type': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
},
},
// Lint rule to disallow usage of typescript namespaces.We've seen at least two problems with them:
// * Creates non-portable types in base ui. [1]
// * This pattern [2] leads to broken bundling in codesandbox [3].
// Gauging the ecosystem it also looks like support for namespaces in tooling is poor and tends to
// be treated as a deprecated feature.
// [1] https://github.com/mui/base-ui/pull/2324
// [2] https://github.com/mui/mui-x/blob/1cf853ed45cf301211ece1c0ca21981ea208edfb/packages/x-virtualizer/src/models/core.ts#L4-L10
// [3] https://codesandbox.io/embed/kgylpd?module=/src/Demo.tsx&fontsize=12
{
rules: {
'@typescript-eslint/no-namespace': 'error',
},
},
// Part of the migration away from airbnb config. Turned of initially.
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unsafe-function-type': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
},
},
]),
},
);
]);
}
4 changes: 2 additions & 2 deletions packages/code-infra/src/eslint/extensions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export const EXTENSION_TS = '?(c|m)[jt]s?(x)';
export const EXTENSION_TS_NO_MODULE = '[jt]s?(x)';
export const EXTENSION_TS_ONLY = '?(c|m)ts?(x)';
export const EXTENSION_TS_ONLY_NO_MODULE = 'ts?(x)';
export const EXTENSION_DTS = `.d.${EXTENSION_TS_ONLY}`;
export const EXTENSION_TEST_FILE = `.test.${EXTENSION_TS}`;
export const EXTENSION_DTS = `d.${EXTENSION_TS_ONLY}`;
export const EXTENSION_TEST_FILE = `test.${EXTENSION_TS}`;
34 changes: 34 additions & 0 deletions packages/code-infra/src/eslint/jsonConfig.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig } from 'eslint/config';
import json from '@eslint/json';

/**
* @returns {import('eslint').Linter.Config[]}
*/
export function createJsonConfig() {
return defineConfig([
// lint JSON files
{
files: ['**/*.json'],
ignores: ['package-lock.json'],
plugins: { json },
language: 'json/json',
extends: [json.configs.recommended],
},

// lint JSONC files
{
files: ['**/*.jsonc', '**/tsconfig.json', '**/tsconfig.*.json', '.vscode/**/*.json'],
plugins: { json },
language: 'json/jsonc',
extends: [json.configs.recommended],
},

// lint JSON5 files
{
files: ['**/*.json5'],
plugins: { json },
language: 'json/json5',
extends: [json.configs.recommended],
},
]);
}
Loading
Loading