준프

준프님의 아티클

준프

준프

안녕하세요. 준프입니다 :)

간단한 자기소개를 부탁드립니다.

  • 웹 프론트엔드 엔지니어로 일하고 있습니다. 웹/앱 서비스를 만드는 기술, 방법에 관심이 많습니다.

  • 글 쓰기, 메모, 기록, 회고 등 무언가 쓰는 걸 좋아합니다.

  • 독서, 게임, 식물 키우기가 취미입니다.

  • 아내와 딸이 있습니다.

왜 링크드인을 활용하려고 하는지/어떤 것을 얻고 싶은지 알려주세요.

  • 노동 시장에서 자신을 표현하는 가장 효과적인 방법은 링크드인을 활용하는 거라고 생각합니다.

  • 링크드인을 활용해 나를 표현하고, 브랜딩하는 데 관심이 있습니다.

  • 링크드인을 통해 자신을 어필하는 방법을 공유하고 얻고 싶습니다.

자신의 링크드인 URL을 꼭 첨부해주세요!

https://www.linkedin.com/in/moonki-lee-037126b0/

잘 부탁드립니다 :)

7
2
준프

준프

도커 네트워크 - 브릿지에 대해 아시나요?

근래 특정 이슈를 해결하기 위해 도커를 살펴보는 중입니다. 특히 컨테이너 간에 데이터를 주고받기 위해선 네트워크에 대한 이해가 필수인데요, 성격상 당장 문제를 해결하더라도 원하는 수준까지 이해하지 못하면 근질근질해서 잘 못 참곤 합니다.

특히 최근 브릿지의 동작에 대해 이런저런 글을 찾아봤지만, 초보자인 제게는 뭔가 부족하다는 느낌을 많이 받았습니다. 그러던 중 정말 잘 설명해주는 글을 소개합니다.

이 글은 브릿지 네트워크 드라이버에 대해 설명하고 있습니다. 브릿지 네트워크 드라이버는 무엇인지, 언제 사용하면 좋은지 그리고 정말 간단한 예제도 있습니다. 특히 시리즈로 나와있는 글들도 도커 네트워크의 개념을 가볍게 이해하기에 정말 좋은 것 같습니다. 이 글들을 토대로 조금 더 심화된 내용을 읽는 것도 좋겠다는 생각이 들었습니다.

도커 네트워크를 이해하는데 어려움이 있으시다면 한 번 참고해보시는 걸 추천드립니다 :)

0
0
준프

준프

리액트에서 Proxy 디자인 패턴 사용하기

Proxy 패턴에 대해 아시나요? Proxy는 메세지를 주고받는 두 대상 사이에 위치해서 여러가지 역할을 합니다. Javascript의 Proxy는 대상 객체의 앞에 위치하여 객체에 대한 외부 요청을 제어합니다.

Proxy 객체를 사용하면 한 객체에 대한 기본 작업을 가로채고 재정의하는 프록시를 만들 수 있습니다.

이번에 소개해드리는 글은 이러한 Proxy를 어떻게 활용할 수 있는지 공유하고 있습니다.

먼저 Proxy를 통해 얻을 수 있는 이점은 아래와 같다고 소개합니다.

  • 데이터 캐싱

  • 보안 개선

  • 자원 소모 감소(게으른 로딩, 캐싱, 접근 제한 등)

  • 네트워크 최적화

  • 동시성 제어

그리고 각 이점에 대한 예시를 소개합니다.

  • API를 통해 가져온 사용자 데이터에 비밀번호(민감정보)가 포함되어 있다면, 서비스를 사용하고 있는 사용자가 어드민이 아니라면 접근해서 수정할 수 없도록 합니다.

    • 이 경우 말 그대로 '보안'이 아니라 데이터에 접근해서 수정하거나 하는 등의 동작을 불가능하게 만드는 '접근 제어'가 더 적절할 것 같습니다.

  • API를 통해 데이터를 이미 가져왔다면 다음에 데이터를 가져올 땐 API를 호출하지 않고 기존 데이터를 제공합니다.

  • 그리고 구체적이진 않지만 다른 사용예를 소개합니다.

    • 추상화 및 코드 재사용

    • 데이터 검증 및 sanitization

    • 퍼포먼스 모니터링 및 최적화

Proxy와 관련해 잘 몰랐는데, 이 글을 이해하기 위해 Proxy에 대해 공부하게 된 계기가 되었습니다. 관련해서 많은 도움이 된 글을 여기에 더해 소개합니다.

0
0
준프

준프

모듈 페더레이션 - 의존성을 공유하기 전 한 번 더 생각하세요.

이번에 소개해드릴 글은 모듈 페더레이션을 사용할 때 의존성에 대해 고민해봐야 한다는 내용의 글입니다.

웹 페이지가 그리고 서비스의 규모가 점점 커지면서 서버 뿐만 아니라 프론트 역시 마이크로서비스를 채택하는 조직이 점점 많아지고 있습니다.

이 글에서 소개하는 것처럼 한 페이지의 컨텐츠 뿐만 아니라 모든 서비스에서 공유하여 사용하는 요소들 역시 모듈 페더레이션을 통해 런타임에 가져와서 사용하곤 합니다.

그렇게 모듈을 공유할 때 의존성 역시 고려해야하는데요, 이 글에선 다소 극단적이긴 하지만 거대한 의존성을 두 애플리케이션이 공유할 때 어떤 점을 주의해야 할지 경험을 공유합니다.

요약하자면

웹팩이 트리 셰이킹을 할 수 있도록 우리가 도와줘야 한다.

입니다. 웹팩은 모듈 페더레이션을 통해 공유하려는 모듈 또는 의존성의 어떤 부분이 어떻게 사용될지 알 수 없기 때문에 트리 셰이킹을 하지 않고 그대로(글에선 node_modules에 있는 그대로) 공유하게 됩니다.

