MeshiTrack/packages/web/eslint.config.js

150 lines
4.2 KiB
JavaScript
Raw Permalink Normal View History

2026-03-27 14:50:34 +09:00
import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import nextPlugin from '@next/eslint-plugin-next';
import prettierRecommended from 'eslint-plugin-prettier/recommended';
export default tseslint.config(
{ ignores: ['.next/**', 'coverage/**'] },
...tseslint.configs.recommended,
// React flat config — uses JSX runtime transform (no need to import React)
reactPlugin.configs.flat['jsx-runtime'],
// React Hooks
{
plugins: { 'react-hooks': reactHooksPlugin },
rules: reactHooksPlugin.configs.recommended.rules,
},
// Next.js
{
plugins: { '@next/next': nextPlugin },
rules: {
...nextPlugin.configs.recommended.rules,
...nextPlugin.configs['core-web-vitals'].rules,
},
},
{
settings: {
react: { version: 'detect' },
},
2026-04-26 18:44:59 +09:00
languageOptions: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,
project: ['./tsconfig.json'],
},
},
2026-03-27 14:50:34 +09:00
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'explicit' }],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'type-imports', fixStyle: 'inline-type-imports' },
],
2026-05-19 16:15:15 +09:00
'@typescript-eslint/member-ordering': [
'error',
{
default: [
'public-static-field',
'protected-static-field',
'private-static-field',
'public-instance-field',
'protected-instance-field',
'private-instance-field',
'constructor',
'public-instance-method',
'protected-instance-method',
'private-instance-method',
],
},
],
'@typescript-eslint/explicit-function-return-type': [
'error',
{
allowExpressions: true,
allowTypedFunctionExpressions: true,
allowHigherOrderFunctions: true,
allowDirectConstAssertionInArrowFunctions: true,
},
],
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'default',
format: ['camelCase'],
leadingUnderscore: 'allow',
trailingUnderscore: 'allow',
},
{
selector: 'variable',
format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
leadingUnderscore: 'allow',
trailingUnderscore: 'allow',
},
{
selector: 'typeLike',
format: ['PascalCase'],
},
{
selector: 'interface',
format: ['PascalCase'],
custom: {
regex: '^I[A-Z]',
match: false,
},
},
{
selector: 'objectLiteralProperty',
format: null,
},
{
selector: 'objectLiteralMethod',
format: null,
},
{
selector: 'function',
format: ['camelCase', 'PascalCase'],
},
{
selector: 'import',
format: ['camelCase', 'PascalCase'],
},
],
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: {
attributes: false,
},
},
],
},
},
{
// React components are functions returning JSX and don't need explicit return types
files: ['**/*.tsx'],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
},
},
{
// Relax some rules in test files
files: ['**/*.test.ts', '**/*.test.tsx'],
rules: {
'@typescript-eslint/explicit-member-accessibility': 'off',
2026-03-27 14:50:34 +09:00
},
},
prettierRecommended,
);