All streams
Search
Write a publication
Pull to refresh
3
0
Send message

не всегда хочется поднимать глобальное хранилище

Зачем? Если нужно локальное, просто используйте локальное. Вот так:

const MyCompoent = observer((props: IMyCompoentProps) => {
  const [state] = useState(() => MyCompoentLocalState(props));
  state.props = props;

  return <div>123</div>
});

И все дела.

прописывать сторы, экшены и т. д.

Зачем эта грязь? Все автоматом делается.

class MyCompoentLocalState {
  props: IMyCompoentProps = null; 
  
  constructor(props) {
    makeAutoObservable(this);
    this.props = props;
  }
  
  someFunction = async () => {
    //...
  }

  someFunction2 = () => {
    //...
  }
}

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

Server Components призваны минимизировать клиентскую часть и ускорить загрузку.

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

Где найти пример классической архитектуры для больших проектов?

Вот же https://habr.com/ru/articles/867232/comments/#comment_27683716

На setTimeout? Надеюсь нет.

Какое отношение setTimeout имеет к работе с данными форм? А что за жалкая попытка высмеять setTimeout? Типо ха-ха-ха он знает, как все устроено и с помощью него может решить проблему которая может помешать писать удобный код..

Понятно, статью вы не читали.

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

Ну если вы не утверждаете истину, тогда спор окончен. Засчитано как слив.

Классика. Найти любой предлог чтобы избежать неудобства любого уровня. Мама попросила помыть посуду, и вдруг опа, сразу ты "захотел" кушать, или вдруг книжку "решил" почитать и т.п. Учитель попросил после уроков помочь убраться в классе, а у тебя тут как тут "живот заболел". Только вот незадача, вы уже вроде как взрослый человек, а приемы все те же.

Рассуждать в таком духе — это либо токсичность, либо ЧСВ за пределами разумного

Вы говорите - писать "велосипеды" плохо. А я говорю что нет. Если я имею своё мнение, то я токсичный и ЧСВшник? Ясно. Более того, прикрываются "велосипедами" в 99% случаях плохие программисты, и снимают с себя ответственность за то или иное решения, спихивая всё на: "ну это библиотека плохая, а не я" или "Я не могу это сделать, потому что в этой библиотеке это не предусмотрено" или "мы не сможем это сделать, потому что я не нашел библиотеки никакой" и т.д. и т.п.

И как раз самая ярая защитная реакция у таких "программистов" это высмеивание "велосипедов". Например, меня не устраивает ни одно решение из готовых для работы с формами и валидацией. Вон ни одно. И что мне делать? Терпеть и взять готовое?
Ну нет, я то как раз программист, и я сделал свое решение и подход(пользуюсь им больше 6ти лет) которое меня более чем устраивает и гораздо удобнее и гибче в использовании, чем ваши "проверенные решения".

Вы действительно считаете, что "думать головой" — это изобретать велосипеды там, где уже есть проверенные решения?

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

Вы не Бог, чтобы решать, кто "достойно" работает в профессии, а кто нет.

Если вы не заметили, то фраза "Ой, думать головой это так ужасно. Это не достойно профессии программиста." это сарказм, описывающий ваше мнение, просто более открытой форме, а не моё.

Если вам не нравится MST, это ваше право, но превозносить своё мнение как истину в последней инстанции — это уже перегиб.

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

Но для сложных приложений, где требуется отладка, undo/redo или работа с состояниями, это полезная функция

Ну и классическая вишенка на торте это то, что именно у вас "сложные" приложения и только вы по настоящему большие и сложные вещи делаете, и вот им то кровь из носа нужна та или иная шелуха, а вот все остальные никогда ничего сложного не делали, поэтому у них все так просто. Мы сами не можем сделать undo/redo, сами знаете почему, ведь у нас сложные задачи, а undo/redo это ещё сложнее, это ж надо целых пару часов убить чтобы реализовать. Но это не наш путь, мы будем искать только готовые и "проверенные решения", пускай кривые косые, медленные и выжирающие всю память, но зато их написал кто-то другой, а он то точно лучше знает что нам надо, мы то не знаем.

Программист решает задачи бизнеса

А Evan You кто? Черепашка? Ну уж явно не программист, ведь он велосипеды пишет. Написал какой-то Vue когда есть реакт, ангуляр и т.п. Написал какой-то Vite когда есть webpack, rollup и т.п. Ну точно черепашка, ибо нормальный человек такое делать никогда не будет, да?