해결 방법은 간단하지만, 모두에게 적용할 수 없다는 단서도 달아 놓고 있습니다.

이번을 기회로 모듈 페더레이션, 트리 셰이킹 등의 개념에 대해 한 번 더 짚고 넘어가면 좋을거 같습니다 :)

0
0
준프

준프

소프트웨어 개발에서 삼체문제

삼체문제에 대해 아시나요? 역학에서 한 물체 또는 두 물체의 움직임을 설명하는 건 가능하지만 단 세 개로 물체의 갯수만 늘어나도 그들의 움직임을 설명하는 건 불가능해집니다.

소프트웨어 개발도 비슷한데요, 한 기능, 두 기능 등 초기 기능 개발은 수월한 방면 기능이 늘어나다보면 각 기능의 상호작용을 그려보는 건 점점 더 어려워집니다.

이번에 소개해드리는 글은 소프트웨어 개발에서 왜 결합도가 중요한지, 문제를 작게 쪼개서 해결하는 방법론이 왜 중요한지 삼체문제를 비유로 설명하는 글입니다. 이런 비유는 어렵게 느껴지는 개념을 이해하기 쉽게 만드는 효과를 가진 것 같습니다. 그리고 실제로 너무 잘 성명해주는 거 같아요 !

저 역시 프론트엔드 개발을 하다보니 조금만 시간이 지나도 문제가 지나치게 복잡해지는 경우를 많이 봐왔습니다. 그래서 어떻게 하면 프론트엔드 사이드의 문제를 단순화할 수 있을지 계속해서 고민하고 있습니다. 또 ! 한 문장이긴 하지만 삼체문제와 관련된 문장도 있답니다 :)

이렇게 되면 기능 간에 결합이 강하게 발생해서 수정이 쉽지않습니다. 이건 마치 삼체문제와 비슷해서 서로 상호작용하는 기능이 많아지는 것보다 문제의 복잡성이 더 빨리 어려워진다는 것을 의미합니다.

관련해서 제가 쓴 글도 참고해보시면 좋을거 같아요 :)

0
0
준프

준프

서프라이즈 없는 안정적인 동료가 되기

오늘은 함께 일하는 사람으로서 어떤 사람이 '안정적'인 사람인지 공유하고 관련 글을 소개하려고 합니다. '나는 다음 번에는 "안정적인 엔지니어"를 고용하라고 HR에 구체적으로 말했습니다.'라는 제목을 가진 이 글은 사실 '엔지니어'라는 단어를 넣긴 했지만 직무 관계 없이 어떤 사람이 '안정적'인 사람인지 소개하고 있습니다.

몇몇 케이스는 동의가 안 되기도 하지만 몇몇 경우는 여러 글에서도 소개하는 만큼 다시 상기하기에 좋은 글이라고 생각합니다.

아래는 이 글에서 소개하는 안정적인 엔지니어는 어떤 사람인지를 요약했습니다.

  1. 아픈 날이 거의 없이 출석하는 사람

  2. 업무의 호불호가 거의 없는 사람

  3. 스스로를 잘 다루는 사람

  4. 긍정적인 사람

그리고 어떻게 안정적인 엔지니어가 되는지 소개하고 있는데요, 방법 중엔 술을 마시는 방법도 있습니다. 물론 다음 날 업무에 영향을 주지 않고, 조금 취하며, 술을 마시는 것 자체에 집중하지 않는 다는 조건이 있지만요.

전 이 글에서 '아픈 날이 거의 없이 출석하는 사람'이라는 주제가 가장 눈에 띄었습니다. 어딘가 아파서 결근을 하는 경우 프로젝트 진행에 영향을 줄 수 있다는 것인데요, 여기엔 두 가지 핵심이 있습니다.

  1. 건강은 프로젝트를 예정대로 진행하는 데 가장 기본이다.

  2. 갑작스런 결근은 프로젝트에 영향을 준다.

그리고 '갑작스런'은 꼭 건강이 아니더라도 아주 중요한 주제입니다. 프로젝트를 관리하는 관리자들, 그리고 함께하는 동료, 작업물을 기다리는 사람 모두 일정 대부분이 예정대로 진행되는 걸 기대합니다. 하지만 '갑작스런' 이벤트는 '나를 제외한 모두'에게 큰 스트레스를 안겨줍니다.

The fewer sudden breaks, the better.

이와 관련해 우미영님도 저서 <나를 믿고 일한다는 것>에서 서프라이즈를 줄이고 신뢰를 얻는 방법에 대해 소개하고 있습니다.

내가 가장 두려워하는 직원은 업무 지시에 아무런 토를 달지 않고 늘 '네'라고 대답하는 사람이다. 이들은 십중팔구 내가 의도한 것과 다른 결과물을 가지고 온다. 혼자 열심히 한다고는 하지만 마감 기한에 임박해서 수정할 시간도 주지 않고 결과물을 들이미는 직원은 가끔씩 나를 아연실색하게 한다. 의욕 자체를 문제 삼을 수는 없지만 회사는 혼자가 아니라 함께 일하는 곳이다. 상사의 입장에서는 피곤하기는 해도 질문을 많이 하고 이해되지 않는 것은 따져 묻는 직원이 오히려 고맙다. 그들은 나와 함께 중간중간 체크해가면서 일하기 때문에 엉뚱한 곳으로 빠지지도 않고 대체로 결과물도 잘 만들어낸다.

대부분의 상사들은 '서프라이즈'를 싫어한다. 작든 크든 조직을 책임지고 있는 사람에게 예측 불가 또는 불확실성만큼 두려운 것이 없다. 그래서 일의 진행 상황을 상사와 공유하는 것이 중요하다.

리스크와 성과를 효과적으로 관리할 수 있도록 도와주는 직원들이 믿음직스러울 수밖에 없다.

일하는 방법을 한 번 돌아보고 얼마나 안정적으로 작업을 진행했는지, 난 어떤 엔지니어인지 한 번 돌아보면 좋을 것 같습니다.

