es-toolkit
Slash
Lodash, 현대적인 JavaScript 유틸리티 라이브러리로 모듈성, 성능 및 추가 기능을 제공. 배열, 숫자, 객체, 문자열 등의 작업에서 번거로움을 제거
es-toolkit: 토스가 개발한 고성능 유틸리티 라이브러리
es-toolkit은 토스(Toss)에서 개발한 고성능 자바스크립트 유틸리티 라이브러리입니다. 이 라이브러리는 성능 최적화에 중점을 두어 설계되었으며, 기존 lodash와 비교시 평균적으로 2배 이상의 속도 향상을 보인다고 합니다. 이렇게 성능이 빠른 이유는 최신 JavaScript API를 효과적으로 활용하여 구현했기 때문이라고 합니다.
주요 기능 은 아래와 같습니다.
배열 조작: chunk, difference, groupBy, keyBy 등
함수 제어: debounce, throttle 등
수학 연산: random, sum, round 등
객체: omit, pick 등
타입 검사: isNil, isNull, isUndefined 등
주요 특징
최적화된 성능:
lodash 대비 평균 2~3배 빠른 런타임 성능 제공
현대적 JavaScript API 활용으로 효율성 극대화
경량화된 번들 크기:
각 함수별 최소화된 번들 사이즈(예: difference 함수의 경우 97.2% 축소)
정밀한 TreeShaking지원으로 불필요한 코드 제거 및 최적화
견고한 타입 시스템:
TypeScript 내장 지원
직관적이고 정확한 타입 정의
isNotNil등 고급 타입 가드 함수 제공
안전성:
100% 테스트 커버리지 유지
Deno, Bun 등 다양한 JavaScript 런타임 환경 지원
개발자 친화적 문서화:
상세한 메서드 설명과 사용 예제 제공
한국어로 작성된 공식 문서
es-toolkit은 높은 성능, 최소화된 번들 크기, 강력한 타입시스템을 결합한 자바스크립트 유틸리티 라이브러리입니다. 한국 라이브러리인만큼 한국 개발자들에게 친숙한 환경을 제공하며, 기존 lodash 사용자들이 성능 향상을 원할 경우 유력한 대안이 될 수 있을것 같습니다.
https://es-toolkit.slash.page/ko/
자바스크립트 객체 복제 방법 총정리 👬
자바스크립트로 코딩을 하시다가 객체가 의도하신 대로 복제되지 않아서 고생하신 적이 한 번 쯤은 있으실텐데요.
예를 들어, 다음과 같은 객체가 있다고 가정해보겠습니다.
```js
const original = {
num: 1000,
bool: true,
str: "test",
func: function () {
console.log("func");
},
obj: {
x: 1,
y: 2,
},
arr: ["A", "B", "C"],
};
```
여러분은 위 객체를 어떻게 복제하여 새로운 변수에 복제본을 할당하실 건가요?
원본에 영향이 없도록 안전하게 복제하실 자신이 있으신가요?
```js
const clone = /* original의 복제본 */;
```
이번 포스팅에서는 자바스크립트에서 객체를 복제하는 다양한 방법에 대해서 실습을 통해서 한 번 정리해보도록 할께요. 우선 객체를 복제하다가 쉽게 범할 수 있는 실수에 대해서 살펴보고, 얇은 복제와 깊은 복제에 대한 개념을 잡아보겠습니다. 마지막으로 Lodash 라이브러리와 웹 표준 API인 structuredClone() 함수를 활용해서 객체 복제를 해보겠습니다.
📝 포스팅: https://www.daleseo.com/js-objects-clone/
🧑💻 실습 코드: https://runkit.com/daleseo/js-objects-clone
토스의 오픈소스 생태계: 한국을 넘어 글로벌로
국내 개발자로서 자부심을 불어넣는 오픈소스 생태계가 있습니다. 바로 토스(Toss)가 주도하는 오픈소스 생태계 인데요.
es-hangul
이라고 하는 한글을 다루기 위한 라이브러리는 이미 1,000개가 넘는 GitHub 스타를 획득했습니다. 또한 lodash
보다 2배 더 빠른 유틸리티 라이브러리인 es-toolkit
은 이미 6,100개의 스타를 받고 국내를 넘어 세계적으로 많은 개발자들의 관심을 받고 있는데요. 이번 토스 모닥불 EP.4 영상에서는 토스에서 오픈소스 생태계를 운영하는 개발자들의 이야기를 만나볼 수 있습니다.
특히나 주목할 만한 점은, 패널로 참여한 토스의 오픈소스 suspensive
를 운영하고 계시는 분인데요. 이 개발자분은 요즘은 필수로 사용되고 있는 TanstackQuery
의 최상위 기여자입니다. Jotai
외에도 토스 오픈소스에도 적극적으로 기여를하고 결국에는 토스에 합류하신게 참 대단하게 느껴지네요.
또한 오픈소스 생태계 구축을 통해 기술 커뮤니티에 긍정적인 영향을 미치고자 하는 토스의 노력도 대단한것 같습니다. 한국 개발 생태계의 경쟁력을 높이고, 개발자들에게 새로운 도전과 성장의 기회를 제공하는데 있어서, 토스의 이러한 행보를 응원합니다.
https://www.youtube.com/watch?v=SdBL-p597Dw
자바스크립트의 groupBy() API 사용법
데이터를 특정 기준에 따라 분류하는 것은 자바스크립트로 데이터 처리를 할 때 자주 필요한 작업인데요. 그런데 아직도 데이터 그룹화를 위해서 reduce()
함수나 Lodash 라이브러리를 사용하시나요?
이번 포스팅에서는 자바스크립트에서 데이터를 그룹화를 위해 쓸 수 있는 비교적 새로운 API인 groupBy()
에 대해서 알아보도록 하겠습니다.
📝 포스팅: https://www.daleseo.com/js-group-by/
관련 게시물
📕 자바스크립트 배열의 reduce() 사용법: https://careerly.co.kr/comments/109141
오픈 소스 기여도 한 걸음 부터, gatsby 이슈가 머지되었다.
작년부터 오픈 소스 기여에 대한 관심을 바탕으로 내가 할 수 있는 선에서 활동을 하기 시작했고, 올해 목표 중에도 이슈를 생성하고 PR을 생성하는 것이 있다.
작년 12월에는 내 블로그를 개발하는 데 사용한 gatsby에서 사용하는 라이브러리(babel-plugin-lodash)가 더 이상 유지보수 되지 않고 있으며 deprecated된 코드를 사용하고 있다는 것을 알게 되었고, 이슈 생성을 통해 제보한 적이 있었다. 그리고 오늘 기대보다도, 예상보다도 빠르게 2주만에 내용이 수정되어 master에 머지되었다. 단순히 이슈를 생성했던 것 뿐이지만, 내가 한 것 중 가장 큰 오픈 소스였기 때문에 뿌듯한 마음이 물 밀듯 밀려왔다.
사실 내가 해결하고 PR을 요청해볼까, 라는 생각도 했었지만 gatsby와 같은 큰 오픈 소스에 대한 막연한 겁이 나기도 했다. babel-plugin-lodash를 fork해서 deprecated된 코드를 수정하고 이 라이브러리를 사용하도록 package 경로를 수정하면 될 것 같다고 생각했는데, 막연한 겁 때문에 이 방법에 대한 확신을 가질 수 없었다. (그런데 이 방법대로 작업되긴했다.)
조금씩 내성을 키우고 익숙해져서 자신감을 가지고 더 많은 도움을 줄 수 있는 사람이 되도록 노력하자.
https://github.com/gatsbyjs/gatsby/issues/38786
import _ from 'lodash'; import React from 'react'; export default function Test() { return _.map([1, 2, 3, 4, 5], (value, index) => { return ( <> <p>{index + 1} 번</p> <p>{value}</p> </> ); }); } 이렇게 코드를 작성하면 콘솔창에 Warning: Each child in a list should have a unique "key" prop. 이 뜹니다. 근데 <> 부분에 key props를 사용하면 사용할 수가 없다고 나옵니다. 어떻게 해야할까요?!
현재 렌더링 되고 있는 화면에서 키는 유일해야 합니다. (현재의 map 뿐만 아니라 전체에서) 따라서 단순히 index를 key로 사용한다면, 같은 오류를 볼 가능성이 매우 큽니다. 특히, array의 요소가 자주 빠졌다, 추가되는 상황이라면 더다욱 index를 key로 활용하면 좋지않은 결과를 볼 수 있습니다. 렌더링 시 가상돔을 비교하는 구문에서 내용이 바뀌지 않았음에도, index가 바껴서 ley가 달라졌다면, 해당 내용은 다시 렌더링이 됩니다.
안녕하세요 로대쉬를 사용하다가 궁금한점이 있어서 질문 남깁니다. sortBy.map.filter 이런식으로 chain메서드 없이도 체이닝을 할 수 있는데 chain 메서드는 왜 사용하는지 어떤 장점이 있는지 문득 궁금해졌습니다. 혹시 이유를 아시는 분 있으시면 답변해주시면 큰 도움이 될 것 같습니다!
사실 로데시 함수에서 chain 함수는 함수형 프로그래밍을 쉽게 구현하기 위해서 사용하는 함수이지만, 앞서 유근수님께서 답변주신것 처럼 지연평가가 필요해서 더 많이 사용되는것 같아요. (지연평가도 함수형 프로그래밍에 일부에요!) 일반적으로 JS에서 지원되는 map, filter 와 같은 람다식 함수들은 n 번의 시간 복잡도를 가집니다. 만약 map(...).filter(...) 식을 가진다면 2n 만큼의 복잡도를 갖게 되어요. 하지만 지연평가는 이터레이터 기법을 이용해서 여러 반복적인 작업을 n번의 순회에 모두 처리하는 기법을 사용합니다. (매 순회마다 처리해야할 로직들을 한번에 처리하며 다음 순회로 넘어가는 방법을 사용합니다) JS의 제너레이터 라는 문법을 이용하여 이터러블한 함수를 구현하고 이를 통해 지연평가를 합니다. 더 자세한건 여러 블로그를 참고하시면 될거에요 : ) "그러면 무적권! 지연평가를 활용하는것이 짱짱 좋은것인가?" 여기에 답변은 No 입니다 ㅎㅎ 그 이유는 지연평가가 여러 반복 로직이 복잡하게 엮여있는 경우에는 성능이 좋은것이 확실하나, 단순 반복에서는 map, filter 가 더 성능이 좋습니다. 이유는 단순히 map, filter는 언어 자체에서 지원하는 기능이기 때문에 반복 순회를 처리하는 과정이 더 효율적으로 짜여있기 때문이에요. 반면에 제너레이터를 이용한 구현시에는 .next()라는 메서드 실행을 통해 다음 순회로 넘어가기 때문에 JS 로직적으로 순회가 처리되어요. (아무래도 명령어 처리 효율이 안좋은 JS보다는 더 로우 레벨 언어로 구현된 map, filter 가 더 빠르겠죠?) 그러면 언제 지연평가를 쓰면 좋을까요? * 대상에 걸어야 하는 반복 로직의 갯수가 많을때 지연평가 효율이 좋습니다. (map(...).filter(...).map(...)...) 때에 따라서는 이러한 로데시 함수 구현없이 reduce 라는 순수 JS 문법을 통해 지연평가로 구현해야할 로직을 대신할수도 있어요! 여러 블로그 및 사이트에서 순수 자바스크립트로 구현을 했을때와 로데시로 구현을 했을때의 성능비교한것을 정리해주고 있어서 해당 자료도 같이 살펴보는 것을 추천드립니다 : ) 🎉 함께 검색해보면 좋은 키워드 🎉 * lodash * 함수형 프로그래밍(FP) * js generator * iterator * 지연 평가 구현 * lodash vs ES6 * reduce
lodash vs underscore중 어떤것을 더 많이 사용하시나요?
레거시 프로젝트가 아니면 대부분 lodash를 사용합니다. lodash를 underscore의 개선 버전이라고 생각하시면 편합니다. (underscore는 2009년에, lodash는 2012년에 만들어졌습니다.) underscore에 있는 함수들은 거의 대부분 lodash에서도 사용이 가능하고, 성능이나 확장성에서도 lodash가 더 낫습니다. underscore는 중첩 객체(nested object)를 다루지 못하는 반면, lodash는 중첩 객체를 탐색하거나 cloneDeep같이 불변성 관리에 도움을 주는 함수를 제공합니다. 다만, 번들 사이즈를 따져봤을 때 lodash는 24.5kB, underscore는 8.2kb로 lodash가 3배 정도 더 큰 용량을 가지고 있기 때문에 lodash를 사용하신다면 트리 쉐이킹 혹은 babel-plugin-transform-imports과 같은 플러그인을 이용해서 modularize imports 사용을 고려하시는게 좋습니다. modularize imports는 import 구문을 내가 사용한 함수만 호출하도록 transform을 해줍니다. 아래는 예시입니다. [전] import { merge } from 'lodash' [후] import merge from 'lodash/merge'
React와 Next.js 사용해서 사이트를 만들고 있습니다. 라우터는 next/router를 사용하고 있고요. 라우터를 사용해 사이트의 query param으로 initialItem 값을 받아와서 item 상태의 초기값을 지정해주려고 하는데, 초기값 선택이 이상하게 됩니다. 각 item 값은 enum으로 선언해 사용하고 있고 query param을 lodash의 toNumber를 사용해 숫자로 변환하고 있습니다. query param이 없는 경우 전체가 선택되게 하고 싶은데 계속 A가 선택되네요. 왜 그런지 아시는 분 계실까요? 충분할지 모르겠지만 초기값 지정하는 부분과 관련된 코드 첨부합니다.
안녕하세요. 혹시 query param 값이 없을 때 라우터에서 어떤 값으로 읽어오는지 확인 해보셨을까요? 해당 값을 빈 스트링으로 불러올 것 같은데 그 경우 isNil로 필터링 되지 않고 아래의 toNumber 로직에서 0으로 변환될 것 같습니다. 그러면 말씀하신 것처럼 item 초기값이 0이될 수 있을 것 같아요.