Да, MST может "завалить" приложение, если с бэка приходит некорректный тип данных

Он его не "завалит", а завалит. Это уже достаточно чтобы косо смотреть на эту поделку. Плюс сам по себе код и подход так себе, по сравнению с MobX.

На самом деле у MobX и MST один и тот же создатель — Михель Вестстрат

И что? Мне сам по себе создатель не внушает никакого уважения и доверия, можно посмотреть на код как он пишет и ужаснуться. Плюс многие примеры в документации ужасны. И пользоваться MobX'ом так, как показано в примерах так себе затея, можно гораздо лучше.

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

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

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

Да, а теперь возвращаемся в реальный мир, и это прям сверх распространенная ситуация когда бэк тебе может прислать вместо '' скажем null или вообще не прислать это поле. А у тебя логика на фронте простая,

{item.price && <div className={styles.price}>{item.price}</div>}

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

Да, всё это можно сделать и на чистом MobX, но в таком случае вы рискуете создать собственный "велосипед"

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

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

Typescript? Не, не слышали.

Снапшоты и путешествия во времени

Такой же "аргумент" всегда приводился в "пользу" redux. И он максимально абсурден и смешон. Ибо в реальности в 99.9999% не нужен никому, а в остальных случаях все равно из коробки работает не так, как тебе именно надо. Потому что тебе нужны совершенно конкретные вещи запоминать для undo/redo, а для этого супер легко и супер быстро пишется логика, и если для вас это целая проблема, то что тут можно теперь поделать.

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

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

Почему?

Ну во первых MobX это максимально нативный код:

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

Чего не скажешь о MST:

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

Во вторых MobX не рушит тебе приложение, когда его можно не рушить, т.к. в нем нет проверок в рантайме на "модель" .
Самый типичный пример:

Приложение в проде, с бэка пришла цента вместо number => string или наоборот, вместо string => number. А мы в карточке товара просто выводим эту цену. Так вот, в случае с MobX все будет ок, а в случае с MST все приложение просто упадет.
Да, это ошибка с точки зрения нарушения контракта бэком, но ошибка ошибке рознь, в данном случае она не критичная и по большому счету ни на что не влияет и не является поводом чтобы завалить прод.

Вот код:
https://stackblitz.com/edit/vitejs-vite-we3busph?file=src%2Fmain.ts&terminal=dev
И результат, кода что выше

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

MST (MobX State Tree) 

Это плевок в лицо MobX'a. Уж тогда лучше оставались бы с редаксом или заменили на любую другую дичь, раз вы не рассматриваете человеческие варианты.

По поводу использования FSD в крупных проектах, могу предложить как вариант монорепу с N-ным количеством небольших FSD приложений и разрулить потом всё через, например, ModuleFederationPlugin в сборщике.

Oh my dear god... куда катиться этот мир. Неужели мы обречены

Вопрос о идеальной архитектуре скорее риторический

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

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

Не понял вообще проблемы, ну есть у вас общая логика, вынесете ее в виде отдельного компонента в src/components/MainForm и все, на всех страница где нужна эта форма берите ее. Это же интуитивно понятно.

Решение зависимостей через SetTimeout выглядит слегка костылём, когда других вариантов не нашлось.

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

Не совсем понимаю, о каких сложностях идёт речь. FSD концепции довольно просты для понимания

entities, features, widgets вообще прям все "просто" и "понятно" и голову ломать не надо каждый раз, ага. И прям "легко" по коду проекта искать то, что тебе нужно. Вместо того что страницу положить в ее законное место, мы будем разность ее по частям по разным папкам. Ну бред же.

Если методология отступает от концепций очевидного наименования логики, она сразу становится нежизнеспособной?

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

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

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

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

А если они скажут что есть и пить это плохо, да и спать тоже, что тогда?
Вы понимаете что апеллировать к "авторитетам" это прям скажем странно. Ибо во первых они авторитетами даже близко не являются, во вторых это не точные науки, где 2 + 2 = 4 и это можно легко проверить и однозначно в этом убедиться.