0
0
준프

준프

데스크탑 스크린 같은 건 없습니다. - 접근성

웹 페이지를 만들다보면 디자이너와 함께 아래와 같이 페이지를 쪼개곤 합니다.

/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {...}

/* Small devices (portrait tablets and large phones, 600px and up) */
@media only screen and (min-width: 600px) {...}

/* Medium devices (landscape tablets, 768px and up) */
@media only screen and (min-width: 768px) {...}

/* Large devices (laptops/desktops, 992px and up) */
@media only screen and (min-width: 992px) {...}

/* Extra large devices (large laptops and desktops, 1200px and up) */
@media only screen and (min-width: 1200px) {...}

(출처: Typical Device Breakpoints)

이 방법은 정말 편하고 유용합니다. 페이지의 요소들을 특정 스크린에 맞춰 몇 가지만 고려하면 되기 때문입니다. 이번에 소개하는 글은 이런 브레이크 포인트, 즉 중단점은 존재하지 않는다는 걸 말합니다. 왜냐하면 같은 스크린 사이즈더라도 폰트사이즈를 키우거나 모바일에서 줌인 또는 줌아웃을 하기 때문입니다. (실제로 제가 만난 몇몇 기획자는 큰 폰트로 보기위해 항상 200%정도 폰트를 키워서 보곤 했습니다.)

이 글에선 사용자의 접근성을 개선하기 위해선 어떻게 하면 좋을지 소개하고 있습니다.

  1. 고정된 px을 사용하는 것보다 em, rem 등을 사용하기

  2. flexbox를 마스터하기

  3. 스크린 사이즈보다 컨텐츠의 크기를 기반으로 media query 작성하기

등 입니다.

그리고 왜 이런 '좋은 방법'을 지키기 어려운지도 소개하고 있습니다. (원글 살펴보기!)

사실 접근성을 개선하는 이러한 방법은 자주는 아니더라도 종종 듣곤 합니다. 하지만 이 글에서 말하는 것처럼 지키기 정말 어렵습니다. 그럼에도 지킬 수 있도록 노력해야 하고 방법은 찾아봐야 한다고 생각합니다. 이 글에서 인상 깊었던 문장이 있어서 소개합니다.

The point is this, though: people do things you wouldn’t expect for all kinds of reasons. It’s not just about “accessibility” and “people with disabilities”. It’s high quality craftsmanship if your stuff just works™️.
(사람들은 온갖 이유로 기대하지 않는 일을 합니다. 이건 단지 '접근성'과 '장애인'에 관한 것이 아닙니다. 당신의 물건이 제대로 작동한다면 그것은 고품질의 장인정신입니다™️.)

그리고 접근성과 관련해 한 권의 책을 소개해드리려고 합니다. '인클루시브 디자인 패턴 접근성 있는 웹디자인하기 - 헤이던 피커링'은 접근성에 대해 소개하면서 굳이 '불편한 사람'을 강조하지 않습니다. 오히려 너무나도 현실적으로 '고객을 놓친다'는 관점을 강조합니다. 그리고 접근성을 고려하고 개선하는 좋은 방법들을 소개합니다. 또한 여전히 유효합니다 !

사용자가 커스텀하여 사용하는 스타일을 크롬에서 테스트해볼 수 있도록 하는 확장 프로그램도 소개하고 있습니다.

그리고 px을 rem으로 변환해주는 패키지도 소개합니다.

0
0
준프

준프

디스콰이엇에 Medium 글을 공유하게 된 계기

이 글에선 디스콰이엇에 Medium 글을 공유하게 된 계기에 대해 짧게 소개하려고 합니다.

쌓여만 가는 아티클

많은 사람이 그렇듯 저도 '와 좋은 글이다 !'하고 글을 쌓아놓기만 하는 편입니다. 그러다보니 이제는 정말 감당 안 되는 수준으로 쌓여있습니다. 분명 '좋은글'이라고 생각했는데 말이죠.

스크린샷 2023-10-30 10.20.31.png

그래서 저 많은 글을 읽어야할 동기가 필요했습니다. 그냥 '읽으면 좋으니까' 정도가 아닌 더 확실한 동기말이죠.

디스콰이엇

디스콰이엇의 클럽을 운영하게 되면서 '좋은 글을 소개해보자'는 생각이 들었습니다. 확실히 내가 글을 쓰는 것보다 훨씬 쉬운 일이니까요. 글을 읽고 다른 사람에게 공유하기, 그리고 규칙적으로 하는 건 충분한 동기가 부여되는 일이었습니다.

정말 '소개'만

글은 베끼는 것 대비 쓰는게 훨씬 더 어렵습니다. 그렇기 때문에 '베껴서 옮기는 것'은 절대 하지않기로 했습니다. 대신 소개하는 글을 읽는 시간을 절약해드리기 위해 '핵심'만 요약해서 적고 제 생각도 옮기기로 했습니다. 그것만 해도 저도 그렇고 읽는 사람들에게도 도움이 되지 않을까 했습니다.

왜 Medium?

다른 플랫폼도 정말 많고 한글로 된 좋은 아티클도 많지만 Medium을 선택한 이유가 몇 가지 있습니다.

  1. Medium의 디자인이 정말 마음에 듭니다. 그래서 개인 블로그도 Medium에 운영하고 있습니다.

  2. 국내 블로그 글은 쉬운 내용은 '사실' 그대로 '빨리' 써내려간 느낌을 많이 느낍니다. 소위 '복붙'한 느낌의 글도 너무 많습니다. 반면 좋은 글은 너무 길거나 어려운 경우가 많습니다.

  3. Medium과 같은 해외 아티클은 복붙한 글도 많지만 비율이 높진 않습니다. 아마 플랫폼에서 필터링을 잘 해줘서 그런 것 같기도 합니다.

  4. 전 Stackoverflow도 자주 사용하는 편인데 '노력 없이 질문하는 걸 잘못된 행위'로 보는 만큼 아티클도 그런 문화가 없지 않아 있는 것 같습니다.

  5. 간단한 글이라도 구체적인 사례 그리고 본인의 생각을 적는 편입니다. 그래서 다른 아티클과 같은 내용을 다루더라도 많은 인사이트를 얻곤 합니다.

스크린샷 2023-10-30 10.32.37.png

(찾아보지도 않았다니... 이 질문은 여기에 이미 있어. -1점이다.)

고르는 과정

좋은 글을 하나를 소개하기 위해 적게는 1개 많게는 10개 정도의 아티클을 읽습니다. 그 중 프론트엔드와 관련되거나 일 할 때 도움이 될거라 생각하는 글을 고릅니다. 그리고 왜 좋았는지 분명한 이유가 있어야 합니다.

결론

정말 짧은 글이네요 ! 사소하게 시작했지만 어느새 오랜 시간 글을 공유했고 그 과정에서 읽은 아티클도 상당합니다. 이 글을 읽으신 분들도 각자 나름의 방법으로 쌓여있는 아티클을 하나씩 읽어가는 계기가 되었으면 합니다 :)

8
0
준프

준프

JSON은 정말 느립니다. 더 빠른 대안을 살펴봐요 !

요즘 Medium에서 핫한 글 하나 소개하려고 합니다. 이 글은 아래와 같은 내용을 담고 있습니다.

  1. JSON을 왜 사용하는지

  2. 앱에서 속도와 반응이 왜 중요한지

  3. JSON이 앱을 느리게 하는지?

  4. 왜 JSON이 앱을 느리게 하는지

  5. JSON의 대안

  6. 데이터 포맷 최적화 (왜 바이트 단위가 중요한지)

  7. 바이너리 포맷을 통한 사이즈 효율화

  8. JSON 퍼포먼스 최적화

  9. 실제 사례를 통해 살펴보는 JSON 속도 최적화

  10. 결론

이 글은 JSON을 왜 많이 사용하는지, 그리고 어떤 점이 문제인지 살펴봅니다. 사실 이 부분을 살펴보며 이런 생각이 들었습니다.

대부분의 서비스는 JSON 최적화를 위해 투입하는 비용 대비 효용이 좋지 않은 것 같다. 확실히 JSON의 장점이 뚜렷하다.

그만큼 JSON이 왜 널리 사용되고 어떤 장점이 있는지도 분명하게 제시하고 있습니다.

하지만 그만큼 인사이트도 많은데요, 인상 깊었던 세부 주제를 살펴보면

  1. JSON은 범용성 측면에서 확실한 장점이 있습니다.

  2. JSON은 serialize하고 deserialize하는 비용이 큰 편인데, 마이크로 서비스의 경우 특히 비용이 높아질 수 있습니다.

  3. JSON의 대체제가 있다니!

  4. JSON을 잘 사용하는 방법이 있다니!

  5. JSON을 사용했을 때 발생한 이슈를 해결한 사례들이 너무 좋습니다.

와 같습니다.

더 자세한 내용은 원문을 읽어보시면 좋을거 같아요 !

0
4
준프

준프

재사용 가능한 컴포넌트를 그만 만드세요

제목부터 자극적인 이 글은 생각보다 정말 순합니다. 우리가 리액트 컴포넌트를 만들면서 마주하는 현실을 있는 그대로 적고 있습니다.

저자는 재사용 가능한 컴포넌트를 만들면서 일종의 반복적인 패턴에 빠졌다고 합니다. 그리고 만족스러웠습니다.

After following a very similar pattern and feeling good about myself, I started wiring up my page.

하지만 재사용을 고려하며 만든 컴포넌트는 재사용되지 않았고 재사용을 고려하다보니 코드는 복잡해지기만 했다고 합니다.

I hadn’t written any of my components based around data.

(그 어떤 데이터도 데이터를 기반으로 작성하지 않았습니다.)

...

Many of those “reusable” components were never reused in the app and many, including my Hero component, never even needed dynamic data.

('재사용 가능한' 대다수의 컴포넌트는 절대 재사용되지 않았고, 심지어 동적 데이터도 필요하지 않았습니다.)

그리고 저자는 재사용 가능한 코드를 작성하는 건 '미래의 가정된 문제를 해결하면서 지금 마주한 어려운 문제를 해결하기를 미루는 것', 즉 일종의 '미루기(procrastination)'라고 봤습니다.

... we humans tend to write code like this as a form of procrastination. Delaying solving the hard problems we have now, by solving the hypothetical problems of the future.

그리고 저자는 재사용 가능한 코드를 작성하고 있다면 '내가 지금 해결해야 하는 문제인지 정직하게 살펴야 합니다.'라고 전합니다.

'오브젝트'의 저자 조영호님도 책에 아래와 같은 말을 남기고 있습니다.

변경은 예상이 아니라 현실이어야 한다. 미래에 변경이 일어날지도 모른다는 막연한 불안감은 불필요하게 복잡한 설계를 낳는다. 아직 일어나지 않은 변경은 변경이 아니다. <오브젝트>, 조영호, 305쪽

더 자세한 내용은 원문을 참고해주세요 :)

0
7
준프

준프

커링 패턴

커링 패턴을 아시나요? 자바스크립트에서 클래스를 사용하기 전부터 종종 사용하던 패턴 중 하나입니다. 몇몇 책에서 소개할 땐 아래와 같은 예시가 대다수였고 공감이 잘 안됐던 기억이 있습니다.

(패턴이란 '어떤 문제를 해결하는데 반복되는 방법을 공식화 한 것이다.'라고 생각하면 편합니다. 분명 기억해두면 활용할 곳이 나타날거라 생각합니다 :) )

const setAdd = (fixNumber) => {
  return (num) => {
    return fixNumber + num;
  };
};

const add5 = setAdd(5);

