Структура проекта

При работе с библиотекой MUI (Material-UI) в JavaScript важно организовать проект так, чтобы его структура была логичной, масштабируемой и поддерживаемой. Стандартная практика предполагает разделение компонентов, стилей, утилит и страниц по отдельным директориям, что облегчает работу над крупными приложениями.


Основные директории

  1. src/ Центральная папка проекта, где сосредоточен весь код приложения. Обычно содержит подкаталоги:

    • components/ – переиспользуемые React-компоненты. Каждый компонент может иметь собственную папку с файлами:

      Button/
        Button.js
        Button.styles.js
        Button.test.js

      Button.js – основной компонент, Button.styles.js – стили с использованием MUI styled или makeStyles, Button.test.js – тесты.

    • pages/ – компоненты страниц приложения, например:

      HomePage.js
      ProfilePage.js

      Каждая страница обычно использует переиспользуемые компоненты из components/.

    • theme/ – настройка глобальной темы MUI:

      theme.js
      ThemeProvider.js

      Здесь определяется цветовая палитра, типографика, overrides компонентов. Обычно оборачивается весь <App /> в ThemeProvider.

    • hooks/ – кастомные React-хуки для управления состоянием и логикой:

      useAuth.js
      useFetch.js

      Хуки помогают изолировать функциональность и делают компоненты более чистыми.

    • utils/ – вспомогательные функции и константы:

      api.js
      constants.js
      helpers.js
    • assets/ – изображения, шрифты, иконки.


Организация компонентов MUI

Компоненты MUI могут использоваться двумя способами: через готовые компоненты и через кастомизированные стили.

  1. Готовые компоненты Пример использования кнопки:

    import Button from '@mui/material/Button';
    
    function MyButton() {
      return <Button variant="contained" color="primary">Кнопка</Button>;
    }
  2. Кастомизация через styled Для уникального дизайна лучше использовать API styled:

    import { styled } from '@mui/material/styles';
    import Button from '@mui/material/Button';
    
    const CustomButton = styled(Button)(({ theme }) => ({
      backgroundColor: theme.palette.secondary.main,
      borderRadius: 8,
      padding: '10px 20px',
      '&:hover': {
        backgroundColor: theme.palette.secondary.dark,
      },
    }));
    
    export default CustomButton;
  3. Кастомизация через sx Для одноразовых изменений стилей на уровне компонента:

    <Button sx={{ borderRadius: 4, marginTop: 2 }}>Пример</Button>

Управление темой

Создание глобальной темы обеспечивает единообразие интерфейса:

import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  palette: {
    primary: { main: '#1976d2' },
    secondary: { main: '#dc004e' },
  },
  typography: {
    fontFamily: 'Roboto, Arial, sans-serif',
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <MainApp />
    </ThemeProvider>
  );
}
  • Палитра цветов (palette) – определяет основной и вторичный цвета, а также цвета для текста и фона.
  • Типографика (typography) – настраивает шрифты и размеры заголовков и текста.
  • Overrides – позволяет переопределять дефолтные стили MUI для всех компонентов проекта.

Подход к файловой структуре компонентов

Для крупных компонентов рекомендуется использовать модульный подход:

components/
  Card/
    Card.js
    Card.styles.js
    Card.test.js
  • Card.js – JSX и логика компонента.
  • Card.styles.js – стили с использованием styled или makeStyles.
  • Card.test.js – unit-тесты с Jest и React Testing Library.

Для маленьких компонентов, не требующих отдельного файла стилей, можно помещать всё в один файл.


Роутинг и страницы

Чаще всего используется React Router для навигации:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import ProfilePage from './pages/ProfilePage';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/profile" element={<ProfilePage />} />
      </Routes>
    </Router>
  );
}
  • Каждая страница импортирует компоненты из components/.
  • Роутинг разделяет приложение логически, что упрощает поддержку.

Разделение логики и UI

Для удобства поддержки компонентов и страниц часто применяют паттерн «Container – Presentational»:

  • Container – отвечает за логику и данные, может содержать хуки и API-запросы.
  • Presentational – чистый UI-компонент, получает данные через props.

Пример:

containers/
  ProfileContainer.js
components/
  ProfileCard.js

ProfileContainer получает данные пользователя и передаёт их в ProfileCard, который отвечает только за визуальное отображение.


Подключение глобальных стилей

Хотя MUI использует JSS и sx, иногда требуется глобальный CSS:

  • Файл index.css для сброса стилей.
  • В MUI можно использовать CssBaseline для унификации стилей браузера:
import CssBaseline from '@mui/material/CssBaseline';

function App() {
  return (
    <>
      <CssBaseline />
      <MainApp />
    </>
  );
}

Итоговая структура проекта

Пример структуры крупного проекта с MUI:

src/
  assets/
    images/
    icons/
  components/
    Button/
    Card/
    Header/
  containers/
    ProfileContainer.js
  hooks/
    useAuth.js
    useFetch.js
  pages/
    HomePage.js
    ProfilePage.js
  theme/
    theme.js
  utils/
    api.js
    constants.js
  App.js
  index.js

Такое разделение обеспечивает чистоту кода, масштабируемость и лёгкость тестирования, позволяя создавать крупные приложения с использованием MUI без хаоса в структуре проекта.