А плюсы же очевидны и просты, если модулю A нужно что-то из модуля B, ты просто берешь это и всё. Даже если A <--> B имеют зависимость друг от друга, то все решается просто, зависимости не должны вызываться синхронно в момент инициализации, достаточно сделать setTimeout и все. А если в момент инициализации синхронно никто никого не дергает, а дергает в процессе, то тем более никаких проблем.

к некой "классической" архитектуре

Ну она же на то и классическая, что вполне себе стандартная на уровне интуитивных вещей. Базовый вид:

src/
    components/
        Button/
            index.tsx
            styles.scss
    config/...
    constants/...
    globalState/
        userState/
            index.ts
    helpers/...
    lib/...
    hooks/...
    layouts/
        mainLayout/
            index.tsx
            styles.scss
      authLayout/...
    routes/...
    pages/
        login/
            index.tsx
            state.ts // Локальный стейт страницы
            styles.scss
        items/
            components/
                component1/
                    index.tsx
                    state.ts // Локальный стейт компонента
                    styles.scss
                component2/...
            index.tsx
            state.ts // Локальный стейт страницы
            styles.scss

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

Согласен с тем, что бывают проблемы с тем, в какой слой (entities, features или widgets) положить модуль, однако не вижу проблемы в том, чтобы единожды договориться об этом внутри команды и следовать договорённости.

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

Ну и опять же к чему все эти сложности на ровном месте? Когда на самом деле все предельно просто.

Не делал ни когда computed'ы зависящие от props'ов, но да и правда warning вылезает в консоли, правда только один раз и в при этом ничего не сломалось, но в целом да, чтобы этого избежать можно это в useEffect поместить. Спасибо что осветили данный нюанс.

Проверочный стэнд:
https://stackblitz.com/edit/vitejs-vite-fxmdw8?file=src%2Fpages%2Fmain%2Findex.tsx&terminal=dev

А с конфигом с автобатчингом этого эффекта нет:
https://stackblitz.com/edit/vitejs-vite-dnuzdw?file=src%2FmobxConfig.ts&terminal=dev

Не могли бы вы подсказать альтернативу

MobX разумеется, в 2017 году уже это было очевидно.

Причем это не просто альтернатива, это единственное решение из всех что есть, для связки с React'om где у вас не будет кровь из глаз идти, где вы будете писать минимально возможно кол-во кода и т.д. и т.п. И MobX нужно использовать и как глобальное состояние и как локальное(у компонента).

Спойлер:

interface IMyComponentProps {
  color: 'black' | 'white';
  count: number;
}

export const MyComponent = observer((props: IMyComponentProps) => {
    const [state] = useState(() => new MyComponentLocalStae(props));
    state.props = props;
    
    return <div onClick={state.incr}>Hello world ${state.counter}</div>
});

class MyComponentLocalStae {
  counter = 1;
  
  constructor() {
    makeAutoObservable(this);
  }

  incr = () => {
    this.counter++;
  }
}

Redux идеален, если у вас сложное приложение с кучей состояний

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

Есть такая штука, с которой у вас вообще не будет проблем от слова со всем, как в громадных приложениях, так и в мелких, начинается на M, заканчивается на X .Есть догадки?)

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

Оно выполняется всегда, просто у вас проблемы с пониманием.

Да? Интересно.

  • Инжектор vs Карбюратор ?)

  • АКПП с гидротрансформатором vs МКПП ?)

  • Голый Javascript vs React + JSX ?)

  • Ноги vs Велосипед ?)

  • Автомобиль vs Велосипед ?)

А почему карбюратор мягко говоря не всегда лучше? Или только у идиотов инжекторные машины?
А почему МКПП не всегда лучше? Или только у идиотов АКПП?
А почему ноги не всегда лучше велосипеда? Или на них только идиоты ездят?

Ведь вы говорите

Оно выполняется всегда

"Чем проще, тем лучше"

А я говорю что не всегда. Где-то да, а где-то нет.

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

Да? Я считаю что всегда лучше велик?) А если нужно преодолеть расстояние в 30км? В 60км? Что лучше? Всё ещё ноги?

Я же писал:

Оно в каких-то конкретных случаях выполняется и я с ним полностью согласен, а в каких-то конкретных случаях оно не выполняется.

Можно вы читать не умеете?) И сами это подтвердили в вашем примере с ногами vs велик.

То есть опять пустые слова и кода не будет да?

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

А в вашем примере используется глобальное состояние, и я бы 100% для этого использовал redux + react-redux-cache, redux (RTK) куда лучше mobx

