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

которые позволяют предсказуемо получать экземпляры сервисов

import { myService } from 'services/service'
Это не предсказуемо? Каждый раз будет какой-то рандомный сервис подсовываться?) Как раз таки через DI мы можем рандомный сервисы пропихивать, вот там да, реально не предсказуемо.

Внедрение зависимостей можно реализовывать по разному

Поэтому и контекст в реакт

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

Да и в целом, внедрение зависимостей никаким образом не противоестественно использовать в JS программах.

import { myService } from 'services/service'

Противоестественно, ведь их можно просто импортировать.

Про то, что тогда в тестах не подсунешь фейковый сервис, извините, для меня ценность таких тестов нулевая. Какой смысл тестировать фейковую программу, которая не будет работать в реальных условиях. Я это уже видел многократно и на разных проектах, ой, у нас зеленые тесты, круто, а прод не работает, как же так. Это все равно что тестировать АПИ просто на то, что код 200 вернулся, значит всё ок. Или отдельно протестировать функции, которые работают по отдельности, а в реальном запросе, когда вызывается цепочка этих функций все идёт по одному месту. Unit тесты уместны только для разработки узко направленных библиотек, а не реальных бизнес проектов где 100500 взаимосвязей, цепочек и сайд эффектов. Для реальных бизнес проектов только ручное тестирование и высокоуровневые e2e тесты канают, остальное детский сад и трата времени в пустую.

В ангуляре везде DI как бэ

И что? Это всего лишь ангуляр как бэ. В react, vue, svelte и т.д. и т.п. нет DI как бэ. И вообще в JS проектах в очень сильно подавляющем большинстве случаев нет DI как бэ. Ибо это противоестественно, в целом как и angular, для ценителей с очень специфическими вкусами)

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

 Получается, DI альтернатив NestJS нет?

Есть) В других языках, ну или написать свою альтернативу в JS. Но вообще концепция DI чужеродная для JS.
Но если пофигу на производительность, которая ниже плинтуса, кучу лишнего кода, в кайф простые вещи превращать в сложны и т.п., то и нет смысла смотреть на альтернативы, можно дальше "кайфовать" на nestjs и не париться. Ну или просто сменить язык, на такой, где изначально принято что простые вещи должны быть сложными и монструозными.

Печально) Попробуйте ради разнообразия скинуть оковы, удивитесь насколько минималистичный и красивый код можно писать, а главное не write-only

Свой велосипед любой может написать, в этом ничего сложного нет

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

Ваш любимы нест, такой же велосипед, очнитесь, посмотрите на историю языков и их фреймворков/библиотек.
Все "проблемы" которые "решает" нест уже были решены за многие годы до его появления многими другими языками, а если про Nodejs говорить, то express/koa/hapi решили всё это за долго до появления нест.

Просто нужно учитывать то как потом людей искать на проект, и как люди после велосипеда будут работу искать

Вы рассуждаете как на 0% программист и как на 100% промысловик.

Нест дает архитектуру и некий стандарт по написанию кода

  • Отвратительную архитектуру

  • Отвратительный "стандарт" по написанию говнокода максимально громоздкого и переусложенного

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

    Да, по истине хороший инструмент конечно.

Я как работник приходя в контору с нестом сразу могу приступить к работе

Т.е. придя на проект где есть Express/Fastify вы не сможете приступить к работе?)) Ведь эти инструменты максимально простые и покрывают 1000% сценариев.

мне не нужно изучать как использовать велосипед

Зачем промысловику вообще понимать что как устроено, как вообще можно реализовывать те или иные аспекты.

и тем более как в нём реализовывать что то новое

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

 которое не вписывается в текущую архитектуру

Что?)) С чего вы это вообще решили? Что вы вообще знаете об архитектуре?)

 и нужно будет сидеть ломать голову придумывать и тратить время

Слова истинного промысловика

 а контора не очень любит оплачивать такие вещи

