> Как выглядела структура проекта и где была сосредоточена логика (JavaScript)

Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы

Компании: Mosline

Стек: Node.js, JavaScript

> Пример ответа

Короткий ответ

Структура проекта обычно строится по feature-based или domain-driven подходу: каждая фича имеет свою папку с компонентами, хуками, утилитами и тестами. Логика сосредоточена в сервисах и хуках, а не в компонентах. Компоненты отвечают только за рендеринг и делегируют бизнес-логику в кастомные хуки или middleware. Это обеспечивает переиспользуемость, тестируемость и разделение ответственности.

Подробное объяснение

В современных frontend-проектах на JavaScript/Node.js структура папок отражает архитектурные принципы. Основные подходы:

  • Feature-based: папки features/auth, features/dashboard содержат всё для одной фичи - компоненты, хуки, API-вызовы, тесты. Логика вынесена в hooks и services.
  • Domain-driven: группировка по бизнес-доменам, например domains/user, domains/order. Внутри - api, model, ui, utils.
  • Layer-based: разделение на слои - components, hooks, services, utils, store. Логика в services и hooks, компоненты - только UI.

Логика сосредоточена в:

  • Кастомных хуках - для управления состоянием и побочными эффектами (useAuth, useFetch).
  • Сервисах - для API-вызовов, обработки данных, бизнес-правил.
  • Middleware - в контексте Redux или Express для обработки запросов/ответов.
  • Утилитах - для чистых функций форматирования, валидации.

Компоненты получают данные через хуки и передают их в дочерние компоненты, не содержат сложной логики. Это упрощает тестирование и поддержку.

На практике

В реальных проектах часто комбинируют подходы. Например, используют feature-based структуру, но внутри каждой фичи - layer-based: components, hooks, services. Логика в хуках может вызывать сервисы, которые работают с API. Пример типичной структуры:

src/
  features/
    auth/
      components/    - LoginForm, RegisterForm
      hooks/         - useAuth, useLogin
      services/      - authApi, tokenService
      utils/         - validateEmail
      tests/
    dashboard/
      components/    - Chart, StatsCard
      hooks/         - useDashboardData
      services/      - dashboardApi
  shared/
    components/      - Button, Modal
    hooks/           - useDebounce, useMediaQuery
    utils/           - formatDate, cn
  app/
    store/           - Redux store
    router/          - routes

Логика в хуках: useAuth управляет состоянием аутентификации, вызывает authApi.login(), сохраняет токен через tokenService. Компонент LoginForm только отображает форму и вызывает useAuth().login().

Пример кода

JAVASCRIPT
// features/auth/hooks/useAuth.js
import { useState, useCallback } from 'react';
import { authApi } from '../services/authApi';
import { tokenService } from '../services/tokenService';
export function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const login = useCallback(async (email, password) => {
setLoading(true);
try {
const { user, token } = await authApi.login(email, password);
tokenService.set(token);
setUser(user);
} finally {
setLoading(false);
}
}, []);
return { user, loading, login };
}
// features/auth/components/LoginForm.jsx
import { useAuth } from '../hooks/useAuth';
export function LoginForm() {
const { login, loading } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
login(email, password);
};
return (
<form onSubmit={handleSubmit}>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
<button disabled={loading}>Войти</button>
</form>
);
}

Как отвечать на собеседовании

Начни с краткого описания подхода: "обычно использую feature-based структуру, где логика вынесена в хуки и сервисы". Затем объясни, почему это важно: разделение ответственности, тестируемость, переиспользуемость. Приведи пример из опыта - как ты реорганизовал проект, вынеся логику из компонентов. Упомяни trade-off: feature-based может дублировать код между фичами, но это решается shared-папкой. Не углубляйся в детали реализации, если не спросят.

Что проверяет интервьюер

  • Понимание принципов разделения ответственности и модульности.
  • Умение проектировать масштабируемую архитектуру.
  • Знание современных практик (hooks, services, middleware).
  • Способность аргументировать выбор структуры.
  • Опыт работы с реальными проектами, а не только с учебными примерами.

Типичные ошибки

  • Всю логику пихать в компоненты - "божественный компонент".
  • Использовать только layer-based структуру без группировки по фичам - сложно найти код.
  • Не выделять shared-утилиты - дублирование кода.
  • Путать хуки и сервисы: хуки для состояния и эффектов, сервисы для бизнес-логики и API.
  • Игнорировать тестируемость - логика в компонентах сложнее тестируется.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью