Выучить React недостаточно для профессиональной разработки больших приложений.  Для этого есть две основные причины. Первая, у React есть огромная экосистема модулей, в которой необходимо разбираться. Вторая, эта экосистема меняется каждый год. Поэтому может быть не просто разобраться во всех тонкостях применения React, и эта статья может стать путеводителем в увлекательный мир современного React.

К этой статье прилагается GitHub репозиторий и Демо приложение, которые демонстрируют работу  упомянутых в этой стать модулей (и некоторых других). GitHub  репозиторий можно использовать в качестве boilerplate для вашего следующего профессионального приложения.

P.S. Я пишу также статьи на английском языке. Английский вариант этой моей статьи доступен тут.


Основные модули

Next.js — React SSR фреймворк

Redux — Central state management

next-redux-wrapper — Next and Redux коннектор

Redux-Saga — Async middleware для Redux

next-translate — Переводы и i18n

React Hook Form — Работа с формами

Chakra UI — Design system


Демо 
— https://enterprise-react-2022.vercel.app

Репо — https://github.com/slava-lu/enterprise-react-2022


Основное изменение по сравнению со стеком популярным пару лет назад является обязательное использование технологии Server-Side Rendering (SSR). Это уже не просто способ улучшить индексируемость поисковыми системами или немного улучшить производительность приложения. Без SSR практически невозможно добиться хороших результатов в новой методике оценки сайтов от Google - Core Web Vitals. Core Web Vitals стали настолько важны, что учебный раздел основного SSR фреймворка посветил этой теме целый раздел. Я рекомендую достаточно хорошо изучить Core Web Vitals. При постоянно увеличивающимся объеме информации может быть не просто определить какой сайт лучше исключительно на основе его контента, поэтому основным определяющим фактором для поисковых систем может стать количество усилий, которые вложили разработчики в создание продукта.

Основным фреймворком для создания SSR приложений на React является Next.js. В настоящий момент каких-то реальных альтернатив не существует. Next.js достаточно прост и имеют хорошую документацию и обучающий раздел.  На нем можно легко создать простое приложение, но создание крупных веб решений может вызвать сложности. Проблемным местом является Redux, который все еще требуется при создании больших приложений.  Многочисленные попытки избавиться от Redux или заменить его на что-то другое пока не привели к его исчезновению. Учитывая, как сильно он облегчает работу разработчика, я думаю что Redux будет с нами еще несколько лет.

Сложность при работе с Redux состоит в том, что он предназначен для работы на стороне клиента (в браузере). Каждый раз, когда вы генерите страницу на сервере, вы создаёте новый Redux store, который надо синхронизовать с данными на клиенте. Этот процесс называется Hydration. Hydration может быть не простым и быть подвержен ошибкам. Оптимальным подходом было бы начальная генерация страницы на сервере вместе с созданием нового чистого Redux store, и затем последующая генерация страниц на клиенте. Таким и был изначальный подход Next.js, когда они предложили метод getInitialProps для получения данных.  По каким-то причинам позже они решили не продвигать этот метод и предложили два новых метода getServerSideProps и getStaticProps в качестве потенциальной замены изначального getInitialProps. Основной посыл компании Vercel, которая стоит за Next.js заключался в том, что два новых метода могу улучшить производительность приложений.  Они не отказались полностью от getInitialProps, но старались не упоминать его ни в документации, ни в своих коммуникациях.

Целью метода getStaticProps является генерация страницы во время сборки приложения и затем отдача статического контента браузеру. Я сомневаюсь, что крупные приложения имеют много статического контента. Возможно, основной целью getStaticProps была попытка конкурировать с фреймворком Gatsby.  Смысл метода getServerSideProps менее прозрачен даже после ознакомления с объяснениями от Vercel. Разработчики продолжают спорить о целесообразности использования этого метода вместо getInitialProps. Очевидно, однако, что getInitialProps работает гораздо лучше с Redux, и полный отказ от этого метода может привести к значительному уменьшению популярности Next.js. Поскольку в мире React других реальных альтернатив нет, то это могло бы мотивировать разработчиков посмотреть в сторону Vue.js и Nuxt.js и возможно там и остаться.

На текущий момент пока не очевидно, какой путь выберет Next.js. В Демо приложении я использовал все три метода, чтобы показать, как с ними можно работать. Как можно увидеть из кода, работать с getInitialProps гораздо удобней, чем с другими двумя методами. 


В качестве Redux middleware для работы с REST API (а также WebSocket) я рекомендую использовать старый добрый модуль Redux-Saga. Он дает возможность хорошо отделять UI от бизнес-логики, а также позволяет легко реализовывать сложную логику получения данных.  Стоит отметить, что процесс начального изучения Redux-Saga может быть трудоемким, но затем вы сможете легко и быстро создать любые асинхронные middleware.

Если вы следите за трендами в мире React, то могли заметить, что иногда высказываются предложения переместить функции получения данных на уровень React компонентов. Однако мне кажется, что это может быть всего лишь очередной попыткой наконец-то избавиться от Redux. Я не вижу особых преимуществ от такого объединения.  Наоборот, разделения UI от получения данных позволяет улучшить надежность приложения и облегчает его разработку.  Простота и скорость разработки, которая получила свой термин как  “Developer Experience” становится все более важной в современном мире. Технологии становятся более сложными, а их изучение более трудоемким. Человеку трудно постичь их всех, не говоря уже о том, чтобы овладеть ими. Поэтому простота разработки может стать определяющим фактором в выборе технологии.

Одним из дополнительных преимуществ при использовании Redux-Saga совместно с Next.js является простота выбора стратегии навигации и получения данных. Существует два основных подхода к этому вопросу:

  1. Сначала переход на страницу, потом загрузка данных

  2. Сначала предзагрузка данных, потом переход на страницу.

Первый способ, на мой взгляд является более популярным, однако его не так легко реализовать на Next.js, поскольку Next.js блокирует навигацию до завершения работы любого из трех методов получения данных, описанных выше. Redux-Saga, однако, позволяет указать, хотите ли вы дожидаться завершения запросов (перевода Promise в статус resolved) до навигации или нет, таким образом реализуя любую из этих двух стратегий. Вы можете посмотреть, как это делается в Демо приложении. Ищите свойство navigateAfterSaga.

Shop.getInitialProps = async ({ store }) => {
  store.dispatch(triggerProductList(10))
  return {
    navigateAfterSaga: false,
    title: 'title#shop_page',
  }
}

Что касается низкоуровневой функции запроса данных, то я предлагаю использовать axios вместо классического fetch. В большей степени из-за отличного функционала, который предлагает axios при работе с таймаутами как на стороне клиента, так и на стороне сервера. Честно говоря, я даже не знаю, как можно реализовать таймауты на стороне сервера при работе с Next.js и fetch.


Одной из новых и приятных функциональностей Next.js является интернациональная маршрутизация (Internationalized Routing). Она предоставляется прямо из коробки и позволяет добавлять префиксы к URL для мультиязычных сайтов.  К сожалению, это только маленькая часть того, что нужно разработчикам для создания мультиязычных сайтов. Как минимум необходим еще модуль переводов. Выбирать его следует осторожно, так как не все модули переводов поддерживают все три методы получения данных, предлагаемые Next.js. Я предлагаю использовать next-translate, так как он поддерживает getInitialProps.

Еще одной полезной функцией, которая требуется мультиязычным сайтам, является функция изменения URL в зависимости от языка. Не только префикса, а всего URL. Так например en/page должно стать de/seite. Есть примеры реализации этого функционала с помощью настройки rewrites. Но это явно не то место, где это должно делаться. Хочется надеяться, что разработчики Next.js обратят внимание на этот вопрос в будущем.


Одной из важных задач при выборе стека является выбор UI модуля или Дизайн Системы (Design System). Можно сделать свою собственную, но это достаточно трудоемко. Существуют готовые решения и очевидным лидером среди них на сегодняшней день является Chakra UI. Ранее популярной опцией был также Material UI, но он уже несколько приелся, да и развивается не очень активно. Chakra UI предлагает хороший выбор базовых бесплатных элементов, а также платные сложные темплейты. С помощью этих темплейтов можно создать дизайн E-Commerce сайта за считанные дни, не прибегая к помощи таких инструментов как Figma или аналогичных. Это очень здорово.

Проблема при использовании этой библиотеки, как в прочем и почти любой другой состоит в том, что она навязывает свой API. Если вы успели выучить наизусть все свойства CSS, то при использовании Chakra UI придется учить их заново.  В прочем, вы можете распечатать основные из них и повесить где-нибудь перед собой.  Для уникальных или сложных UI компонентов я предлагаю использовать styled-components. Эта библиотека очень гибкая и позволяет использовать стандартный CSS без сокращений или конвертации в Camelcase.


Что касается работы с формами, то в экосистеме React появился новый лидер. Некоторое время назад на смену всем известной библиотеки Redux Form пришел Formik. Проблема с Formik заключалась в том, что эта библиотека использует шаблон render props. В свое время этот шаблон был популярен, но не прижился в React сообществе. Мне кажется этот шаблон несколько запутанным, и при разработке больших приложений бывает трудно понять, что происходит в коде.

На фоне сложностей с Formik и другими библиотеками для обработки форм появилась новая - React Hook Form, которая очень активно набирает популярность. Она очень проста в использовании, но имеет одну особенность. Она основана на шаблоне неуправляемых компонентов (Uncontrolled Components). Из-за этого становиться непросто отсылать форму не из компонента самой формы, но это возможно.  Простота и очень хорошая документация является неоспоримыми преимуществами этой библиотеки.


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

Хочется еще сказать несколько слов про развертывание приложений. Если вы создали приложение на Next.js, то я рекомендую рассмотреть возможность его развёртывания на хостинге Vercel. Вы можете подключить свой репозиторий GitHub к облаку Vercel и развернуть приложение за пару кликов мышкой.  Что еще более приятно, так это то, что вы получаете готовый CI/CD из коробки. Как только вы создаете Pull Request (PR), то создается так называемая preview версия приложения на основе этого PR. После принятия этого PR, основное приложение также автоматически обновляется. Если вы когда-либо пытались настроить такой функционал в Jenkins или GitHub Actions, то вам непременно эта функциональность должна понравиться.

Есть еще пара важных тем, которые напрямую не относятся к React, но относятся к области frontend разработки. Я скажу пару слов о них ниже.

Тестирование. Тема тестирования является гораздо более запутанной, чем кажется на первый взгляд. С одной стороны, никто не сомневается, что тестирование является важным. Но немногие могу раскрыть, какое тестирование является важным и почему.  Большой шум вокруг юнит тестирования пришел к нам из мира backend, где у разработчиков нет возможности мгновенно видеть результат своей работы. Единственным простым и быстрым способом убедиться в качестве написанного кода для backend разработчика является тестирование его юнит тестами. Но это не так в мире frontend. С надежной и производительной технологией Fast Refresh, которую предлагает Next.js и другие фреймворки, frontend  разработчик может мгновенно видеть результат каждой строчки кода, которую он печатает.  Если это еще и соединить с компонентным подходом, который разделяет элементы кода (особенно при использовании Redux-Saga), то ценность юнит тестирования становиться совсем неочевидной.  Я даже готов сделать смелое утверждение, что юнит тестирование приносит совсем мало пользы при современной разработки React приложений, если только у вас нет файлов с действительно сложной логикой. Но если они есть, то имеет смысл подумать про перенос этой логики на backend.

Но что может быть действительно полезным, так это функциональное тестирование интерфейса. Разработчику часто бывает сложно заметить, что радиус контейнера картинки составляет 2px вместо 4px, или что расстояние между элементами интерфейса увеличилось на 4px. Этот тип тестирования может быть хорошо автоматизирован. Также может быть полезным хаотичное нажатие на ссылки и кнопки. Разработчики обычно проверяют только разумный сценарий, который должны выбрать сознательные пользователи.  Случайное нажатие на кнопки может уронить сайт или привести к отображению неправильных данных. Таких проблем лучше избегать.    

Typescript. Typescript активно пытается стать основным языком разработки frontend приложений, но пока не смог получить этот статус. Утверждается, что Typescript позволяет совершать меньше ошибок при разработке приложений.  Возможно, это так, но не стоит забывать про побочные эффекты, такие как менее читаемый код и дополнительный траблшутинг специфичных для Typescript проблем, который отнимает время, но не улучшает при этом само приложение. Можно сравнить Typescript c автопилотом от Tesla. Автопилот Tesla действительно хорош и помогает водителю управлять автомобилем. Проблема, однако, состоит в том, что он стоит 10К+ долларов и водитель все равно не может расслабиться и посмотреть фильм на заднем сидении. Он вынужден держать руки на руле. Возникает вопрос, а в чем тогда ценность этого Автопилота?
Похожие рассуждения можно применить и к Typescript. Вы все равно должны быть хорошим разработчиком, чтобы создавать профессиональные приложения.  Но если вы являетесь профессиональным разработчиком, то возможно вам не нужен и Typescript, чтобы помогать вам писать качественный работающий код, и вы можете создавать приложения быстрей без него.
Возможно, часть хайпа вокруг Typescript идет от backend разработчиков, которые приходят в мир frontend и пытаются ООПезировать JavaScript, чтобы чувствовать себя более комфортно. 
Typescript может быть полезен при разработке модулей для других разработчиков, так как это позволяет получить подсказки в стиле IntelliSense от IDE. Ценность Typescript при разработке конечных продуктов для меня менее очевидна.

Последняя тема, которую я хотел бы тут затронуть, это сторонние сервисы.  Сегодня никто не хочет возиться с настройкой почтовых серверов и других инфраструктурных сервисов.  Чтобы сэкономить вам немного времени на поиск информации, я составил свой список предпочтений. Я не буду приводить какие-либо аргументы, чтобы не увеличивать объем статьи, но мы можем обсудить мой выбор в комментариях, если будет желание.


Cloudinary — хранение мультимедиа и обычных файлов

Sendgrid — отправка технических emails

Mailchimp — отправка маркетинговых emails

Sendbird — чаты и другая коммуникация с пользователями


Многие могут сказать, что они создали хорошие приложения, используя другой набор модулей.  Это скорей всего будет правда.  Но что я могу обещать, так это то, что вы не пожалеете, если остановите свой выбор на стеке, представленным здесь.

Надеюсь, что этот обзор был вам полезен и интересен и поможет вам лучше понять экосистему React, даже если вы не согласны со всеми тезисами в этой статье.

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


  1. DrBulkin
    21.01.2022 00:34
    +3

    Картинка к статье. Шестерни фрезеруют на портальном ЧПУ. Аж глаз задергался :)


  1. Ilusha
    21.01.2022 01:29
    +9

    В 2022 такое отношение к typescript вызывает удивление. Ну правда, я даже в стартапах, где нужно "ещё вчера" вижу значительное улучшение качества кода, а значит - меньше багов. Не говоря уже об крупных проектах. А вот ваши аргументы не выдерживают критики.

    Несомненно, найдутся сложные вещи, которые сложно быстро без опыта воплотить в коде. Но всегда можно заигнорить.

    Тема локализации и интернационализации не раскрыта. Почему не formatjs? Только из-за next?

    Почему не рассмотрен mobx?


    1. Bone
      21.01.2022 09:44
      +6

      Аналогично. Я просто не понимаю, когда говорят, что typescript, что-то усложняет. Он ничего не усложняет, наоборот он многократно упрощает написание кода и его читаемость.


    1. slaval_ch Автор
      21.01.2022 10:12
      -4

      Что меня всегда удивляло в сторонниках тайпскрипта, так это нетерпимость у другому мнению. Это особенно настораживает. Наверно в ИТ не должно быть правильного мнения и неправильного, все таки. Я высказал свое. Если оно вас удивляет, это не значит, что оно не правильное.


      1. Roman_Cherkasov
        21.01.2022 10:30
        +3

        Хм, а меня удивляет больше другой момент. Вам привели несколько аргументов которые ставят под сомнение ваше мнение (в том числе в комментариях к оригинальной статье), и вместо того чтобы его отстаивать в конструктивной дискуссии - вы переходите к тому, что "в IT не должно быть правильного мнения". И говорите о том что сторонники чего-то не терпимы к чему-то отличному...


        1. slaval_ch Автор
          21.01.2022 10:37
          +3

          не змаетил аргументов, к сожалению. "Я вижу что тайпскрипт лучше", это не аргумент, а личное мнение. Аргумент, это какие-то рассуждения, анализ, выводы, сравнения и т.д.
          И минус - это не аргумент, а скорей показатель их отсутсвия


          1. Ilusha
            21.01.2022 13:09
            +1

            Неявные аргументы были, но Вы решили их пропустить.

            Но я не акцентировал на этом внимание, потому что у Вас нет аргументов не использовать ts. Вы приводите какие-то слабейшие мифы и домыслы, расписываясь в том, том, что ts не использовали и не знаете. Зачем тогда о нем пишите?

            Я лишь взывал к здравому смыслу.


      1. Ilusha
        21.01.2022 13:04
        +1

        Разве в моем сообщении есть намек нетерпимость? Вы что-то путаете.
        Я не называл Ваше мнение неправильным, это сделали Вы сами.

        Мнение? Я выразил свое, да. А Вы оскорбились.
        Имхо, вы просто не пользовались ts-ом. Поэтому и такое отношение.


      1. Ostic
        21.01.2022 13:37
        -1

        Если послушать интервью Дэна, то на вопрос о TS ответ однозначно "нет" ) Команда, которая поддерживает свыше 700 страниц, по словам того же Дэна, не использует TS. Но есть люди, как выясняется, которые его и в стартапах юзают. И да, они достаточно агрессивны.


        1. Alexandroppolus
          21.01.2022 14:03
          +3

          Они там вместо TS используют Flow. Так исторически сложилось. Не было бы Flow, давно перешли бы на TS.


          1. Ostic
            21.01.2022 16:10
            -1

            Цитирую ответ Дэна:

            " Если и будем переписывать, то как-то более фундаментально, на тот же Rust или что-то такое. "

            Так что на счет "перешли бы на TS" - это вряд ли.

            Не буду критиковать TS, но как-то не находит отклик в душе, как-то (исключительно моё мнение) угловато всё это.

            Я бы, по примеру Python, ещё бы и хвосты отрезал. (код не мой - так, для примера).
            Я бы, по примеру Python, ещё бы и хвосты отрезал. (код не мой - так, для примера).
            Куда как приятнее без хвостов
            Куда как приятнее без хвостов


    1. slaval_ch Автор
      21.01.2022 10:14
      -5

      mobx не рассмотрен, потому что это не обзор экосистемы Реакта. Это предлагаемый универсальный стек для реализации приложений любого маштаба. На мой взгляд mobx не позвоялет реалтизовать приложения любого маштаба.


      1. nin-jin
        21.01.2022 10:30
        +4

        mobx не позвоялет реалтизовать приложения любого маштаба

        Для реализации приложений любого масштаба нужны механизмы декомпозиции. MobX, как реализация ОПР, это позволяет. Redux же, наоборот, всячески сопротивляется.


        1. funca
          23.01.2022 11:44

          Что такое ОПР?



      1. Alexandroppolus
        21.01.2022 11:00
        +3

        На мой взгляд mobx не позвоялет реалтизовать приложения любого маштаба.

        Уже который раз вижу такие слова, но как всегда - без обоснования.


      1. Ilusha
        21.01.2022 13:13
        +1

        Вы использовали mobx на проектах среднего и выше масштаба, чтобы так заявлять?

        Аргумент "это мое мнение" Вы уже приводите второй раз, серьезно?
        Я могу пропагандировать "теорию" плоской земли, имея в арсенале только лдин аргумент: "потому что я так считаю"?


        1. slaval_ch Автор
          21.01.2022 13:44
          -3

          Любая статья, это мнение автора. Вы можете написать свою про мобх. Зачем спорить. Пусть пользователи увидят 2 стека и сами решат. Помимо желания высказать свое мнение, надо уважать чужой труд.


          1. Ilusha
            21.01.2022 15:34
            +4

            Статья здесь - это пропаганда мнения автора.

            Зачем спор? В нем рождается истина.

            Не высказать критику, потому она - неуважение к труду, по мнению автора? Вам не кажется, что это очень скользкая дорожка?


      1. strannik_k
        21.01.2022 21:06
        +1

        В Vuex и Mobx практически все используют MVVM (или что-то близкое к этой архитектуре). Получается и Vue не должен позволять писать приложения любого масштаба. Но ведь пишут, как на Mobx так и на Vue + Vuex).
        Mobx в отличие от Redux не ограничивает какой-либо архитектурой. Если плохо получается на нем, дело в навыках. При хороших архитектурных навыках можно вообще без менеджеров написать что угодно, но с ними удобнее.

        Порекомендую перейти с redux на что-то другое хотя бы по той причине, что когда ответсвенность за архитектуру перекладывается на фремворк/библиотеку, это плохо сказывается на росте навыков проектирования.


        1. Ilusha
          21.01.2022 21:19
          +1

          У vue появилась pinia от разраба vuex.

          https://pinia.vuejs.org/

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


          1. strannik_k
            21.01.2022 21:31

            Буду знать, спасибо! Пока пишу на React, но думаю при удобном случае перейти на Vue.


            1. Ilusha
              21.01.2022 21:53

              Я перешёл уже как пол года. Сейчас у меня проекты vue2/vuex и vue3/pinia. Ну что сказать: после реакта как-то бедненько с экосистемой. Если что-то популярное есть, то оно часто безальтернативное. А разраб vee-validate, единственого популярного решения про формы, вообще упоротый чувак, смена мажорной версии - новая либа под старым названием.

              Но кодить мне нравится больше на vue, но тут ещё фактор новизны играет роль.


    1. Ostic
      21.01.2022 14:27
      +1

      Это интервью Дэна 2021 года.

      В твоих постах периодически видно пассивно-агрессивное отношение к Redux. Почему он тебе так не нравится, учитывая, насколько удобные обёртки написали мейнтейнеры, Redux toolkit и насколько улучшилась документация?

      В плане документации и так далее — они большие молодцы, я оценил. К тем, кто его поддерживает, у меня нет совершенно никаких претензий, только благодарность. Почему я пассивно-агрессивно отношусь к нему — потому что это несколько строк кода, которые ничего не делают.

      У меня первая реакция на такие вопросы — я не знаю, что такое state management, не понимаю, что люди имеют в виду, когда говорят об этом. Может, у меня профдеформация, потому что в React-команде мы просто думаем об этом иначе.

      В React уже есть понятие State, это UI-состояние, его менеджишь тем, что просто используешь State, если нужно передать глубоко, используешь контекст и все дела.

      — Насколько я знаю, Vue уже переписали на TypeScript. Когда, может быть, React перепишут с Flow на TypeScript?

      Зачем? Я не то, чтобы какой-то адский фанат Flow, мне и то и другое по большей части по барабану, но это звучит как проект, в котором я не вижу смысла. На definitions, которые публичные, это никак не влияет. Наши внутренние типы всё равно будут другие, потому что то, как ты используешь React, отличается от того, как он реализован. Поэтому это звучит как большой проект, который не даёт для нас никакого выхлопа, и главное — для наших юзеров

      Мнения разные бывают, так что не удивляйтесь.


      1. Ilusha
        21.01.2022 15:28
        +1

        Вы меня просите, но я не понимаю, что вы хотите сказать. Разные ситуации, абсолютно разные позиции.

        Дэн говорит об бесполезности переписывания на ts, потому что там флоу. А ТС говорит о бесполезности ts.


  1. nin-jin
    21.01.2022 02:00
    +15

    Профессиональный React стек

    Экспертный астрологический прогноз. Ладно, ладно, сначала глянем что нам там посоветуют профессионалы..

    Redux — Central state management

    Привет, процедурное программирование вокруг глобальной переменной, замаскированное под ФП, порождающее горы тормозящего бойлерплейта.

    Redux-Saga — Async middleware для Redux

    Здравствуй, состояние гонки и гличи.

    Без SSR практически невозможно добиться хороших результатов в новой методике оценки сайтов от Google - Core Web Vitals.

    Смелое заявление. Проверять я его конечно.. буду:

    Как-то не густо для показа 10 карточек, десятка ссылок и поисковой формы. Которые, к тому же ещё и толком не работают. Но требуют 200КБ скриптов!

    Для сравнения, старая демка без SSR, с нормально работающим поиском, подсветкой найденного, фильтрами, сортировкой и 40 отображаемыми карточками:

    И всё это всего в 45КБ скриптов. Ну да ладно, пошли дальше..

    С надежной и производительной технологией Fast Refresh ... ценность юнит тестирования становиться совсем неочевидной. 

    Основная задача тестов - постоянно проверять, что ты не сломал что-то ещё, пока пилил то, что хотел. Скорость перезагрузки тут ни чем не поможет.

    если только у вас нет файлов с действительно сложной логикой. Но если они есть, то имеет смысл подумать про перенос этой логики на backend

    Привет, сетевые задержки на ровном месте, ибо фронтендер не осилил тесты.

    что может быть действительно полезным, так это функциональное тестирование интерфейса. Разработчику часто бывает сложно заметить, что радиус контейнера картинки составляет 2px вместо 4px

    Функциональные тесты проверят функциональность. Какую функцию выполняют скругления контейнера и почему радиус берётся не из константы и требует написания тестов?

    Typescript позволяет совершать меньше ошибок при разработке приложений.  Возможно, это так, но не стоит забывать про побочные эффекты, такие как менее читаемый код и дополнительный траблшутинг специфичных для Typescript проблем, который отнимает время, но не улучшает при этом само приложение

    Отладка таки допущенных ошибок отнимает куда больше времени. А если не хочется траблшутить - всегда можно написать any откатившись до Wild Wild JS.

    Typescript может быть полезен при разработке модулей для других разработчиков, так как это позволяет получить подсказки в стиле IntelliSense от IDE. Ценность Typescript при разработке конечных продуктов для меня менее очевидна.

    Конечные продукты всегда пилят программисты-одиночки, способные удерживать в голове проект любой сложности не ограниченно долгое время?


  1. jarvis
    21.01.2022 02:44
    +9

    Статья отлично иллюстрирует как используется современный фронтенд тулзы - столько всего, чтобы отобразить сайт с функционалом из 2009 года, при том что сейчас работает еще и медленнее!


    1. slaval_ch Автор
      21.01.2022 10:33
      -1

      Покажите пример другого стека с переводами и адекватным стейтом и удобным функционалом. Желательно конечно, чтобы было репо и демка, чтобы было удобно перенять чужой позитивный опыт. Всем будет полезно.


      1. DmitryKazakov8
        21.01.2022 16:25
        +2

        Пожалуйста - https://habr.com/ru/post/450360/ . Уже 3 года назад Redux и Styled-components были глубоким легаси, которые только затрудняют развитие приложения.

        Спустя 3 года и десятка энтерпрайз-проектов на подобной архитектуре я стал из ярого противника убежденным сторонником TS, а из сторонника реакт-хуков их ярым противником. Но React, MobX, CSS Components, Webpack и Babel прошли интенсивную проверку боем и продолжают на данный момент оставаться лидерами для старта энтерпрайз-проекта.

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

        Поэтому мои личные рекомендации - использовать для старта нового проекта именно этот стек + TS. Но подходы в той статье довольно устарели на мой взгляд, сейчас топлю за модульную архитектуру (lazy-load скриптов для каждой страницы, каждая из которых содержит модульные сторы и экшены), так как это лучше масштабируется при большом количестве страниц и разработчиков. Поэтому подумываю о сиквеле той статьи, но для этого сначала нужно завершить разработку вспомогательных библиотек.


        1. nin-jin
          21.01.2022 17:19

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

          Что, даже $mol едва ли приближается?


          1. DmitryKazakov8
            21.01.2022 22:18

            До него так и не добрались руки, как вижу this.$ \>= и т.п. , сразу в конец списка приоритетов по просмотру идет. Не то, чтобы было сложно разобраться - но семантичность это крайне важно для проектов, в которых участвую. Как и распространенность инструмента, экосистема, опыт разработчиков в этой системе. Также $mol - это комплексный фреймворк, я же ориентируюсь на кастомные решения в каждой из отдельных областей (рендеринг, роутинг, ssr, локализация, генерация, организация файлов и т.п.), потому что часто требуется кастомный функционал.

            Но это все пальцем по воде, в бою ваш фреймворк не использовал, поэтому нет какого-либо сформированного мнения. Но попробую, когда будет свободное время.


            1. nin-jin
              21.01.2022 23:04

              Вот как раз с семантичностью у $mol всё в порядке. Чего только стектрейсы стоят:

              $mol - не комплексный фреймворк, а набор микромодулей, любым из которых можно использоваться независимо. В частности:

              • рендеринг - $mol_dom_render

              • роутинг - $mol_state_arg

              • ssr не требует особых приседаний

              • локализация - $mol_locale

              • генерация - чего? если HTML, то $mol_view / $mol_jsx

              • организация файлов - MAM

              • и так далее.


              1. DmitryKazakov8
                22.01.2022 19:30
                +1

                Попробовал запустить локально, но наткнулся на море багов. Все по туториалу сделал, перезапускал сервер и перезагружал страницу несколько раз - пустая. Потом удалил папку my, внезапно страница my/hello заработала. Пересоздал папку с другим неймспейсом - пишет что найти неймспейс не удается. Любые изменения в файлах не подтягиваются. Создал чистую папку с инсталляцией чистого hyoo-ru/mam.git, почему-то локальный сервер стал показывать что папка my/hello существует и видимо из какого-то кеша подгружает файлы из соседнего проекта. Дальше возиться смысла не вижу, пока версия библиотеки не станет достаточно протестированной (у меня свежий linux и море проектов на других фреймворках, которые запускаются без багов и танцев).

                Тем не менее, посмотрел базовое описание и примеры - в них мне явно не подходит:

                • локализация в json, нужна ts-типизированная

                • процессинг стилей через postcss-cssnext вместо CSS Modules с кастомными плагинами транформации

                • дефолтное форматирование без ESLint и Prettier с кастомными энтерпрайзными правилами, прикрутить их будет непросто, т.к. много кода автогенерируется

                • http протокол локальной разработки

                • много автоматизированной "магии". Как правило мне нужен только рендерер в DOM с лайфциклом и совместимость с большим количеством opensource библиотек (компоненты, графики, таблицы, визуальные редакторы и т.п.). Архитектурные моменты с нужным функционалом как правило просто прикручиваю свои с дописыванием коннектора к рендереру.

                • негибкая структура файлов

                Это чисто по чтению базовой документации, как сказал выше потрогать все это не получилось. У кого-то может и заведется и он будет готов все с нуля создавать под новые проекты, но даже при поверхностном взгляде это совсем не продакшен решение.


                1. nin-jin
                  22.01.2022 20:18

                  перезапускал сервер и перезагружал страницу несколько раз - пустая

                  Вангую, что надо было просто выключить кеш в девтулзах.

                  локализация в json, нужна ts-типизированная

                  В коде тексты пишутся на английском, потом оттуда они экстрактируются в JSON и передаются в сервис переводов.

                  процессинг стилей через postcss-cssnext вместо CSS Modules с кастомными плагинами транформации

                  Там нет ни того, ни другого. Стили пишутся в TS.

                  дефолтное форматирование без ESLint и Prettier с кастомными энтерпрайзными правилами, прикрутить их будет непросто, т.к. много кода автогенерируется

                  Не распарсил. Кто где генерируется?

                  http протокол локальной разработки

                  А это о чём?

                  Как правило мне нужен только рендерер в DOM с лайфциклом и совместимость с большим количеством opensource библиотек (компоненты, графики, таблицы, визуальные редакторы и т.п.)

                  В $mol довольно богатая стандартная библиотека компонент. Любые сторонние прикручиваются элементарно - берёте this.dom_node() и делаете с ним, что хотите.

                  негибкая структура файлов

                  Какой гибкости не хватает?


                  1. DmitryKazakov8
                    22.01.2022 22:56
                    +1

                    Может и браузерные кеш, но чтобы его не надо было отключать можно было бы contenthash дописывать к файлам.

                    Локализацию предпочитаю писать в отдельных тс-файлах с константами, после чего они прогоняются через шаблонизатор со всеми нужными удобствами, а в систему локализации попадают в шаблонизированном виде - держать тексты, даже дефолтные, в коде разметки - строгое табу в тех проектах, которые делаю.

                    Стили в TS малопривлекательная идея, т.к. реимплементируют функциональность, которая проработана в многочисленных препроцессорах и плагинах. Styled-components как вариация - это ад. Стили должны быть отдельными для эффективного кеширования и не включаться в скрипты, раздувая их размер и ухудшая перфоманс.

                    Генерируются js-файлы из стилевых и шаблонных. Сами стилевые и шаблонные имеют синтаксис, вряд ли поддерживаемый ESLint, Prettier, Stylelint. Опора на .editorconfig в проектах, в которых участвует не один разработчик не приводит к консистентности и не налагает достаточного количества ограничений. Переформатирование же сгенерированных файлов на precommit приведет к большим расхождениям между тем, что локально у человека, и тем, что в гите.

                    Про http имел в виду что таков дефолтный протокол для localhost - возможно, во фреймворке есть возможность включить https, но я, как говорил, не добрался до более глубокого изучения. Нужно это для одинаковой среды между локальным сервером и стендом.

                    Стандартная библиотека компонентов подойдет для маленькой CRM какой-нибудь студии, в крупных проектах требуется мощь Material UI или Antd, которые экономят громадное количество времени на разработку и легко интегрируются в Figma/Zeplin дизайнерами.

                    Под гибкостью я имел в виду свободу в организации файловой структуры. Может быть тут и есть import для подключения отдельных слоев (глобального апи, сторов, экшенов), но опять же я не добрался до архитектурных проб.


                    1. nin-jin
                      23.01.2022 01:01

                      Может и браузерные кеш, но чтобы его не надо было отключать можно было бы contenthash дописывать к файлам.

                      Зачем засирать кеш, если достаточно один раз поставить галку?

                      держать тексты, даже дефолтные, в коде разметки - строгое табу

                      Это какое-то религиозное убеждение делать лишнюю работу или есть какая-то рациональная причина?

                      Стили в TS малопривлекательная идея, т.к. реимплементируют функциональность, которая проработана в многочисленных препроцессорах и плагинах

                      В каких таких препроцессорах и плагинах вы видели тайпчек стилей по иерархии владения компонент а так же семантичные имена классов с гарантией отсутствия конфликтов?

                      Стили должны быть отдельными для эффективного кеширования и не включаться в скрипты, раздувая их размер и ухудшая перфоманс.

                      И скрипты, и стили обновляются как правило вместе. Объём стилей не такой уж и большой получается - несколько килобайт. Выносить их в отдельный бандл, создавая дополнительную точку отказа, нет особого смысла.

                      Генерируются js-файлы из стилевых и шаблонных. Сами стилевые и шаблонные имеют синтаксис, вряд ли поддерживаемый ESLint, Prettier, Stylelint.

                      Какая разница как там отформатирован сгенерированный JS-код? Глазами вы его обычно не видите.

                      Опора на .editorconfig в проектах, в которых участвует не один разработчик не приводит к консистентности и не налагает достаточного количества ограничений.

                      Для любителей бондажа там есть настройки форматирования для VSCode. Впрочем, вы тут акцентируете внимание на совершенно не значительных вещах.

                      Про http имел в виду что таков дефолтный протокол для localhost - возможно, во фреймворке есть возможность включить https

                      Фреймворк-то тут при чём? Дев-серверу TLS не нужен. Если очень хочется - всегда можно поднять локальный прокси для ходьбы на локалхост через TLS.

                      Нужно это для одинаковой среды между локальным сервером и стендом.

                      Что дев-сервер забыл на стенде?

                      Стандартная библиотека компонентов подойдет для маленькой CRM какой-нибудь студии, в крупных проектах требуется мощь Material UI или Antd

                      В чём же заключается их мощь?

                      Под гибкостью я имел в виду свободу в организации файловой структуры. 

                      Вам эта свобода нужна чтобы что?

                      Может быть тут и есть import для подключения отдельных слоев (глобального апи, сторов, экшенов), но опять же я не добрался до архитектурных проб.

                      В $mol используется концепции каналов и инверсии контроля, так что никаких глобальных апи, сторов, экшенов и прочего непотребства тут не нужно.


                      1. DmitryKazakov8
                        23.01.2022 15:58

                        Кеш можно и не перегружать, но корректный hot-reload без дополнительной возни обязателен.

                        Тексты в разметке - всегда боль. Когда они хранятся в отдельных ts-файлах, как я сказал, можно их прогонять через любой шаблонизатор с нужными функциями, а при удалении ключей ругнется TS, при добавлении же неиспользуемых - ESLint. Так ли приятно видеть скажем проект, в разметке которого масса арабских или китайских слов? Но всегда приятно, когда видишь семантическое `{getLn(messages.buttonReset)}`. И в сторах, и в разметке, и в экшенах, и в сайд-эффектах это основа проекта, нацеленного на распространение в другие страны.

                        Семантичные имена классов с гарантией отсутствия пересечений - CSS Modules, где класс `.table` будет преобразован например по маске `[folder]_[name]-[hash:4]` и в итоговом коде будет `.ModalProduct_table-1234`. При этом в коде это будет просто `{styles.table}` с любым семантичным ключом, не ограниченным фреймворком. Тайпчек для css - однозначно лишнее, все проекты, в которых мы пробовали типизировать стили, в итоге приходили к мысли о бесполезности этого.

                        Точка отказа в файле стилей - это что-то новенькое, не сталкивался ни разу. CSS-файл обычно загружается параллельно с js и выполняется раньше него, улучшая метрики сайта. Также благодаря постпроцессорам типа CSSO стили эффективно преобразуются и размер их кардинально уменьшается, а за счет параллельной обработки браузером увеличивается скорость при открытии других страниц и при добавлении элементов на страницу, когда браузер уже знает как отображать новый элемент, а не получает инлайновый `style`.

                        Весь код в проекте должен быть в едином формате для простоты чтения и консистентности между разными разработчиками - это относится и к стилям, и к шаблонам, и к логике. Файлы должны переформатироваться при сохранении и на пре-коммит, чтобы гит-база содержала только консистентные данные. Это очень значительно для любого, кто занимался разработкой не в "соло".

                        VSCode - один из многих IDE, намного эффективней выносить правила в ESLint, который поддерживается широким спектром редакторов и может выполняться на CI для проверки консистентности форматирования и стиля кода.

                        Если локальная разработка на http, а стенды на https, то могут возникать определенные расхождения в работе приложения. К тому же стенд бэка, из которого локальный разработчик берет данные, может содержать специфические правила безопасности - часто на бэке длинная цепочка прокси-серверов, и то, в каком протоколе к ним обращаются, это важно. Да, можно настроить локальный nginx, не проблема, но дополнительная точка для документации, обучения, синхронизации.

                        Мощь готовых библиотек в соответствии функционала бизнес-требованиям. Широкий выбор библиотек и компонентов очень важен.

                        Свобода в организации файлов мне нужна для того, что жесткий подход в именовании файлов и их хранении - ограничение, которое может стать проблемой, как в том же Next.js, не позволяя совершенствовать архитектуру.

                        До каналов и инверсии я не добрался, но безусловно называть глобальные сторы и экшены непотребством - непрофессионально. Я разрабатываю в трехуровневом стиле: глобальные-модульные-локальные, из которых локальные - практически не используются, так как есть масса задач, когда контролировать компоненты требуется из-вне и часто на самом верхнем уровне (тот же онбординг).

                        Я понимаю, что все мы стремимся к идеальной архитектуре кода, но на мой взгляд вы давно свернули не в ту сторону, даже в самых базовых вещах, которые на мой взгляд и новичку должны быть понятны, мы расходимся. Как бы хорошо $mol ни работал в маленьких примерах и бенчмарках - в целом концепт очень навязчивый и ограничивающий, в стиле "а мы пойдем своим путем" вместо того, чтобы развивать и развиваться вместе с общим потоком фронтенд-разработки.


                      1. nin-jin
                        23.01.2022 19:05

                        Кеш можно и не перегружать, но корректный hot-reload без дополнительной возни обязателен.

                        Добавил, чтобы сервер требовал ревалидацию кеша. Больше таких проблем быть не должно.

                        Когда они хранятся в отдельных ts-файлах, как я сказал, можно их прогонять через любой шаблонизатор с нужными функциями

                        В $mol каждый текст вам доступен через отдельный канал. Он умеет динамически подгружать JSON бандл с локализацией на соответствующем языке, который экстрактируется из кода.

                        а при удалении ключей ругнется TS, при добавлении же неиспользуемых - ESLint

                        У нас сборщик ругается, если встречает лишние тексты. Если какого-то не хватает - фолбечится до английского.

                        Так ли приятно видеть скажем проект, в разметке которого масса арабских или китайских слов?

                        Там только английский.

                        Но всегда приятно, когда видишь семантическое {getLn(messages.buttonReset)}.

                        Семантично - это что-то типа $my_sign_in_reset_label

                        И в сторах, и в разметке, и в экшенах, и в сайд-эффектах это основа проекта, нацеленного на распространение в другие страны.

                        Зачем вам переводы в "сторах, экшенах, сайд-эффектах", если они нужны исключительно для отображения пользователю?

                        Семантичные имена классов с гарантией отсутствия пересечений - CSS Modules, где класс .table будет преобразован например по маске [folder]_[name]-[hash:4] и в итоговом коде будет .ModalProduct_table-1234.

                        Вот это вот 1234 имеет какую семантику? И чем оно отличается от 1235? Как переопределить стили у заголовка в компоненте карточки продукта на этой странице без повышения специфичности селектора, чтобы не ломать работу его псевдоклассов?

                        При этом в коде это будет просто {styles.table} с любым семантичным ключом, не ограниченным фреймворком.

                        В $mol этот бойлерплейт писать не приходится вообще.

                        Тайпчек для css - однозначно лишнее, все проекты, в которых мы пробовали типизировать стили, в итоге приходили к мысли о бесполезности этого.

                        У $mol_style так-то нет аналогов. Вообще. Такого уровня тайпчека вы не встретите больше нигде. А на тех всех проектах была не стат типизация, а лишь её видимость.

                        Точка отказа в файле стилей - это что-то новенькое, не сталкивался ни разу.

                        Ну а я приодически натыкаюсь, что сайт загрузися и пытается тебе что-то показывать, а стили - нет. Да, собственно, чего далеко ходить:

                        CSS-файл обычно загружается параллельно с js и выполняется раньше него, улучшая метрики сайта.

                        Это распаралленивание ничего не даёт, ибо показывать что-то пользователю мы можем лишь когда и то и другое прогрузилось. А вот нагрузка на всех участников процесса возрастает пропорционально числу запросов.

                        благодаря постпроцессорам типа CSSO стили эффективно преобразуются и размер их кардинально уменьшается

                        На фоне сжатия все эти "оптимизации" являются пустой тратой времени. Я вам больше скажу - у нас даже JS не минифицируется, но бандлы получаются меньше, чем любимый вами стек даже без прикладной логики.

                        счет параллельной обработки браузером увеличивается скорость при открытии других страниц и при добавлении элементов на страницу, когда браузер уже знает как отображать новый элемент, а не получает инлайновый style

                        Браузер получает stylesheet. Откуда он получен ему в принципе фиолетово. Более того, ему же проще, получить его сразу в виде CSSOM, а не парсить из текста. Опять же, даже с созданием этого стайлшита при загрузке, приложение на $mol грузится быстрее, чем пустая страница на React с параллельным парсингом ультраоптимизированного CSS.

                        Весь код в проекте должен быть в едином формате для простоты чтения и консистентности между разными разработчиками

                        А все разработчики должны ходить в пиджаках и брюках для консистентности перед начальством. Вы возводите в абсолют совершенно бессмысленные правила. Важно, чтобы код был ясным и понятным. Никакой автоформаттер не сделает ваш код более ясным для человека, чем это сделает сам человек. А вот испохабить его форматированием "по правилам" он может запросто.

                        VSCode - один из многих IDE

                        VSCode сейчас лучшая IDE для веб разработки. Поэтому с MAM в нём работать проще всего. Поддержкой других IDE сейчас заниматься некому, к сожалению.

                        намного эффективней выносить правила в ESLint, который поддерживается широким спектром редакторов и может выполняться на CI для проверки консистентности форматирования и стиля кода.

                        У меня вьетнамские флешбеки от зафейленных сборок из-за какой-то мелочи с форматированием. Да, собственно, чего далеко ходить:

                        Мощь готовых библиотек в соответствии функционала бизнес-требованиям.

                        Ни одна нетривиальная библиотека не будет соответствовать вашим требованиям на 100%. Поэтому важна кастомизируемость. А с этим у популярных фреймворков просто беда. В результате на доработки порой приходится тратить времени больше, чем на разработку с нуля. В $mol же мало того, что уже есть больше готовых библиотек, чем в любом другом UI-ките, так ещё и кастомизируются они куда проще.

                        Например, какие-нибудь ЯКарты - это мегабайт кода, монструозный апи и дикие ограничения по возможностям отрисовки. А $hyoo_map - это всего 50КБ кода и вся мощь $mol по кастомизации. Например, вот, взяли и прикрутили коллаборативное рисование на карте - бандл всгео 60КБ.

                        Свобода в организации файлов мне нужна для того, что жесткий подход в именовании файлов и их хранении - ограничение, которое может стать проблемой, как в том же Next.js, не позволяя совершенствовать архитектуру.

                        MAM очень слабо вас ограничивает: он лишь гарантирует, чтобы расположение сущностей соответствовало их именам. Странно, что вам, как любителю порядка и консистентности, это не по душе.

                        До каналов и инверсии я не добрался, но безусловно называть глобальные сторы и экшены непотребством - непрофессионально.

                        Не профессионально рассуждать о том, до чего не добрался. А процедурное программирование вокруг глобального дерева я, разумеется, пробовал. Для меня остаётся загадкой как такая тупая идея смогла захватить столько умов.

                        Я разрабатываю в трехуровневом стиле: глобальные-модульные-локальные, из которых локальные - практически не используются, так как есть масса задач, когда контролировать компоненты требуется из-вне и часто на самом верхнем уровне (тот же онбординг).

                        В $mol все компоненты хранят состояние по умолчанию локально, но при этом полностью контролируются владельцем, который может любое состояние как "поднимать", так и "опускать", и даже "сдвигать". Тут нет дилеммы между "контролируемыми" и "неконтролируемыми" компонентами. Это позволяет писать простой и ясный код, не теряя в гибкости и надёжности.

                        Онбординг, кстати, - это антипаттерн, который не работает так, как задумывается. Ибо пользователь хочет поскорее приступить к своим задачам и прокликивает этот онбординг не вникая. Но даже он на $mol реализуется гораздо проще, ибо в $mol, не смотря на инкапсуляцию, нет сокрытия. То есть вы легко можете достучаться до любого канала в приложении. И тайпскрипт всё это протайпчекает.

                        Как бы хорошо $mol ни работал в маленьких примерах и бенчмарках

                        На больших примерах он ещё лучше работает. Собственно, это сейчас единственный фреймворк, рассчитанный на экосистемы приложений и микросервисную разработку порталов. Ближайшим конкурентом был БЭМ, но он, считай, помер. Все остальные легко и просто смотрятся на каунтерах и привет-мирах, но чуть более сложное приложение и начинается ад.

                        "а мы пойдем своим путем" вместо того, чтобы развивать и развиваться вместе с общим потоком фронтенд-разработки.

                        Ну вот те, кто гнался за общим потоком сначала вкорячивали Flux и shouldComponentUpdate, потом переписывали всё на HOC и Redux, потом переписывали на Hook и MobX.. И судя по тому говнокоду, что людям приходится писать на хуках, это ещё не конец. Тем временем, в $mol как была абстракция реактивных каналов 6 лет назад, так никуда и не делась. Не смотря на то, что система реактивности дважды полностью переписывалась.


                      1. DmitryKazakov8
                        23.01.2022 21:24

                        JSON бандл как правило приходит через систему локализации, обычно удобнее получать данные через запрос к ней, а не загрузкой JSON, так как тексты - ответственность не разработчиков, а контент-менеджеров, поэтому в коде лучше держать только константы с базовым примером текста.

                        Только английский как основной не всем подойдет, это очередное ограничение.

                        $my_sign_in_reset_label - это что? Доллар-моя-подпись-в-сбросе-надписи? Доллар зачем, название страницы зачем? Если "для уникальности" - то пусть об уникальности заботятся инструменты.

                        1234 - это уникальный суффикс, не имеющий семантического значения, нужен для резолва исторически сложившегося глобального CSSOM, чтобы разруливать коллизии.

                        Переопределение стилей делается добавлением класса к компоненту, в Реакте например через проп <MyComponent headerClassName={styles.headerGreen} />, в самом компоненте в его class будет два класса - дефолтный и переданный, так не сломаются псевдоклассы.

                        Переводы в экшенах нужны для показа локализованной нотификации пользователю - например, каждый запрос к АПИ при фейле выдаст нотификацию (которая запускается через глобальный стор), но создавать на каждый запрос отдельный компонент нотификаций - это плохая практика, проще передать готовый текст через стор.

                        То, что не приходится писать {styles.table} - значит фреймворк решает за тебя, как будут называться классы, что является очередным ограничением. Кто-то может это назвать удобством - но нет, работа с именованиями классов это отдельное искусство, цель которого - дать ясное представление о структуре элементов на сайте и их взаимосвязях. Для этого нужна вложенность и семантика. Безиерархичные стили и автогенерируемые классы ухудшают читаемость и понятность.

                        Полный тайпчек стилей, если реализован грамотно, то может быть немного полезен, тут соглашусь. Но ценность этого довольно низкая, так как лишние стили лишь добавят немного размера файлам, не повлияя на работу сайта, и несложно находятся при рефакторинге.

                        Современные браузеры грузят ресурсы параллельно, и размер CSS как правило мал, особенно оптимизированного и сжатого, поэтому стили грузятся раньше скриптов, и нагрузка на браузер как раз снижается.

                        Размер бандла - хороший аргумент, с ним не поспоришь, как и со скоростью работы фреймворка, судя по бенчмаркам. Но это редко определяющие факторы при выборе. Если брать картину в целом то мой любимый стек выигрывает по более важным параметрам, а размер бандла при эффективном сжатии достаточно мал.

                        Ясный и понятный код у каждого свой. У одного это $.$$ { this.$ }, у другого yield* pipe(partial(sum, 1), multiply(3)).stream(), у третьего await StreamPipeUserControllerManager.emit('SuperLongNameFnFromThatModule'), у четвертого - императивный. И у каждого свое форматирование, табуляция, "лучшие практики", нейминг, длина строк, вложенность и т.п. Правила нужны для того, чтобы код оставался консистентным, согласованным и каждый человек не переписывал код другого человека под свое понимание понятности.

                        VSCode лучшая только для тех, кто к ней привык, и делать только для нее - как раз "заставлять ходить в брюках и рубашке", как собственно весь $mol и заставляет. "Только так, это самое лучшее, все остальное дно". Нет, не лучшее, а видение одного человека, опыт которого отличается от опыта всех остальных разработчиков.

                        Запрет на console.log в линтере - отличная практика, при необходимости сверху просто ставится // eslint-disable-next-line no-console. Увеличивает внимательность сотрудников, охраняет чистоту консоли. Не доводилось работать в проектах, которые при открытии консоли выводят несколько страниц кому-то когда-то нужного текста для разработки? Мне доводилось больше, чем несколько раз.

                        Кастомизируемость библиотек - это важно, рад, что в $mol есть хорошо кастомизируемые. Проблемы с библиотеками для Реакта бывают, и иногда весьма сложные. Но справиться можно со всем, изредка дописывая кастомные компоненты, это часть разработки.

                        Порядок и консистентность в файловой структуре - это отлично, только он должен создаваться соглашениями в команде, а не навязываться кодом. Код - продукт который делает команда, а не клетка, в которой они сидят. Подходы к форматированию файлов и паттерны написания кода - тоже корнями уходят в опыт и предпочтения команды. Хотя жесткие фреймворки освобождают от рутины синхронизации мнений, это подходит не всем. Я обычно высказываю в комментариях и статьях свое мнение о том, как должно быть все устроено, но в команде гибок и открыт для предложений, часто устраиваю глобальный рефакторинг проектов для того, чтобы он более соответствовал требованиям бизнеса и запросам коллектива. С $mol либо так, как видит его создатель, либо никак. С Реактом как правило всех устраивает html-подобный синтаксис и жизненный цикл, а все остальное - гибкое.

                        Отсутствие сокрытия состояния и глобальный доступ - это и есть глобальность. Когда можно вызвать тултип или нотификацию из любого места, провалидировать форму до перехода на другую страницу, сделать серию модалок, каждая из которых будет иметь доступ к данным предыдущей. При необходимости, разумеется. Если такое есть в $mol то может быть в этом пункте мы сходимся, только для меня состояние - это observable объект, а "канал" - функция изменения этого объекта из любого места. Каждое изменение рассылается тем компонентам, сайд-эффектам и геттерам, которым оно нужно. Этих концептов хватает для построения приложения любой сложности.

                        По поводу подходов к хранению состояния, подпискам на него и методов работы с жизненным циклом Flux, HOC, Redux, Hooks, MobX - лестница развития фронтенд-разработки. Где-то ступеньки приводят не туда, где-то возвращают на путь к идеальной архитектуре, и конца этого пути пока не видно - мы свидетельствуем начало кроссплатформенного программирования интерфейсов, и недостатков много и в CSS+HTML+JS, и в подходах с их использованием. Вполне возможно, что и вы со временем кардинально пересмотрите подход к фронтенду, по мере развития технологий всеобщими усилиями.


                      1. Ilusha
                        23.01.2022 19:17

                        Влезу в ваш диалог с вопросами по локализации.

                        Скажите, Вы реально работаете с проектами, где default locale - не английская?

                        Я много работал с локализациями и пришёл к выводу, что удобнее всего комбинированный подход:

                        • Локали можно объявлять по месту использования

                        • Локали можно объявлять в отдельном файле

                        id - или явный, или автоматический. Явный id меньше мешает рефакторингу, если не хранить историю изменений суррогатного.

                        А всю "магию" делает тулинг: вытаскивает в json всю инфу. Так мы всегда видим неиспользуемые локали. Дефолтная является технической: она тоже уходит в систему переводов. И уже подгружаемая подключается для пользователя.

                        Юзаю formatjs


                      1. DmitryKazakov8
                        23.01.2022 20:18

                        Да, были проекты с дефолтной локалью на русском и арабском. Если в отдельном файле хранить - то id можно генерировать из __dirname - соответственно не будет пересечений с другими файлами и из такого id можно по большей части понять, где текст используется.

                        А как вы генерируете из разметки json-файл, если объявляете тексты по месту использования? Он попадает туда в шаблонизированном виде, который удобен для добавления склонений, множественного числа, переводов строк, форматов дат? Суть объявления в отдельных файлах как раз удобство генерации id, преобразования в json и контролируемых шаблонах, которые можно отредактировать в системе локализации.

                        В целом да, дефолтный текст уходит в систему переводов, а финальный приходит через апи-запрос при смене языка, это довольно эффективная схема.


                      1. Ilusha
                        23.01.2022 22:04

                        Вы реально для арабского языка не использовали дефолтный русский/английский вариант? Это не усложняло разработку?

                        В коде пишем:
                        $formatMessage({
                        id: 'id', // или автогенерация, функцию для которой можно переопределить
                        message: 'ICU_MESSAGE format',
                        description: 'опциональное описание, которое можем отдать переводчику'
                        }, { /* здесь передаем параметры, если есть */ })

                        Если хочется отдельным файлом, то просто объявляем объект с доступом по ключу:

                        const messages = defineMessages({
                        greeting: {
                        id: 'app.home.greeting',
                        description: 'Message to greet the user.',
                        defaultMessage: 'Hello, {name}!',
                        },
                        })


                        Для дат, чисел, валют и т.д. есть свои форматеры.
                        $formatNumber(3, {style: 'currency', currency: 'USD'})

                        Тулинг либы formatjs:
                        extract: в базовую локаль, которая уходит в систему переводов. Здесь хоть место в файле указывай.
                        compile: plane object 'id': 'ICU Message'. Или ast.

                        https://formatjs.io/

                        В коде объявлять имеет эффекты:
                        - пухнет шаблон
                        - все перед глазами: не нужно переключаться на контекст файла с текстами
                        - у нас гарантировано удаляются неиспользуемые локали


                      1. DmitryKazakov8
                        23.01.2022 22:25

                        Понятно, да, если прогоняется все через функцию - тогда вытянуть тексты не проблема. Когда я имел в виду "держать тексты в шаблонах" подразумевал просто писать "some text" без функции. В вашем подходе не вижу недостатков - можно хоть в шаблоне, хоть в отдельном файле. Я обычно не использую сторонних инструментов и пишу просто

                        export const messages = wrapMessages({
                          hello: 'Hello {user}',
                        })

                        а айди формируется автоматически из __dirname. Для экспорта в любую систему локализации - либо пробежаться по всем этим файлам простой регуляркой, либо выполнить во всех этих файлах wrapMessages, подменив ее функционал на JSON.stringify. Так получится JSON с [{id: 'pages/user/accordion.hello', value: 'Hello {user}'}] , что можно загрузить в любую систему локализации. В коде в соответствии с веткой и локалью запрашивается готовый JSON и кладется в стор, который уже является источником правды для текстов в коде. Если там значения нет - то выводится дефолтный текст из объекта выше.

                        С арабским у меня проблем не было, владею им) А так - для какого заказчика разрабатываешь, на таком языке как правило и дефолтные тексты. Неудобства не испытываешь, т.к. имена констант все равно на английском.


                      1. faiwer
                        23.01.2022 16:40
                        +1

                        Зачем засирать кеш, если достаточно один раз поставить галку?

                        Поведение браузера с "disable cache" и без очень разное. Гораздо лучше работать локально без неё, чтобы потом не заниматься отловом cache-based багов на тестовом сервере или проде.


                        Всё таки кеширование это сложный и неотъемлемый элемент веб-разработки. Чем ближе ваше дев-окружение к настоящему, тем меньше граблей вы соберёте в проде.


                      1. Alexandroppolus
                        23.01.2022 17:22

                        Гораздо лучше работать локально без неё

                        Пробовал - не понравилось. Дебажиться очень трудно, меняешь код, а поведение не меняется, и это выносит мозг.

                        Про cache-based баги лучше подумать отдельно.


                      1. faiwer
                        23.01.2022 17:30

                        Пробовал — не понравилось.

                        Собственно причиной тому у вас, скорее всего, было то, что cache на уровне dev просто непродуман. В идеале он может быть устроен почти также как и в prod-е


                        Про cache-based баги лучше подумать отдельно.

                        Они бывают слишком хитрые. Я столько этого наелся (всякие CDN, CORS, и просто двойные загрузки), что прямо "нафиг-нафиг". У меня доходило до дебага https2 запросов через wireshark.


                      1. nin-jin
                        23.01.2022 19:23

                        Поведение браузера с "disable cache" и без очень разное.

                        Именно, и быстро переключается одной галкой. Вообще, я стараюсь по максимуму задействовать нативные девтулзы, а не лепить сбоку какие-то кастомные.


                      1. faiwer
                        23.01.2022 19:50
                        +1

                        Я понимаю, как вы пытаетесь это подать, но снаружи это выглядит скорее так:


                        • для работы в dev-режиме необходимо отключать кеш (и, соот-но держать дев-тулзы открытыми)
                        • для dev разработки на мобилке нужно пробрасывать adb и отключать кеш на десктопных дев-тулзах
                        • о реальных кеш-related проблемах узнавать уже с прода (в худшем случае не узнаёте)
                        • разработка чего-то с прогревом кеша — постоянно toggle-ить галочку "disable cache"

                        И при этом это называется не "мы пока не довели до ума dev-кеширование", а "стараюсь задействовать нативные тулы".


                        Дело ваше, конечно.


                      1. nin-jin
                        23.01.2022 20:14

                        На проде у вас один сервер, выдающий одни хттп-заголовки для статики. В деве у вас другой сервер, выдающий другие хттп-заголовки для статики. Дополнительно, на проде скорее всего статика раздаётся не напрямую, а через прокси какого-нибудь CDN. А локально вы через него не ходите. На проде одни тайминги, а локально абсолютно другие.

                        Так что давайте не фантазировать про приближенность локального дев-сервера к проду. Для этого обычно поднимается тестовый контур на продовой инфраструктуре.


                      1. faiwer
                        23.01.2022 20:25

                        Вы как-то всё очень сильно упростили. На моём проекте всё куда сложнее. Но спорить не буду, у каждого своя правда. Я сыт по горло от этой "disable cache" и никому её не рекомендую, кроме очень узких кейсов, когда надо "срочно", а кеш "мешается и не связан с задачей".


        1. canishoryuken
          21.01.2022 20:07

          А почему стал противником хуков? Хуки же реально проще для понимания, чем работа с классовыми компонентами.


          1. Ilusha
            21.01.2022 21:55
            +1

            Влезу в ваш разговор.

            Проще для понимания маленьких и простых компонентов. Потом есть "средний размер и функционал", где хуки превращаю код в кашу.


          1. DmitryKazakov8
            21.01.2022 22:32
            +1

            Вот в этих комментариях описывал:

            https://habr.com/ru/post/534632/comments/#comment_22459664

            https://habr.com/ru/company/ruvds/blog/507518/comments/#comment_21763020

            https://habr.com/ru/company/skillfactory/blog/539068/comments/#comment_22619868

            https://habr.com/ru/post/565904/comments/#comment_23221032

            https://habr.com/ru/post/586526/comments/#comment_23656254

            В первом же крупном проекте который делал на хуках пришлось писать длинные цепочки их вызовов с учетом результатов выполнения каждой (для сложного селекта и для онлайн редактора кода), что даже после нескольких итераций рефакторинга выглядело пугающе, в отличие от удобной компоновки в методах класса. Потом пришлось бороться с постоянным потоком ошибок от коллег-разработчиков в оптимизации и равенства по ссылкам при использовании длинной лестницы вложенных хуков. Это стало основными причинами нелюбви, к которым добавились впоследствии те, что описал в комментариях выше.


            1. Alexandroppolus
              21.01.2022 23:52

              Сложная логика на хуках выглядит кошмарно, согласен. Все эти обвесы useCallback и проч.

              Мне нравится такой подход: логика уезжает в классы (некоторые из них - сторы мобх). Экземпляры классов хранятся в рефах, то есть живут, пока жив компонент-владелец. Могут прокидываться вниз через контексты. А хуки - только как связующее звено: создание/хранение экземпляров, резолв зависимостей, очистка перед удалением, контексты. Гибкая схема, на основе которой можно всякое мутить без лапшекода, нормально декомпозировать и легко писать юнит-тесты как на логику, так и на компоненты.


  1. slaval_ch Автор
    21.01.2022 10:34
    -7

    Любопытно сравнить отношение к чужому труду тут и на международном medium


    1. Sadler
      21.01.2022 23:48
      +4

      Ваш труд, то есть мнения, ценны тем, что они имеют отношение к истине, а не априори потому, что озвучены. Выходите из информационного пузыря и учитесь отстаивать своё мнение, если уж высказываете что-то столь непопулярное.

      Если убрать из статьи категоричность, то стек как стек: я бы писать на таком не стал, но каждый кодит как он хочет.


  1. slaval_ch Автор
    21.01.2022 10:40
    -6

    Что еще удивляет, почему 40+ пользователей добавили статью в закладки, но не поставили +. Если вы хотите использовать результат работы другого человека, ну уделите хотябы 5 секунд, чтобы сказать "спасибо".


    1. Xop
      21.01.2022 11:03

      Возможно добавившие в закладки не имели достаточной кармы, чтобы поставить плюс?


      1. slaval_ch Автор
        21.01.2022 11:14
        -1

        Очень странно. Т.е кому статья не нравится, у тех есть карма ставить минус, а кому полезна, те не могут поставить +.
        Есть интересно у Хабра канал для обратной связи. Это уже совсем косаяк PM такой вот user interaction реализовать.


        1. Ostic
          21.01.2022 13:57

          Есть "мэйнстрим" и их не волнует, что разработчики React просто смеются, когда слышат "стэйт менеджер", ну типа, была такая тема для конференции и про TS они ничего слышать не хотят, но только снисходительно улыбаются. Посмотрите интервью Интервью Наталии Теплухиной с Дэном Абрамовым + подкаст на Вебстандартах с ним есть, но это никого не убедит не смотря на то, что это, как бы разработчики собственно React и масштабы приложений у них high-end. Притом, что я интересом прочитал статью буквально за пару минут интереса ради. В чем-то согласен, в чем-то нет.


  1. RiverFlow
    21.01.2022 11:27
    -5

    Реакты - дно, некст - тем более, редукс - муть а статья - легаси-рефлексия.

    Но все плюсы что есть отдаю за верные слова о тайпскрипт.

    Всё остальное в мире жс можно принять с улыбкой или слепой но тайпскрипт, его не здоровое лобби это злючий мрак который должен уволили в свою ООО дыру и сдохнуть, вот тогда он действительно сделает то о чем поют его сторонники: наконец-то поможет программистам жс!


    1. Alexandroppolus
      21.01.2022 20:09
      +1

      все плюсы что есть отдаю

      )) тонко!


  1. canishoryuken
    21.01.2022 20:00
    +6

    Не, ребят, серьезно, это уже чересчур. В 2022 писать, что TypeScript это хайп - это просто мракобесие какое-то.