197 lines
6.3 KiB
JavaScript
197 lines
6.3 KiB
JavaScript
import eslint from '@eslint/js'
|
|
import tseslint from 'typescript-eslint'
|
|
import importX from 'eslint-plugin-import-x'
|
|
import react from 'eslint-plugin-react'
|
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
import jsxA11y from 'eslint-plugin-jsx-a11y'
|
|
import eslintConfigPrettier from 'eslint-config-prettier'
|
|
import eslintPluginPrettier from 'eslint-plugin-prettier'
|
|
import globals from 'globals'
|
|
import boundaries from 'eslint-plugin-boundaries'
|
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
|
|
const fsdPathGroups = [
|
|
{ pattern: 'app/**', group: 'internal', position: 'before' },
|
|
{ pattern: 'pages/**', group: 'internal', position: 'before' },
|
|
{ pattern: 'widgets/**', group: 'internal', position: 'before' },
|
|
{ pattern: 'features/**', group: 'internal', position: 'before' },
|
|
{ pattern: 'entities/**', group: 'internal', position: 'before' },
|
|
{ pattern: 'shared/**', group: 'internal', position: 'before' },
|
|
// alias вида "@/shared/..."
|
|
{ pattern: '@/**', group: 'internal', position: 'before' },
|
|
]
|
|
|
|
/** Правила + FSD-границы. */
|
|
export default tseslint.config(
|
|
{
|
|
ignores: ['dist/**', 'node_modules/**'],
|
|
},
|
|
{
|
|
name: 'react-plugin-settings',
|
|
settings: { react: { version: '19' } },
|
|
},
|
|
eslint.configs.recommended,
|
|
...tseslint.configs.recommended,
|
|
importX.flatConfigs.recommended,
|
|
importX.flatConfigs.typescript,
|
|
react.configs.flat.recommended,
|
|
react.configs.flat['jsx-runtime'],
|
|
reactHooks.configs.flat.recommended,
|
|
reactRefresh.configs.vite,
|
|
jsxA11y.flatConfigs.recommended,
|
|
{
|
|
files: ['**/*.{ts,tsx}'],
|
|
languageOptions: {
|
|
globals: { ...globals.browser, ...globals.es2021 },
|
|
},
|
|
settings: {
|
|
'import/internal-regex': '^(@/)?(app|pages|widgets|features|entities|shared)(/|$)',
|
|
'import/resolver': {
|
|
typescript: { project: './tsconfig.json' },
|
|
node: true,
|
|
},
|
|
},
|
|
rules: {
|
|
'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
|
|
quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
|
|
'max-len': [
|
|
'warn',
|
|
{
|
|
code: 120,
|
|
ignoreStrings: true,
|
|
ignoreTrailingComments: true,
|
|
ignoreTemplateLiterals: true,
|
|
ignoreComments: true,
|
|
},
|
|
],
|
|
'import-x/extensions': [
|
|
'warn',
|
|
{
|
|
js: 'never',
|
|
jsx: 'never',
|
|
ts: 'never',
|
|
tsx: 'never',
|
|
json: 'always',
|
|
svg: 'always',
|
|
},
|
|
],
|
|
'import-x/prefer-default-export': 'off',
|
|
'import-x/no-extraneous-dependencies': 'off',
|
|
'import-x/no-cycle': 'warn',
|
|
'import-x/order': [
|
|
'warn',
|
|
{
|
|
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
|
pathGroups: [
|
|
{ pattern: 'react', group: 'external', position: 'before' },
|
|
{ pattern: 'react-dom', group: 'external', position: 'before' },
|
|
{ pattern: '@mui/**', group: 'external', position: 'before' },
|
|
...fsdPathGroups,
|
|
],
|
|
pathGroupsExcludedImportTypes: ['react'],
|
|
'newlines-between': 'never',
|
|
alphabetize: { order: 'asc', caseInsensitive: true },
|
|
},
|
|
],
|
|
'react/prop-types': 'off',
|
|
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'ignore' }],
|
|
'react/display-name': 'off',
|
|
'react/no-unescaped-entities': 'warn',
|
|
'@typescript-eslint/no-explicit-any': 'warn',
|
|
'@typescript-eslint/no-unused-vars': ['error', { args: 'none' }],
|
|
'no-unused-vars': 'off',
|
|
'@typescript-eslint/no-shadow': 'off',
|
|
'no-shadow': 'off',
|
|
'@typescript-eslint/no-use-before-define': 'error',
|
|
'no-use-before-define': 'off',
|
|
'consistent-return': 'off',
|
|
'@typescript-eslint/no-empty-function': 'warn',
|
|
'@typescript-eslint/no-unnecessary-type-constraint': 'warn',
|
|
'class-methods-use-this': 'warn',
|
|
},
|
|
},
|
|
{
|
|
files: ['**/*.{ts,tsx}'],
|
|
plugins: { prettier: eslintPluginPrettier },
|
|
rules: { 'prettier/prettier': ['warn', { endOfLine: 'lf' }] },
|
|
},
|
|
eslintConfigPrettier,
|
|
{
|
|
files: ['**/*.{ts,tsx}'],
|
|
plugins: { boundaries },
|
|
languageOptions: {
|
|
parserOptions: {
|
|
ecmaVersion: 'latest',
|
|
sourceType: 'module',
|
|
ecmaFeatures: { jsx: true },
|
|
},
|
|
},
|
|
settings: {
|
|
'import/resolver': {
|
|
typescript: { project: './tsconfig.json' },
|
|
},
|
|
'boundaries/include': ['src/**/*'],
|
|
'boundaries/elements': [
|
|
{ type: 'app', pattern: 'src/app/**' },
|
|
{ type: 'pages', pattern: 'src/pages/**' },
|
|
{ type: 'widgets', pattern: 'src/widgets/**' },
|
|
{ type: 'features', pattern: 'src/features/**' },
|
|
{ type: 'entities', pattern: 'src/entities/**' },
|
|
{ type: 'shared', pattern: 'src/shared/**' },
|
|
],
|
|
},
|
|
rules: {
|
|
'boundaries/no-unknown': 'off',
|
|
'boundaries/no-unknown-files': 'off',
|
|
'boundaries/dependencies': [
|
|
'error',
|
|
{
|
|
default: 'disallow',
|
|
checkUnknownLocals: true,
|
|
rules: [
|
|
{ from: { type: 'shared' }, allow: { to: { type: 'shared' } } },
|
|
{
|
|
from: { type: 'entities' },
|
|
allow: { to: { type: ['entities', 'shared'] } },
|
|
},
|
|
{
|
|
from: { type: 'features' },
|
|
allow: { to: { type: ['features', 'entities', 'shared'] } },
|
|
},
|
|
{
|
|
from: { type: 'widgets' },
|
|
allow: {
|
|
to: { type: ['widgets', 'features', 'entities', 'shared'] },
|
|
},
|
|
},
|
|
{
|
|
from: { type: 'pages' },
|
|
allow: {
|
|
to: {
|
|
type: ['pages', 'widgets', 'features', 'entities', 'shared'],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
from: { type: 'app' },
|
|
allow: {
|
|
to: {
|
|
type: ['app', 'pages', 'widgets', 'features', 'entities', 'shared'],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
files: ['eslint.config.js'],
|
|
rules: {
|
|
'import-x/no-unresolved': 'off',
|
|
'import-x/no-named-as-default': 'off',
|
|
'import-x/no-named-as-default-member': 'off',
|
|
},
|
|
},
|
|
)
|