console.log(add5(10)); // 15
console.log(add5(20)); // 25

(도대체 이걸 어디에다 쓴다는거지...?)

하지만 어떤 개념이든 알아두고 문제를 해결할 때 '아, 그그 그거 있는데, 좋은거'하고 떠오른다면 충분하다고 생각합니다. 제게 커링 패턴이 그랬던 것 같습니다.

오늘 소개해드리는 글은 커링 패턴이 어떤 것이고 실제로 어떻게 사용하면 좋은지 유쾌하게 소개하고 있습니다.

https://blog.stackademic.com/spice-up-your-javascript-with-currying-894a7c463d03

그리고 최근에 제가 쓴 글에서도 간단하게 소개하고 있습니다.

https://medium.com/@shinbaek89/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%97%90%EC%84%9C-%ED%95%A8%EC%88%98%EC%99%80-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0-50752df217b5

0
0
준프

준프

클린 단위 테스트

단위 테스트를 작성할 때 중요하게 생각하는 것 중 하나가 바로 '테스트 코드 역시 관리해야 하는 코드다'입니다. 테스트를 작성하고 유지하다보면 이 역시 만만찮은 비용이 들어간다는 사실을 알게됩니다. 나중에 유지하기 어려워서 테스트를 꺼버리는 경험을 누구나 한 번쯤은 하곤 하죠.

it.skip('...', () => {...}); // 이 테스트는 이제 더이상 유지할 수 없어...

그렇기 때문에 테스트 코드를 작성할 때에도 유지하기에 좋은 방법으로 작성해야 합니다. 이번에 소개해드릴 글은 테스트 코드를 어떻게 잘 작성할 수 있는지 소개하는 글입니다.

이 글은 Robert C. Martin의 글을 인용하는 걸로 시작하는데요, 정말 좋아하는 문장 중 하나 입니다.

“Test code is just as important as production code. It is not a second-class citizen. It requires thought, design, and care. It must be kept as clean as production code.”

이 글의 요약은 아래와 같습니다.

  1. 테스트의 구조를 Arrange-Act-Assert 패턴으로 잡으세요.

    • BDD에서 사용하는 Given-When-Then도 참고하면 좋습니다 :)

  2. 일반적으로 사용되는 객체들을 쉽게 설정하기 위해 테스트 객체 빌더를 사용하세요.

  3. 하나의 단위 테스트에선 하나의 개념만 테스트하세요.

  4. 테스트는 빠르고, 독립적이고, 반복할 수 있어야 하고, 자기 검증이 가능해야 하며(성공 또는 실패로 대표되어야 합니다.) 프로덕션 코드와 비슷한 시기에 작성해야 합니다.

  5. 테스트는 실패해야 할 때 실패해야 합니다.

  6. Happy Path 뿐만 아니라 Edge Case역시 테스트 해야 합니다.

  7. 잘못된 결과로 이어질 것 같은 케이스를 테스트해야 합니다.

더 자세한 내용은 원글을 참고해주세요 :)

원글:

https://betterprogramming.pub/clean-code-with-unit-tests-5f28020828a5

0
0
준프

준프

React Hook 지옥으로부터 벗어나기

리액트에서 Hook을 사용하다보면 알 수 없이 코드가 복잡해지고 점점 건드리기 무서워지기 마련입니다. 그건 아마 부수효과와 관리해야 하는 Hook이 많아져서 그런게 아닐까 막연하게 생각하곤 하는데요, 이번에 소개해드릴 글은 Hook을 어떻게 관리하면 좋을지 제안 하는 글입니다.

useEffect

"useEffect는 라이프사이클 Hook이 아니다"라는 말로 시작합니다. 예를 들어, 특정 상황(API server, strict development mode 등)에서 기대하지 않은 호출이 발생할 수 있습니다. 그리고 많은 useEffect의 사용은 가독성을 떨어뜨리고 유지하기 어렵게 만들며 테스트하기 어렵게 합니다.

useMemo

useMemo를 써야하는 곳이 아님에도 쓰는 건 '섣부른 최적화'라고 말합니다. useMemo를 남용하는건 메모리 이슈와 의존성을 신경쓰지 못해 발생하는 문제 등이 발생할 가능성을 높입니다.

useState

useState를 많이 사용하는건 한 함수에서 변수를 여럿 사용하는 것과 마찬가지로 가독성을 해치고 관리하기 어렵게 만듭니다.

이밖에도 useReducer, useContext, Hook 내부에 비즈니스 로직 등 좋은 내용이 많습니다. 이번에도 긴 글은 아니니 한 번 읽어보시는 걸 추천합니다 ! :)

0
2
준프

준프

물어보는 문화 vs 추측하는 문화

이번에 소개하는 글은 물어보는 문화와 추측하는 문화에 대한 글입니다. 꽤 오래전에 추천 글로 올라왔었고 읽어야 겠다 생각 했지만 개발과 직접적으로 관련되어 있지 않고 다소 길다보니 미루고 있었는데요, 읽어보니 정말 좋은 내용인 거 같아 공유드립니다 :)

(요약문은 제가 의역한 부분이 많습니다. 그대로 옮기려니 조금 어색하더라구요... 하하)

먼저 이 글에서 말하는 물어보는 문화의 특징은

  1. yes라고 할 만한 요청이 아니더라도 무엇을 원하는지 물어봅니다.

  2. 다른 사람을 신경쓰기 보다 내가 필요한 걸 신경씁니다. 왜냐하면 yes라고 하기 싫다면 그럴 것이기 때문입니다.

  3. no라고 할 가능성이 높아보이더라도 요청하는 건 괜찮습니다.

  4. 사람들은 정말 괜찮을 때 yes라고 합니다. 그렇지 않다면 no라고 할 것입니다.

입니다.

다음으로 추측하는 문화의 특징입니다.

  1. 다른 사람이 yes라고 할만한 상황이라고 생각될 때에만 요청합니다.

  2. 요청하는 게 좋을지 판단하기 위해 간접적인 상황 단서들을 수집합니다.

  3. 다른 사람이 no라고 할만한 상황을 만드는 건 무례합니다.

  4. 사실 상황이 적절하고 그렇게 느껴진다면 요청을 하지 않아도 됩니다.

이 글에서 재미있는 예시가 있는데요, 질문하는 문화 안에서 추측하는 사람이 어떤 모습일지 보여줍니다.

"내가 일을 잘 한다는 사실은 분명하기 때문에 누군가 나를 툭툭 치면서 '매니저를 해주면 안 될까'라고 하길 바래"

라고 하는 사람이라는 것입니다.

반면 물어보고 요청하는 문화에선 요청을 받아줄거라 기대하지 않더라도 요청할 수 있어야 하고 요청에 대해 화내지 않고 거절할거라는 믿음이 필요합니다.

이 글을 보면서 많은 생각이 들었는데요, 특히 추측하는 문화에 익숙해 불편했던 점들이 떠올랐습니다. 그 중 가장 큰건 '내가 요청하지 않아도 내가 필요로 하는 인정을 받을 수 있는 마음'이 아닐까요?

그 밖에도 딱히 말하지 않아도 그 사람이 알아서 척척 일해주길 바라는 마음, 내가 어려움에 처해있을 때 요청하지 않아도 '어려운 일 있어?'라고 먼저 물어봐주길 바라는 마음이 있을 거 같습니다.

하지만 이 글에서 말하듯 요청한다는 건 거절 가능성을 전제로 하는 것이기 때문에 어렵습니다. 그럴 때 어떻게 하면 좋을지 아래와 같은 방법을 소개하고 있습니다.

  • 어떤 문제에서 헤어나오지 못하고 있다면 도움을 요청하기

  • 사람들이 no라고 하는 것에 좀 더 둔감해지기. 당신은 사람들이 no 라고 하지 않더라도, 사람들이 yes라고 할만한 요청만 하고 있을 것입니다. 그러니 좀 더 둔감해지고 좀 더 과감하게 요청하세요.

  • "내가 원하는 대로 할 수 있다면?"이라고 스스로에게 물어보세요. 이렇게 하면 다른 사람이 어떤 걸 원할지 생각해보지 않고 내가 원하는 걸 명확하게 요청할 수 있습니다.

추측 문화에 있으면 '뭐 먹고 싶어?'라고 물어볼 때 '아무거나'라고 대답한다고 합니다. 그리고 내가 먹고 싶은 걸 다른 사람이 선택해주길 기대하는 것이죠. 일을 하면서 이런 비슷한 일이 많은 거 같습니다. 물어보는 문화가 무조건 좋은 건 아니지만 추측하는 문화 역시 그렇지 않을까요?

조금 더 명확하게 요청하고 거절에 둔감해지는 걸 연습해보는 건 어떨까요?

그때가 6월경이었다. 나는 12월까지 권한대행 기간을 연장해주면 당해연도 지사의 실적 목표와 몇 가지 과제를 해결하는 것으로 내가 지사장 자격이 있는지 평가받고 싶다고 했다. 결과를 보고 적합한 사람이 아니라고 생각하면 그때 새로운 지사장을 다시 물색해서 영입하고 나는 원래 자리로 돌아가 역할을 다하겠다고 했다.

<나를 믿고 일한다는 것>, 우미영

0
5
준프

준프

Optimistic UI에 대해

Optimistic UI에 대해 아시나요? Optimistic UI란 서버에서 응답이 오지 않더라도 "괜찮을 거야"라고 낙관하고 미리 결과를 화면에 노출하는 방법입니다. 그렇다면 Optimistic UI를 구현하기 위해 준비해야할 건 무엇일까요?

사실 UI를 구현하는데 고민할게 있을까? 싶을 수 있습니다. 평소엔 서버에 요청을 보내고 로딩 스피너를 노출했다면, 이젠 바로 완료 메세지를 보여주면 되지 않을까요?

사실 그렇지 않습니다. 서버에서 오류가 발생해 UI를 되돌려야 한다고 생각해보면 많은 이슈들을 고려해야 하기 때문입니다.

이번에 소개해드릴 아티클은 Optimistic UI를 구현하기위해 알아야할 그리고 준비해야할 것들을 명료하게 소개합니다.

가장 먼저 서버에서 실패하는 경우가 아주 희귀해야 한다는 전제 조건이 필요합니다. 그렇지 않다면 Optimistic UI를 구현하는 것 자체가 큰 비용일 수 있습니다.

그리고 실패란 코드 분석을 통해서 실패 발생 케이스가 0%이지 않고서는 실패가 발생할 가능성은 존재하기 때문에 대응하는 케이스를 준비해둬야 합니다. 그건 바로 클라이언트와 서버의 데이터 일관성과 동기화 입니다. 왜냐하면 실패했을 때 rollback을 할 책임을 클라이언트 역시 갖기 때문입니다.

더 자세한 내용은 아티클을 참고해주세요 ! 그리 길지 않습니다 :)

0
5
준프

준프

리액트 Custom Hook과 Context API

지겨울 만도 하지만 다시 나타난 Custom Hook과 Context API에 관한 글 입니다. 하지만 그럼에도 좋은 글이라고 생각해서 공유 합니다. 왜냐하면 사랑에 대한 글과 문장은 많지만 울림을 주는 경우는 많지 않고 명문은 더욱 적은 것과 비슷하다고 할까요?

종종 설명을 하다보면 장황하게 설명할 때가 많은데요, 이 글은 Custom Hook과 Context API가 리액트 앱에서 어떤 역할을 하는지, 언제 사용하면 좋을지 아주 간결하고 명확하게 설명합니다.

Custom hooks are functions that allow you to extract and share stateful logic across multiple components. They allow you to encapsulate state and behavior in a reusable, modular, and testable way. The Context API, on the other hand, provides a way to pass data down the component tree without having to pass props down manually at every level.