Так используйте, покажите код который полностью повторяет функционал. Кто ж против. В этом и весь смысл.

Больше повторять одно и то же не буду.

Классический слив, классического пустослова. Вообще максимально ожидаемо.

Это не ответ. Это просто отписка.

Вот:
https://stackblitz.com/edit/vitejs-vite-ffchmx?file=src%2Fpages%2Fmain%2Findex.tsx&terminal=dev

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

Без ссылки на stackblitz это всё просто слова.

Я больше о том, что если библиотека весит 64 кб, то зачем говорить, что она весит 17 кб Цель какова?

Потому что для пользователя, с точки зрения траффика она будет 17кб, а не 64кб. И уже много лет принято говорить gzip размер когда речь идет про js бандлы, ибо в сыром виде их все равно никто и никогда по сети не гонят.


В сыром виде реакт весит 130кб, получается он не пригоден для использования?))) А preact то 3kb gzip, почему на него все не перешли?)) Потому что размер библиотеки играет крайне посредственное значение. У нас тут 5G все дела давно. Эпоха dial-up закончилась в нулевых. Намного важнее ряд других критериев, размер может быть от силы приятным бонусом(иначе react никто и никогда бы не использовал). Просто нелепо и смешно, когда называют в минусах размер стейт менеджера, я бы понял если он реально много весил, а тут 17кб (64кб в сыром виде), это вообще нет ни что.

Просто посмотрите сколько весит 1 картинка которая у вас загружается на сайте. Например ужатая и в разрешении 640*480 весит в среднем 30kb и это в gzip, в сыром виде в среднем они в 2 раза тяжелее.

Т.е. 1 вшивая маленькая пережатая картинка весит как 2 mobx'a.

Масштаб нелепости понимаете?)

А вот я просто открыл объявление на авито:

Почти 4mb в gzip'e, 15mb в сыром виде. А вы тут рассуждаете про десяток килобайт, это смешно)

3.7mb / 0.017mb(17kb) = 217
1/217 часть карл)

Это 0.46% от того, что мы загрузили открыв страницу. А про то, что после загрузки бандла он положился в кэш и больше не будет загружаться пока он не изменится я вообще молчу.

А теперь представьте, какая разница, основа приложения(стейт менеджер) будет весить 1кб или 17кб, есть какая-то разница? Если тот, что 1кб по всем фронтам лучше и удобнее, то да, лучше его, а если нет, то конечно лучше тот что в 17 раз больше весит. Ибо по факту разницы для пользователя не будет.

Честно говоря, не понимаю моду мерить размер бандла в gzip

Это не мода. Это фактическое значение. Ибо у 99.99% сайтов, я имею ввиду адекватных, а не hello world поделок школьников включен gzip.
Т.е. специально не включать gzip === максимальная степень глупости.
Вот например vite.dev

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

Тогда можно ещё указывать степень сжатия

Тоже нет смысла. Ибо между самой распространённой средней и самой максимальной разница ничтожная. Я лично проверял.

 но вообще сколько кода js выполняется. На Хабре не раз подмечали прямую зависимость тормозов от объема выполняемого кода.

А вот и не правда. "Тормоза" зависят не от кол-ва кода, а он того, какой собственно код выполняется и какую работу он делает. Если ваш JS файл весит 40mb, а из них только выполняется 2 функции, то если вынести это 2 функции в отдельный файл, который вест 500 байт, то результат в скорости будет тот же. Не считая скорости загрузки самого файла.

С такой логикой игры вообще не должны запускаться, они весят по 100 с лишни гигабайт) И кода там не на пару килобайт так то)) IDE не должны тоже работать, там тоже размер огогошечки. Однако все прекрасно работает.

Ибо не существует прямой зависимости скорости работы от объема кода как вы говорите.

А теперь внимание шок контент:
Habr:

У habr.com 5mb JS'a. А у vite.dev 560kb

Получается habr должен работать в 9 раз медленнее, чем vite.dev. Отклик на все нажатия и т.п. в 9 раз медленнее. Ведь как вы говорите, зависимость прямая.

Однако этого не происходят, даже близко.
А как же это так?)) Это другое?))

Information

Rating
Does not participate
Registered
Activity

Specialization

Frontend Developer
Lead
TypeScript
JavaScript
React
Node.js
MobX