Коллеги, всем привет!

Давайте честно: сколько из вас за последний год успели если не впрогреть, то хотя бы посмотреть в сторону нового JS-фреймворка? Qwik, Solid, Svelte — список можно продолжать. Я сам постоянно ловлю себя на этом: вижу хайп, читаю доки, даже пет-проект пытаюсь сделать... А потом прихожу на работу и видим тот же легаси-код, который всё сложнее поддерживать.

И тут я задал себе простой вопрос: а что, если дело не в фреймворках? Что, если мы просто лечим симптомы, а не болезнь?

Болезнь под названием "хочу новый фреймворк"

Знакомо:

  • Начинаешь новый проект — руки чешутся взять что-то модное

  • Через полгода код превращается в спагетти, даже с самым крутым фреймворком

  • Рефакторинг становится болью

  • Тесты писать сложно

  • Команда боится вносить изменения

Я прошел через это. Потратил кучу времени на изучение новых инструментов, но проблемы оставались. Пока не понял одну простую вещь...

Лекарство: три принципа, которые перевернули мой подход

Принцип 1: Делай одну вещь, но делай её хорошо

Помните тот ужасный компонент, который:

  • Ходит за данными

  • Форматирует их

  • Рендерит

  • И ещё аналитику отправляет?

Я называл это "компонент-бог". И таких у меня было полно. Пока не попробовал разбивать всё на мелкие сущности с одной ответственностью.

Вот как это выглядит сейчас:

userApiService.js → только запросы к API
userDataMapper.js → преобразование данных
AnalyticsTracker.js → только аналитика
UserProfileView.js → только отображение

Да, файлов стало больше. Зато теперь:

  • Если падает API — я знаю, где искать

  • Если дизайнер поменял вёрстку — правлю один файл

  • Если нужно добавить аналитику — не трогаю компонент

Принцип 2: Не прячь зависимости — покажи их

Раньше я постоянно импортил axios прямо в компонентах. Казалось, что так быстрее. Пока не попробовал написать тесты для такого кода...

Теперь я явно передаю все зависимости:

// Было
const UserList = () => {
    useEffect(() => {
        axios.get('/api/users').then(...)
    }, [])
}

// Стало
const UserList = ({ userService }) => {
    useEffect(() => {
        userService.getUsers().then(...)
    }, [userService])
}

Разница кажется небольшой, но на практике:

  • Тесты пишутся в 3 раза быстрее

  • Легко подменить реализацию (например, для моков)

  • Код становится предсказуемым

Принцип 3: Завись от интерфейсов, а не от реализаций

Это звучало для меня как какая-то магия, пока я не попробовал на практике.

Вместо того чтобы компонент знал про конкретный API:

// Плохо: компонент знает слишком много
const UserList = () => {
    const [users, setUsers] = useState([])
    
    useEffect(() => {
        fetch('/api/v2/users') // А если бэкенд поменяет API?
            .then(response => response.json())
            .then(setUsers)
    }, [])
}

Я создаю прослойку-абстракцию:

// userRepository.js
class UserRepository {
    async getUsers() {
        // Здесь может быть REST, GraphQL, моки - не важно
        const response = await fetch('/api/users')
        return response.json()
    }
}

// В компоненте
const UserList = ({ userRepository }) => {
    const [users, setUsers] = useState([])
    
    useEffect(() => {
        userRepository.getUsers().then(setUsers)
    }, [userRepository])
}

Теперь если бэкенд поменяет API, мне нужно поправить всего один файл, а не 15 компонентов.

Что изменилось в моей работе

После того как я начал применять эти принципы:

  1. Скорость разработки сначала немного упала (привыкал к новому подходу), но потом выросла в разы

  2. Качество кода стало заметно лучше — коллеги теперь понимают мой код с полуслова

  3. Рефакторинг перестал быть болью

  4. Тесты пишутся легко и быстро

Да, я всё ещё смотрю в сторону новых фреймворков. Но теперь я понимаю: не важно, React у меня или SolidJS — эти принципы работают везде.

Выводы, которые я сделал

  1. Фреймворки приходят и уходят, а архитектурные принципы остаются

  2. Инвестиция в архитектуру окупается быстрее, чем кажется

  3. Простота важнее модных фич

Я не призываю вас забросить изучение нового. Просто предлагаю сначала построить прочный фундамент.

А какие архитектурные принципы помогают вам в работе? Давайте обсудим в комментариях — возможно, я упустил что-то важное!

Комментарии (3)


  1. vkomp
    04.10.2025 05:09

    В react повсеместно юзаю useSWR. Типа useState+useEffect+кэш. Хорошая штука, рекомендую в концепции "один источник истины": компонент получает состояние, что-то поменялось - вызываешь mutate() и спишь спокойно.
    Выношу url в отдельный файл редко - в случаях когда юзается в нескольких местах. Обычно один url для одного компонента - и легко во Ctrl+Shift+F находится. Да и вообще есть какой-то критерий управляемости, по которому не разбиваю компонент.


  1. sunUnderShadow
    04.10.2025 05:09

    Когда только-только узнаешь про SOLID.

    Правда, не очень понятно при чем тут вообще фреймворки и почему мы опять застряли в реакте, хотя речь идёт про "чистый код", ну да ладно


  1. dominus_augustus
    04.10.2025 05:09

    Поздравляю, вы изобрели Solid, но реакт это слой рендеринга, так что тут это как костыль