Зато любит оплачивать нест, где разработка идёт в 2-3 раза медленнее чем с Express, а ещё надо в 2 раза больше мощностей чтобы выдержать ту же нагрузку что express. И кого вместо проекта в проде через пол года, контора получаем проект в проде через полтора года, вместо проекта силами 1 разраба, получаем проект силами 3-5 разрабов. Че-то математика вообще не сходится.
6мес 400к = 2.4млн
18мес * 3чел по
400к = 21.6млн
Вообще не сходится на порядок

Я как контора при найме людей предпочту специалистов у которых в голове уже есть некая структура

Ага) Промысловиков))) Очень талантливые разработчики они, мы знаем))

который просто выкидывает нест и пишет свой набор велосипедов под конкретный проект

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

Т.е. выкинуть уродца nest, заменить на express/fastify/koa/hapi это всё, фиаско?))) Так делают только дурачки и т.п.?

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

Есть такая штука, называется мысленный эксперимент. Неужели не очевидно как будет выглядеть код на nest и на fastify/express и т.п. Ведь судя по вашим рассуждениям, где вы называете тех, кто пишет инструменты - "свой набор велосипедов", "с которым никто не хочет заниматься нонейм великом" и в этом духе, значит вы настолько шикарный специалист(который не сможет написать аналог express/nest и т.п., но зато в первых рядах высмеивает тех, кто может) что для вас это не должно составить никакого труда, просто закрыл глаза и сразу код перед тобой.

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

Никогда не понимал и не пойму таких людей, которые элементарные вещи усложняют так, что без бутылки не разберешься. Скорее всего это обусловлено банально их невежеством и не понимаем самой сути происходящего, что именно мы должны сделать скажем для обработки запроса. Казалось бы, пришел запрос GET /api/users?limit=100, ну что может быть проще

0) Провалидируй входные данные
1) Сделай запрос в БД
2) Отдай ответ в виде JSON

Почему некоторые индивидуумы эту процедуру превращают в 7 кругов ада? И с умным видом говорят что они делают все правильно. Загадка.

Что это за "другое"? JS/TS это полноценные языки. Вы имеете ввиду это про фронтенд?

Про человеческий код.

нет, моя "пиар компания" включает обработку ошибок.

1) try {} catch (e) {}
2) window.addEventListener("error", (event) => {});
3) window.addEventListener("unhandledrejection", (event) => {});

Это всё шутки, и они ошибки не ловят? Или если человек намеренно не ловит ошибку, а дает ей подняться на верх он идиот?

Опять вы про обработку ошибок, еще меня в зацикленности клеймите.

Если сделать поиск по странице по слову "ошибка". будет очень много вхождений, что говорит о зацикленности)

Эффект снимает когнитивную нагрузку

Всё равно я вижу только один шум, который кишит ключевым словом Effect. Плюс сам по себе этот код крайней своеобразный и противоестественный. Всё это и есть крайне лишняя когнитивная нагрузка.
Плюс генераторы вместо async/await, ну такое себе.

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

Я больше 13ти лет пишу и вообще никогда никаких проблем, от слова совсем из-за ошибок не было, там где программа должна продолжить свое выполнение в случае ошибки, там их люби просто обрабатывают try {} catch(e) {}, в остальных случаях они ловятся глобально и сообщение пользователю вываливается, ой, всё сломалось. JS/TS позволяет писать очень чистый код и ловить ошибки высоко, гибко и легко.

В том же Golang, делают в 99% случаев тоже самое, что по умолчанию в JS, все ошибки возвращают наверх через return err, а в JS просто этим мусором можно не засорять код вот и всё, try {} catch(e) {} на верхнем уровне все отловит.

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

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

Без повышения когнитивной нагрузки?))) И это вообще цветочки в виде hello world примера, чего уж там говорить про код с реальной логикой.