그리고 장점과 단점도 명확하게 나열되어 있습니다. 그 중에 특히 단점이 눈에 들어왔습니다.

  • Complexity: While custom hooks and the Context API are very powerful, they can also add a layer of complexity to your code, making it more difficult to understand and maintain.

글이 길지 않기 때문에 읽기도 좋네요 :)

0
1
준프

준프

가면 증후군과 압박감에 대해

가면 증후군(Imposter Syndrome)에 대해 아시나요?

이 증후군은 내 실력은 보잘것 없는데 인정 받을 때 내 진짜 실력이 드러나지 않을까 불안해하는 상태를 말합니다. 저도 이런 상태를 항상 경험하고 있는 편입니다. '난 잘 해내는 게 별로 없는데 나에 대한 기대치가 너무 높은게 아닐까?'하는 불안감은 때론 스스로를 너무 지치게 하는 것 같습니다.

이런 가면 증후군은 생각보다 많은 사람이 그리고 많은 개발자가 경험하고 있습니다. 이것과 관련해 좋은 글이 있어서 소개해 드리려고 합니다 !

한글로 작성되었고 좋은 내용이 많은 만큼 꼭 읽어보시는 걸 추천드립니다 !

가면 증후군은 압박감에 대한 방어기제가 아닐까 합니다. 압박(기대)을 많이 받다보니 불안감과 두려움이 커지는게 아닐까요. 그래서 압박감 해소를 위한 글도 하나 소개해드리려고 합니다.

이 글에선 압박감 해소를 위해 몇 가지 방법을 소개하고 있습니다.

  1. 현실을 객관적으로 평가하기 - 압박이 강하다면 '만약?'이라는 패턴에 갇히게 되는데, 거기에서 빠져나와 현실과 사실에 집중합니다.

  2. 불안감을 기대감으로 바꾸기 - 연구 결과에 따르면 불안감을 위협이 아니라 기회로 보는 사람들의 생산성이 더욱 높았다고 합니다. 불안한 상황에서 '침착하게 대응하자'라고 하는 대신 '난 지금 매우 기대돼'라고 해보는 건 어떨까요.

  3. 과거의 경험을 활용하기 - 이전에 비슷한 경험을 통해 성공해본 사례가 있나요? 지금 불안한 상황이 미래의 잠재적 성공으로 가기 위한 길은 아닌지 과거의 경험을 통해 살펴보는 건 어떨까요.

  4. 아주 작은 개선 - 불안감은 사람을 옴짝달싹 못하게 만들곤 합니다. 대신 아주 작더라도 지금 당장 개선할 수 있는 것에 집중합니다. 먼 길도 눈 앞의 한 걸음부터 시작이라는 사실을 잊지 않습니다.

  5. 항상 준비되어 있는 상태 - 스스로를 예상하지 못한 어려움을 예상할 수 있도록 훈련합니다. 침착하게 대응하기 위해 최악의 상황이 벌어질 수 있다는 사실을 받아들이고 준비합니다.

여기에 있는 내용들은 진부하게 느껴질 수도 있지만, 기억해 둔다면 압박감 때문에 움직일 수가 없을 때 한 번쯤 시도해보면 좋은 내용들이라고 생각합니다. 모두의 건강한 일상을 응원합니다 !

0
0
준프

준프

이벤트 버스로 결합도를 낮추기

이번에 소개해드리는 글은 '이벤트 버스'와 관련된 글입니다. 특히 이벤트 버스를 활용해 불필요한 결합을 제거하는 방법을 소개하고 있습니다. 특히 리액트 예시가 눈길을 끌었습니다.

이벤트 버스라는 단어가 잘 와닿지 않을 수도 있는데요, 가장 간단한 예시로 'input' 이벤트가 있습니다.

// HTML
<label for="nameInput">이름</label>
<input type="text" id="nameInput" />

// javascript
const $input = document.querySelector('#nameInput');

$input.addEventListener('input', (event) => {
  console.log('이름이 바뀌었어요 !', event.target.value);
});

input에 텍스트를 입력하면 브라우저에선 이벤트를 발생시킵니다. 이 과정은 텍스트 입력이라는 승객을 브라우저라는 버스에 태운 것으로 해석할 수 있습니다. 그리고 브라우저는 승객을 이벤트의 형태로 이벤트 리스터 정착지에 내려줍니다.

이 과정은 브라우저에서 기본으로 제공하는 버스라면 우리가 버스를 만들 수도 있는데요, 이 글에선 우리가 만드는 버스를 통해 프론트엔드에서 결합도를 낮추는 방법을 소개하고 있습니다. 이 글에선 아래와 같은 버스를 소개하고 있습니다.

let model = {
  value: '',
  set(val) {
    if (val === this.value) return
    this.value = val
    window.dispatchEvent(new CustomEvent('modelUpdate', { detail: this }))
  },
}

그리고 이벤트 버스를 사용했을 때 장점과 단점도 소개하고 있습니다.

An event bus allows us to loosen the coupling between the two parts of the code. By loosening the coupling between the code, we gain the ability to replace one part without affecting the other, which means the software becomes easier to modify. At least in theory.
...
A disadvantage of this indirect way of communicating is that it’s more difficult to identify who is being called or who is doing the calling or even if there are any callers or callees to begin with (because that’s what gives it the advantages).

사실 우리가 이벤트 리스너를 사용했을 때 장점과 단점을 기억해보면 이해하기 쉬울 거 같습니다.

제 경우 정확히 기억이 나진 않지만 커스텀 이벤트를 통해 문제를 해결했던 경험이 2-3회 정도 있었는데요, 알아두면 언젠가 도움이 되지 않을까 합니다.

0
2
준프

준프

일반적인 프론트엔드 프로젝트에서 오버엔지니어링 하지 않기

