- Changed @mui/material/Box deep imports to { Box } from '@mui/material'
- Updated no-restricted-imports to only restrict DS-covered components,
allowing Box/Stack/Grid for layout
94 lines
3.7 KiB
JavaScript
94 lines
3.7 KiB
JavaScript
const path = require('path');
|
|
const src = path.resolve(__dirname, 'src');
|
|
|
|
module.exports = {
|
|
parser: '@typescript-eslint/parser',
|
|
parserOptions: {
|
|
sourceType: 'module',
|
|
ecmaFeatures: { jsx: true },
|
|
},
|
|
plugins: ['@typescript-eslint/eslint-plugin', 'react', 'react-hooks', 'import', '@conarti/feature-sliced'],
|
|
extends: [
|
|
'plugin:@typescript-eslint/recommended',
|
|
'plugin:react/recommended',
|
|
'plugin:react-hooks/recommended',
|
|
],
|
|
root: true,
|
|
env: {
|
|
browser: true,
|
|
es2020: true,
|
|
},
|
|
settings: {
|
|
react: { version: 'detect' },
|
|
'import/resolver': {
|
|
typescript: {
|
|
alwaysTryTypes: true,
|
|
project: './tsconfig.json',
|
|
},
|
|
},
|
|
},
|
|
ignorePatterns: ['.eslintrc.cjs', 'vite.config.ts', 'vitest.config.ts', 'dist/'],
|
|
rules: {
|
|
'no-restricted-imports': ['warn', {
|
|
paths: [{
|
|
name: '@mui/material',
|
|
importNames: [
|
|
// DS-covered: import from @moex-vibe/design-system
|
|
'Typography', 'Button', 'TextField', 'Select', 'Checkbox',
|
|
'Paper', 'Chip', 'Badge', 'Alert', 'Dialog', 'Skeleton',
|
|
'CircularProgress', 'Link', 'IconButton',
|
|
'Table', 'TableBody', 'TableCell', 'TableContainer',
|
|
'TableHead', 'TableRow', 'TableSortLabel',
|
|
'TablePagination', 'Pagination',
|
|
],
|
|
message: 'Import from @moex-vibe/design-system instead, or use Box/Stack/Grid for layout.',
|
|
}],
|
|
}],
|
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
'react/react-in-jsx-scope': 'off',
|
|
|
|
// FSD layer boundaries (from @conarti/eslint-plugin-feature-sliced)
|
|
// layers-slices: catches cross-layer violations (e.g., shared→entities)
|
|
'@conarti/feature-sliced/layers-slices': ['error', {
|
|
// allow test files and test utilities to import from any layer for mocking
|
|
ignoreInFilesPatterns: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx', '**/test/**'],
|
|
}],
|
|
// absolute-relative: false positives with @/ alias convention — disabled
|
|
'@conarti/feature-sliced/absolute-relative': 'off',
|
|
// public-api: too strict for app/ and test internals — disabled
|
|
'@conarti/feature-sliced/public-api': 'off',
|
|
|
|
// FSD layer boundaries (from import/no-restricted-paths)
|
|
// NOTE: `from` = what's being imported, `target` = the file doing the import
|
|
'import/no-restricted-paths': [
|
|
'error',
|
|
{
|
|
zones: [
|
|
// shared/ cannot import from entities/, features/, widgets/, pages/, app/
|
|
{ from: `${src}/entities`, target: `${src}/shared` },
|
|
{ from: `${src}/features`, target: `${src}/shared` },
|
|
{ from: `${src}/widgets`, target: `${src}/shared` },
|
|
{ from: `${src}/pages`, target: `${src}/shared` },
|
|
{ from: `${src}/app`, target: `${src}/shared` },
|
|
// entities/ cannot import from features/, widgets/, pages/, app/
|
|
{ from: `${src}/features`, target: `${src}/entities` },
|
|
{ from: `${src}/widgets`, target: `${src}/entities` },
|
|
{ from: `${src}/pages`, target: `${src}/entities` },
|
|
{ from: `${src}/app`, target: `${src}/entities` },
|
|
// features/ cannot import from widgets/, pages/, app/
|
|
{ from: `${src}/widgets`, target: `${src}/features` },
|
|
{ from: `${src}/pages`, target: `${src}/features` },
|
|
{ from: `${src}/app`, target: `${src}/features` },
|
|
// widgets/ cannot import from pages/, app/
|
|
{ from: `${src}/pages`, target: `${src}/widgets` },
|
|
{ from: `${src}/app`, target: `${src}/widgets` },
|
|
// pages/ cannot import from app/
|
|
{ from: `${src}/app`, target: `${src}/pages` },
|
|
|
|
],
|
|
},
|
|
],
|
|
},
|
|
};
|