class MyConsole 
  extends Context.Tag("MyConsole")<MyConsole, {
    log: (input: unknown) => void
  }>(){}

//function heyEffect(arg: number): Effect.Effect<boolean, Error, MyConsole>
function heyEffect(arg: number) {
  return Effect.gen(function*() {
    const logger = yield* MyConsole;
    if (arg == 2) yield* Effect.fail(Error("boom"));
    logger.log(logger)
    return true;
  });
}

pipe(
  heyEffect(1),
  Effect.provideService(MyConsole, { 
    log: (input) => console.log(input)
  }),
  Effect.catchAll(error => { // error соответсвует только типу Error
    console.log("hey was failed with expected error", error.message);
    return Effect.void // нужно вернуть новый эффект
  }),
  Effect.runSync //запуск эффекта 
)

Я вижу тут только одну сплошную когнитивную нагрузку и минимум полезного кода.

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

В golang, на уровне языка нужно всегда проверять что функция не вернула ошибку

А в чем проблема писать на языке, который спроектирован так писать? Вам вообще JS и TS не нужны, это языки вообще про другое. Почему вы на Golang не пишете? Там проверка ошибок после каждой сточки. Вся ваша "пиар компания" построена вокруг - обработки ошибок, прям зацикленность на этом.

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

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

 предлагаете полностью перейти на e2e тесты ?

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

 и kiss это не что иное как все в одном хендлере держать?

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

  • сложность тестирования

Для этого же есть end-to-end где полностью вся цепочка сразу тестируется. Это намного качественнее. Какой смысл изолированно протестировать 10 функций которые будут работать без ошибок по отдельности, если реальный запрос будет состоять из цепочки из 10 этих же функций и как раз в таком случае будет падать с ошибкой. Тесты будут зеленые, а API не рабочем, замечательное тестирование.

  • проблемы с масштабируемостью

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

  • прямая работа с базой в обработчике запроса

И что? В любом случае работа с базой данных будет вызвана в обработчике запроса, сразу или через 1-2-10 функций. Мы либо сразу понимаем что мы делаем и что происходит, либо бегаем по десятку файлов, все пытаемся удержать в уме, чтобы выстроить цепочку что происходит, что куда прокидывает, что вызываем и т.п.
Keep It Simple, слышали о таком? В этом примере сразу понятно что происходит, вообще любому человеку. Т.е. при таком подходе ситуация когда мы написали код, а через 2 месяца к нему вернулись и не понимаем что тут уже происходит просто исключена, т.к. KISS во всей красе.

  • и т.д. и т.п.

И что же ещё?

 То есть, у нас теперь есть memo, который на каждый рендер будет сравнивать пропсы

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

и еще сама система реактивности MobX-а, которая не бесплатна.

Да, но по сравнению с иммутабильностью как основным атрибутом на котором построено по умолчанию реактовское управление состоянием, да и в redux и т.п. тоже самое (иммутабильность). Накладные расходы на реактивность MobX'a можно назвать бесплатными и даже профицитными, потому что в совокупности факторов на реальных проектах экономят процессорное время и оперативку, да и с garbage collector'a снимают лишнюю нагрузку, иными словами мы просто не платим налог на иммутабильность.

Ну приходится изучать MobX, и уже работать с ним:

30 мин хватит за глаза, а если посветить ему день, то вы уже асс.
99% случаев покрывают 2 функции:
makeAutoObservable()
observer()
Остальные 1% покрывают
reaction()
autorun()
when()

А для понимаю принципов его работы достаточно знать getters/setters как работает.

Спорный момент, где-то может быть даже легче useState, а не писать целый класс

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

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

1) 1000 строк класса === 1000 строк в компоненте реакта, и что лучше?)
2) Классы можно разбивать как угодно, можно использовать композиции и т.п.

Перерендеров нет, но зато есть потребление памяти. Повторюсь - реактивность не бесплатная.