오늘 소개해드리는 이 글은 우리가 일상적으로 만드는 프론트엔드 프로젝트가 어떤 걸 갖추면 좋은지 이야기 합니다. 반대로 어떤 요소들이 오버엔지니어링을 발생시키는지 말해줍니다.

이 글이 좋았던 이유는 여기에서 말하는 대부분의 것들은 생각보다 일정 규모 이상의 조직에서 경험하게 된다는 것입니다. 즉, 제가 경험하고 들어본 대부분의 작은 조직에선 이 글에서 말하는 '갖추면 좋은' 구성도 고려 대상이 아닙니다. 그들 역시 회사를 먹여살리는 일상적인 규모의 프론트엔드 프로젝트를 운영함에도 그렇습니다.

그렇기 때문에 이 글이 눈에 들어왔습니다. 프로젝트를 구성할 때 참고하면 도움이 되지 않을까 합니다.

이 글에서 추천한 몇몇 섹션에 대해 제 생각을 공유하는 걸로 마무리 해보겠습니다 :)

상태 관리

상태 관리가 반드시 필요한가? 라고 하면 고개를 갸우뚱하게 됩니다. 그렇다고 해서 원천적으로 '아니다'라고 하는 건 아닙니다. 이 글에서 말하는 것처럼 애플리케이션이 커지고 복잡도가 올라갈 때 상태관리를 고려하는 건 충분하다고 생각합니다. 물론 불필요한 상황에서 미리 도입하고 보는 건 오버엔지니어링이 될 수 있다고 생각합니다.

기능 플래그

기능 플래그는 새로운 기능을 배포할 때 아주 유용한 도구 입니다. 일정 규모 이상의 앱을 개발한다면 적극적으로 고려해볼만 하다고 생각합니다.

테스트

이 글에서 말하는 것처럼 테스트는 필수입니다. 하지만 어떤 테스트냐에 따라 다를 수 있습니다. 우리 앱의 안정성을 높이는 데 맞는 테스트를 고민해보고 적용하는 과정이 있어야 한다고 생각합니다.

모니터링 (Observability)

모니터링은 고객으로부터 문제를 보고받기 전, 그리고 고객이 느끼지 못하는 잠재적인 문제를 해결할 수 있도록 도와줍니다. 그리고 문제가 발생했을 때 원인 파악을 비교적 정확하게 할 수 있도록 도와줍니다.

접근성

접근성은 앱에서 갖춰야할 가장 중요한 요소 중 하나 입니다. 현재 만들고 있는 앱이 사용자의 접근성을 해치진 않는지 한 번 검토해보는 것도 중요하다고 생각합니다.

DDD, 헥사고날 아키텍처, 마이크로 프론트엔드

모두 오버엔지니어링으로 카테고라이징이 되어 있습니다. 저도 그렇게 생각합니다. 대규모 프로젝트가 아니고서는, 심지어 대규모 프로젝트라고 하더라도 도입은 충분한 고민 후에 그리고 필요에따라, 무엇보다 구성원의 동의와 함께 도입되어야 한다고 생각합니다. 왜냐하면 진입장벽이 존재하고 진입장벽이 존재한다는 사실 자체만으로 앱의 안정성을 해칠 가능성이 있기 때문입니다.

디자인시스템

디자인 시스템은 앱 개발의 생산성을 높여주는 중요한 요소 중 하나 입니다. 하지만 이 글에서 언급한 것처럼 처음부터 발명하고 구현하고 유지보수 하는 건 일정 규모의 조직이 아니고선 생각보다 많은 비용을 발생시키는 오버엔지니어링 입니다. 대신 외부 라이브러리를 가져와 그대로 사용하거나 우리 앱에 맞게 커스터마이징 하는 걸 고려해보는 게 좋다고 생각합니다.

0
5
준프

준프

값 객체에 대해 아시나요?

프론트엔드 개발자로서 일을 하다보면 종종 나누는 이야기가 있습니다. 그 중 하나는 바로

"프론트엔드 개발을 하면서 클래스를 써본 경험이 있나요?"

입니다. 전 종종 쓰기도 하고 곧 블로그로 글을 쓸 예정인데요, 이번에 소개해드릴 글은 클래스를 사용할 때 유용한 개념 중 하나인 '값 객체Value Object' 입니다. 값 객체는 이미 존재하는 타입(예를 들어 string, Date 등)을 통해 만드려는 시스템을 표현하는 데 한계가 있을 때 사용합니다.

예를 들어, 아래와 같이 개발하실 때가 많을 텐데요.

const startDate = new Date(2023, 1, 1);
const endDate = new Date(2023, 1, 2);

if (startDate > endDate) {
  // 값이 잘못됐다는 오류
}

// 이 코드가 반복돼서 아래와 같이 함수 제작

function isStartGreaterThanEnd(startDate, endDate) {
  return startDate > endDate;
}

if (isStartGreaterThanEnd(startDate, endDate)) {
  ...
}

이렇게 하는 대신 값 객체를 사용하면 아주 그럴싸(응집도가 올라가는 등)해집니다.

class EventDate {
  #date;
  constructor(date) {
    this.#date = date;
  }

  ...

  greaterThan(date) {
    return this.#date > date;
  }
}

const startDate = new EventDate(new Date(2023, 1, 1));
const endDate = new EventDate(new Date(2023, 1, 2));

if (startDate.greaterThan(endDate)) {
  ...
}

}

하지만 이런 값 객체를 사용하려면 몇 가지 지켜야할 내용이 있는데요, 찾아보면 생각보다 어려운 개념들이 많고 DDD와 관련된 내용도 많아서 접근하기가 꺼려지는게 사실입니다.

그래서 길가다 주운 좋은 아티클을 소개드리려고 합니다. (영어지만 요즘은 AI가 번역해준다는 사실... ㅎㅎ)

그리고 조만간 관련해서 블로그를 통해 소개해드리겠습니다 !

0
0