Комментарии 60
А, ну и бонусный комментарий: пожалейте разработчиков, которые не используют лодаш. Я сталкивался с лодашными проектами: читать этот код больно, местами ты не понимаешь, зачем нужно вот это, а что делает вот это. Документация у них не идеальная, и, опять же, новички могут его использовать совсем уж неправильно.
В отличие от всяких библиотек, интегрированных в фреймворк, лодаш совсем не выглядит нативно - особенно с этим чудесным андерскором.
хорошая статья, нужна такая же про моментс
Вот я как пример пользователя лодаша (правда на сервер-сайде). Использую: _.noop, _.clone, _.clamp, _.min / _.max, _.compact а также более удобные обертки типа isNaN / isInteger. Удобно и минималистично ) зачем мне самописно заменять все, если одна маленькая и многолетне вылизанная либа все покрывает )
Ещё одна, не упомянутая в статье, проблема лодаша — по наследству от андерскора функции в нём перегружены для множества различных типов. То есть, условный filter
будет обязательно содержать код для фильтрации и объектов, и массивов, да ещё и, из-за перегрузки типа второго аргумента, — код для фильтрации по явному предикату, если будет передана функция, либо по множеству ключей-значений через matches
, если будет передан объект; по ключу-значению через matchesProperty
, если будет передан массив-кортеж; по значению поля через property
. Притом этот код не может быть удалён тришейком.
Но вы скажете, что же насчет незаменимых методов? Давайте посмотрим на те, что я видел чаще всего
По моим прикидкам, чаще всего из «незаменимого» встречаются debounce и sortBy.
Спасибо!
Про методы: дебаунс совсем уж легко заменить, sortBy... Не знаю с ходу отличий от обычного сорта, но как будто мы не так часто сортируем, а когда да, прописывание логики по типу (a,b) => a - b даже помогает в понимании (имхо)
Отличие в том, что sortBy позволяет делать сортировку по нескольким полям одновременно. Например, sortBy(users, ['lastName', 'firstName'])
Можно написать собственную версию где-нибудь в utils, но даже этот код можно долго улучшать для поддержки направлений сортировки, чисел параллельно со строками или для натуральной сортировки строк с числами:
function comparator(keys) {
const coll = new Intl.Collator('ru');
return (a, b) => keys.reduce((acc, key) => (acc || coll.compare(a[key], b[key])), 0);
}
// users.toSorted(comparator(['lastName', 'firstName']))
Так что это хороший кандидат на выделение в библиотеку.
В целом я со всем согласен, но
Вы можете написать свой крохотный метод с удобным API и так, как вам нужно
Приводит к тому, что в разных местах проекта плодятся крохотные, почти одинаковые, но не совсем, методы, от разных авторов, которые делают вроде одно и то же, но не совсем. Это такой зоопарк, от которого увеличивается вероятность логических ошибок, которые сложно отлавливать. Нужно постоянно в новый контекст влезать. Плюс дублирующийся код, который порой сложно просто так сократить в дальнейшем из-за едва различимой разницы во внутренней логике. Тут нужно сильно заморачиваться с ревью и документацией, чтобы этого не допустить. Но это тоже время, да и вечные споры, как какую помогалку лучше сделать и назвать. Библиотеки - сборники утилит, вроде lodash или D3, дают тот же эффект, что и инструменты по типу prettier - тимлид приходит, бъет кулаком в стол и говорит "мы делаем так!". И все, больше никакого зоопарка. Это далеко не идеальный вариант, но тем не менее проблему синхронизации всех участников решает.
Это не совсем решает вопрос с наличием аналогичных встроенных методов. Например, делать map/filter/toSorted массива через нативную версию или через Lodash?
Скажу как тимлид, ударивший кулаком: написали свой UI Kit c утилитами и юзаем. Полет - прекрасный)
Ну то есть мне на любой свой пет-проект писать юай-кит, понял.
Копировать между проектами только вручную или можно отдельным модулем оформить?
Если можно модулем, то я могу на нпм залить? Назову как-нибудь, типа низкий деш или что-то типа того.
Людей бесит что народ не включая голову юзает лодаш/джквери, поэтому они так же не включая головы начинают советовать всем пилить свои велосипедики для того чтобы всё оно было зоопарком с левым синтаксисом.
Хочется в
https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore?tab=readme-ov-file#_get тыкать автора, как нашкодившего щенка и спрашивать - вот это кто предлагает самому в любом проекте писать, а? кто это предлагает?
Мы написали UI Kit, потому что у нас не пет проекты, а десятки проектов.
Недавно делал пет проект, и, внезапно, не использовал лодаш. И не писал кучу кастомных утилит. Когда писал vue-yandex-maps понадобился метод сравнения - ну поставил либу для этого. И все равно справился без лодаша.
Было также еще несколько пет проектов в течение последних лет - и опять без лодаша, без jquery, что же это такое! И без велосипедов в виде утилит заменителей.
А, и кстати
Ну то есть мне на любой свой пет-проект писать юай-кит
Ну если там кастомный дизайн, и вдруг еще есть грамотный дизайнер, то для компонентов уж точно полезно было бы. Сколько раз за свою жизнь написал компонент попапа и кнопки - сбиваюсь уже со счета. И это все еще и без таилвинда и бутстрапа! Страх и ужас, одним словом.
Было также еще несколько пет проектов в течение последних лет - и опять без лодаша, без jquery, что же это такое! И без велосипедов в виде утилит заменителей.
А у меня друг рекомендовал всем отказаться от лодаша, а его недавно скорая сбила. Анекдотические свидетельства не работают.
Давай конструктивно - я вижу что ты для решения проблемы, которую обозначил @sfi0zy предлагаешь писать свой юай кит. Я тебя правильно понял?
Нет, просто это наше решение из-за большого числа проектов - своя библиотечка, которую я назвал ui kit'ом, но там еще и утилитки есть.
Если лодаш и подобные подключатся во имя каких-то утилит, от которых нельзя отказаться или заменить на что-то, а также нет ресурсов/не хочется заниматься ревью и выносить дублирующиеся участки в набор утилит (локальный или нет - неважно) - то хотя бы правильно использовать, о чем я писал в статье - правильно подключать и использовать только то, что нужно.
Ну и варианты как мой, так и условного лида, который подключил лодаш, не идеальны и несут свои издержки. А проблема ревью и дубликатов мелких утилит никуда не уходит - дубликаты, по идее, будут происходить и без всяких лодашей (как с компонентами, так и с методами). Лодаш и подобные не покрывают всё, поэтому отсекать дубликаты и выносить их куда-то надо в любом случае (особенно на больших проектах).
Тех, кто в 2024 использует упомянутый вами _.get
и аналоги нужно гнать ссаной тряпкой из профессии за полную профнепригодность. Сколько лет назад в язык оператор ?.
завезли? И ведь ?.
- это то, что предлагается по ссылке - но какому-то непризнанному гению это не нравится и он что-то про "нашкодившего щенка" пишет.
А что, в ".?" завезли получение свойств по динамическому пути или ты профнепригоден? Тогда прикрепляй в тред скан трудовой что уволился.
Что вы, уважаемый непризнанный гений, несёте? Динамический путь при получении свойств объекта? Если вы не в курсе, ?.
позволяет использовать конструкции вроде foo?.[bar]?.[baz]
, а динамический путь в виде произвольной строки - зло чуть ли не хлеще, чем eval
.
А про "профнепригоден" и "уволился" - насмешили, спасибо.
Первая же функция в списке реализована адски неэффективно
Каюсь, читал по верхам. Да, согласен, многократное применение деструктуризации массива не способствует высокой производительности.
Разумеется, существуют другие варианты реализации такой функции:
javascript - Split array into chunks - Stack Overflow
Еще кое-что:
You Might Not Need Lodash
Альтернативная реализация chunk (вроде тоже не очень эффективная?)
Внутри Lodash хорошая реализация. По вашей ссылке на SO топовый ответ тоже хороший (на самом деле там только цикл другой, а базовая схема та же).
Я немного поэкспериментировал, сравнил несколько вариаций с разными циклами и немного разными подходами - все более-менее близки, максимальный разбег примерно x3. Но вот та реализация с деструктуризациями на каждой итерации - катастрофа. Если массив более-менее большой, она в сотни и тысячи раз медленнее, на несколько минут(!) может залипнуть.
Даже любопытно стало, а вместо момента вы что предлагаете? Придуманный инопланетянами Intl?
А для каких целей: форматировать или проводить операции с датой/временем?
В целом что угодно современное. Мы используем Intl и натив, но если не подходит, сейчас date-fns очень популярен слышал. А так Moment просто официально умер, поэтому лучше бы слезать
date-fns или day.js
Luxon вполне себе.
Меня возьмут в рай если я буду клонировать объект так:
const obj = { test: { test: { test: 'Hi!' } } };
const cloneObj = JSON.parse(JSON.stringify(obj));
Я бы взял. Ну лучше пока мир не придумал....
Хм.... я вот всегда так делаю. Но мне можно, я бэкендер :-)
Самый надежный метод из придуманных, конечно) Но да, structuredClone - наш выход
Это ок только если ты прям точно уверен, то копируемый объект не будет содержать циклических ссылок.
Есть мнение, что программирование - оно все о переиспользовании. Переиспользовании проверенных, протестированных и доказавших свою надежность решений вместо написания своих велосипедов.
Я сталкивался с лодашными проектами: читать этот код больно, местами ты не понимаешь
А написать по 5-10 строк кода тут-там, забыть что оно уже написано (или не знать, что оно уже написано другим разрабом) и лежит воооон в том дальнем углу огромного проекта, и написать еще разок - весь этот замес будет более читаемым?
Если плохи дела со сборкой и 24kb gzipped - много, то просто создайте свой ПР, который позволит использовать более современный подход. Вродь же живая репа, мерджи есть. 50 млн только спасибо скажут https://npmtrends.com/lodash, а откажутся ли они после данной статьи - это врядли )
Я очень ленивый разработчик, поэтому написали свой набор утилит, и локально в проектах переиспользуем composable (я вьюшник) в отдельных папках. И это не велосипеды, а небольшие методы. Велосипеды есть, но их минимум - если совсем выхода нет, подключаем библиотеку. Но ни разу за все время в АВ на куче проектов никто не сказал "это нельзя сделать без лодаша".
А писать PR и переписывать лодаш - вот опять же, смысл? Ради тех пяти методов? Им всем уже есть современные легковесные альтернативы (если уж нет в нативе), может за редкими исключениями.
Переиспользовании проверенных, протестированных и доказавших свою надежность решений вместо написания своих велосипедов
Другая крайность - это вместо велосипеда получить франкенштейна. Навтягивать из разных библиотек однострочных функций. На мой взгляд уж лучше написать у себя эти функции в едином стиле, чем тянуть лишние зависимости в проект
Любая библиотека - это всего лишь инструмент, каждый сам себе решает, использовать или нет.
Если платят за написание собственных велосипедов - можно и писать, но они заведомо будут хуже того, что было протестированно на таком количестве тест кейсов, о которых ни вы, ни я даже не слышали.
В-третьих, люди не работают всю жизнь на одном месте. И никому неизвестные собственные велосипеды всегда будут проигрывать хорошо известным, типа, аналогам.
Не нравится теущий инструмент - поменял на другой. Со своим велосипедом придется "плакать, но всё равно продолжать есть кактус".
И такие библиотеки, как lodash, ramda, etc. являются прекрасным обучающим материалом, который просто необходимо просматривать иногда.
можно и писать, но они заведомо будут хуже того, что было протестированно на таком количестве тест кейсов
Зависит от метода. Условный дебаунс тяжело написать плохо
можно и писать, но они заведомо будут хуже того, что было протестированно на таком количестве тест кейсов
Опять же - зависит от сложности и огромности проекта. В большинстве случаев, на больших проектах уже и так куча утилит, а тут просто +5 на замену лодаша, а на мелких часто вам многие методы и не нужны
Не нравится теущий инструмент - поменял на другой
Когда весь код покрыт лодашем - так не получится. Мы его относительно долго выпиливали с одного проекта, где он также использовался совершенно бысмысленно
И такие библиотеки, как lodash, ramda, etc. являются прекрасным обучающим материалом
Вот совершенно не соглашусь. Их часто используют, не вникая в то, как это работает - методы простые и решают задачу, зачем вникать, пока с ними нет проблем или непоняток?
В отличие от того же UnJS, которые местами написали сложные штуки, на которые хочется взглянуть - да и то не делают.
Зависит от метода. Условный дебаунс тяжело написать плохо
Вот как раз дебаунс, хороший, с параметрами, отменой и т.п. написать совсем непросто. Он в библиотеках обычно десятки, а то и сотни LOC
В большинстве случаев, на больших проектах уже и так куча утилит, а тут просто +5 на замену лодаша, а на мелких часто вам многие методы и не нужны
Наверно я на недостаточно крупном проекте, в котором только девелоперов 1500 человек от Сиднея до Рейкьявика, но никому и в голову не придет выпиливать простой, удобный и надежный, как лом, lodash
Мы его относительно долго выпиливали с одного проекта, где он также использовался совершенно бысмысленно
Если вы на проекте бессмысленно используете инструмент - это разве говорит о том, что плохой инструмент?! Это говорит совсем о другом.
Вот совершенно не соглашусь.
Ваше право. Если Вы или Ваши сотрудники не смотрите хоть иногда в код того, что используете, не пытаетесь понять, что-то перенять, чему-то научиться - это очень и очень странно, в свою команду я бы не хотел таких разработчиков.
P.S. И да, про FP было смешно: я думал речь о разработчиках в статье идет, а не о просто обывателях-домохозяйках.
1) structuredClone работает не эквивалентно deepClone, например он теряет конструктор класса, не копирует функции, не копирует геттеры и сеттеры
2) "Для чего нужен FP - никто не поймет", вы серьёзно?
Верно, но на моей практике такие объекты нужно копировать весьма редко
Обыватель - вряд ли. Даже если он доберется для доки - она такая, что проще забить и не использовать (https://github.com/lodash/lodash/wiki/FP-Guide)
Я понимаю, что лодаш создает проблемы с тришейкингом, но писать свои утилиты это огромная проблема! Своя утилита должна обрабатывать все кейсы, которые разработчик вряд ли покроет. Это первое! А второе, типы, граждане вывод типов. Все ваши собственные утилиты никогда нормально не умели в сужение типов. Сколько я этого насмотрелся в проектах! Я не понимаю почему все резко стали против библиотек. Я использую ramda, и не вижу ничего плохого. Она полность тришейкабл и может отлично работать с типами.
Помню для тришейкабл нужны были какие-то костыли.
А вот с типами вообще не соглашусь. Это js-ная либа без типов, типы - сторонние, и у меня регулярно при обновлении зависимостей что-то отваливалось.
Ещё один минус того что либа js-ная - она обмазана проверками типов. Каждая функция будет проверять, что в неё передаётся, валидировать, приводить типы и стараться покрыть все их комбинации. Это ж сколько лишнего кода!
В итоге плюнул и пересел на remeda. Стало гораздо лучше. Тришейкается вообще без лишних движений, компактная, изначально ts. Советую посмотреть.
Вы используете лишь 5 методов.
А где статистика? Или пост ради хайпа?
Вопрос автору. А какие минусы в использовании lodash? Понятно, что некоторые функции уже перекрываются нативной поддержкой. Опять же, не все, и не везде. Но вот зачем может понадобиться выпиливание? Что в итоге получим? "более лучший/чистый/правильный код"? Хотелось бы что-нибудь более существенного :)
Вы простите, конечно, но я процитирую себя:
В правильный код я не верю. Скорее всего, код без лодаша будет работать быстрее - как минимум после замены на натив. Использование нативных методов также улучшит понимание того, что можно делать в чистом JS. Ну и код, скорее всего, правда будет чище - меньше импортов, меньше неймспейсов с методами.
Где для вас та грань, когда вместо того чтобы писать решение вручную, вы подключаете библиотеки и фреймворки, такие как Axios, Vue, React, Angular, Day.js, i18n, и UI-библиотеки? Ведь все это можно написать самому современным кодом.
Писать вручную может занять много времени и усилий. Готовые решения позволяют быстрее приступать к основной задаче.
В каждой функции из Lodash, например, соблюдаются лучшие традиции функционального программирования. Они выполняют ровно одну задачу, что упрощает их использование и тестирование.
Эти функции документированы и покрыты тестами, что обеспечивает надежность кода.
Инструменты, такие как Lodash, позволяют писать декларативный код, который часто работает быстрее нативного.
Для подтверждения этого можно найти множество бенчмарков, например, этот.
Наговнокодить можно и на нативном js, не нужно ругать из-за этого каждый инструмент, который делает рутинные, сложные вещи проще для понимания (опять же речь не про говнокод! А то начнете писать про то, как непонятен lodash в реальном проекте, который собирал джун)
Пропустил комментарий!
Условный реакт и вью это уже нынче стандарт. Без них разрабатывать бывает больно, мы не думаем, подключать их или нет
От аксиоса мы ушли на ofetch, и даже без него писали бы свою обертку под фетч. Изначально сидели на аксиосе из-за его превосходства над XHR, доказанного временем, но ушли с переходом на Nuxt 3 из-за того, что $фетч в нем встроен
Day.js мы не подключали, но если бы у нас не было ресурса писать обертки под Intl - подключили бы
UI библиотеки мы не используем, потому что написали собственные. Их полезно использовать, если на проекте нет и не будет дизайнера
Наговнокодить можно и на нативном js, не нужно ругать из-за этого каждый инструмент, который делает рутинные, сложные вещи проще для понимания
Нет, я ругаю именно лодаш. Однако, я видел множество проектов, созданных умными людьми, на которых столько библиотек, что черт ногу сломит - и как минимум половину можно выкинуть. Так что да, я сторонник того, что что-то легко заменить, лучше это сделать - а если не легко, посмотреть на популярность, актуальность библиотеки и другие факторы.
Но мы тоже не сумасшедшие, чтобы писать свои костыли на каждый чих - например, на основном проекте подключена относительно легкая set-cookie-parser, а также еще ряд библиотек, замена которых того явно не стоит - плюс всё, что у нас подключено, хорошо или хотя бы средне поддерживается, чего не скажешь о лодаше.
Спасибо за статью. С Lodash никогда не работал, поэтому решил узнать, что это за зверь. Вывод прост: не работал и дальше не буду)))
Мой выбор на данный момент - это набор util-функций под названием es-toolkit. Тулза весит всего 2,6 kB(minified + gzipped), совсем свежая (первый релиз от 31 мая 2024 г.), но уже 1,1k звездочек за неполных полтора месяца существования набрала.
Вам не нужен Lodash. Хватит! Пожалуйста