См. пункт выше, по сравнению с налогом на иммутабильность всё в ажуре наоборот. Тем более я специально замерял в браузере (Вкладка Pefromance в DevTools) потребление больших продакшен приложений которые мы писали с MobX'ом, цифры не отличаются от любых других сайтов и все в диапазоне 85Mb находится. Ну и главное не забывать руками нажимать Collect Garbage чтобы не попадать в фазы луны срабатывания gc.

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

Но называть решения приведенные в статье полумерами, как-то некорректно.

Ну по сути React + MobX, по сравнению с голым react это просто небо и земля. Поэтому не использовать MobX это принудительно лишать себя возможности лучшей жизни. Поэтому решения в статье это фактически костыли и борьба с реактом, которых можно элементарно избежать просто добавив MobX. Опять же не вижу не единого смысла страдать) Ну в целом я то и не страдаю, да и проблемы описанные в статье для меня никогда проблемами не были из-за MobX'a)

То есть memo используется всегда!

Всё правильно, в этом и весь смысл

Насколько это хорошо?

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

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

Они бы рады, и это бы работало, если бы в реакте не существовало такой вещи как React.Context, т.к. там всё топорно, компонент родитель просто не может знать когда контекст изменился, поэтому никаких memo по умолчанию быть не может.

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

Вот пример все завернуто в контекст, но ререндерятся только те, кто должен:
https://stackblitz.com/edit/stackblitz-starters-b9zww5vj?file=src%2FApp.tsx

А есть у вас еще аргументы в пользу Mobx?

Ну вам показали код, вы на него посмотрели, неужели самого этого кода уже не достаточно? Он же просто тупо нативный.

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

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

Вы приведите пример с best practises использования, и скажите, что оно плохо работает.

Так best practises у zustanda === много лишнего грязного кода. Какой в этом смысл? Вам в кайф утопать в куче лишнего кода? В чем прикол сознательно одевать на себя пудовые ботинки чтобы бегать по набережной? Когда вот прям перед носом лежат отличные кроссовки весом в 80 грамм, с амортизирующей подошвой.

Ну а зачем приводить пример из антипатернов использования и говорить, что оно плохо работает.

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

Да, так можно) Но тогда код становится ещё заметно хуже и в нем ещё больше лишнего мусора.

И это всего лишь Hello World example, а не Real world. Но камон в реальной жизни во всех компонентах вот такие портянки раскрывать их могут быть десятки только в рамках одного компонента, а таких компонентов в проектах сотни. Это смешно. Зачем этот суицид если много много лет назад придумали выход, как сделать реакт идеальным, на сколько это вообще возможно.

Кстати ещё один жирный минус в анти копилку zustand'a:
Если в его стейте что-то изменяется, но при этом это не используется в компоненте который использует другие свойства из этого стейта, то компонент все равно каждый раз перерендеривается в пустую.



Вот ссылка:
https://stackblitz.com/edit/stackblitz-starters-ab7az7ym?file=src%2FApp.tsx

А в чем именно проблема использования внутренних инструментов для состояния?

1) Иммутабильность
- Это побеждается только использованием MobX

2) При перерендере родителя, перерендериваются дочерние компоненты, хотя не должны.
- Первый вариант(садо мазо) - это "лечится" заворачиванием всего и вся в ручную в React.memo, useMemo, useCallback соответственно код становится очень грязным и вырвиглазным.
- Второй вариант(традиционный) - это лечится просто использованием MobX.

Но адекватно можно и на том, и на другом писать.

Используя внутренние инструменты реакта, адекватно можно написать только Hello World, причем в прямом смысле этого слова. Как только будет интерактив и изменение состояния, то безальтернативно реакт нужно использовать в связке с MobX. В противном случае сам выбор реакта ошибка и лучше тогда уж взять vue или svelte.

Information

Rating
Does not participate
Registered
Activity

Specialization

Frontend Developer
Lead
TypeScript
JavaScript
React
Node.js
MobX