개발자
류준열
게시글 전체 보기

클로드코드랑 금요일에 만든 것
플래시게임, 개발 최신 동향 모음집 2개를 만들었다.

입코딩
datocms 프리티어가 다되어서 이미지 업로드가 안된다. 라이센스 업그레이드 하면 월 200유로다.. 클로드코드는 신이다. 클로드코드, dotoCMS MCP, supabase MCP를 이용해서 약 1시간만에 마이그레이션했다. 이젠 정말 아이디어 to 배포다

성능측정 귀찮아 (Saas 종말론)
성능최적화 매번 하는게 귀찮아서 Saas를 찾아봤는데 UX도 뭐 어쩌라는건지 모르겠고 해서 그냥 내가 직접 만들었다. 클로드코드는 신이다. 이래서 Saas 종말론이 나왔나보다.

크롬익스텐션 만들어서 동료 일 덜어주기
우리 회사는 랜딩페이지를 자주 배포한다. 디자이너분의 검수를 조금이나마 편하게 해드리고자 크롬 익스텐션을 만들었다.

되돌아보니
나중에 가면 똑같이 생각할 것 같다. 되돌아가면 지금 32살 이 시간에 내가 원하는 삶을 살겠다고 오버하지도, 겁먹지도 말고 그냥 나답게 살자.

40 Questions to ask your self every year
한 해 회고할때 쓰는 40가지 질문

Vercel의 React Best Practice - Waterfall
Vercel에서 React BestPractice skill이 공개되었다. 한줄 한줄 읽어보는데, AI를 떠나서 프론트엔드 개발자로써 인사이트를 많이 얻는다. AI가 나오기 전부터 나만의 클린코드로 갈고 닦은 내용도 있고 생소한 내용도 있다.

AI 이용 2주차 응애
AI를 본격적으로 공부한지 2주가 되었다. 생산성이 올라간다. 회사에서 문서화 한 김에 블로그에도 작성한다.

AI를 배우면서
이제 내가 발견하는 대부분의 작은 문제들은 입코딩으로 1시간만에 해결이 가능해졌다.

일하는 방식의 변화
todolist.md를 통해 스펙을 고정하고 AI는 피드백 루프를 통해 제품이 완성될때까지 작업하도록 했다. todolist가 명확하니 헛짓거리 없이 제품을 잘 만들었다. (중간에 클로드코드에서 코덱스로 변경했음에도 불구하고

Reverse Proxy 적용하여 백엔드 띄우기
바이브코딩으로 만든 사이드프로젝트 서버가 터졌다. 인증서가 만료되어 있었다. 인증서를 갱신하는 과정에서 Reverse proxy를 적용하였는데 그 과정을 기록

모바일 사파리에서 키보드가 올라올때 생기는 가상영역 문제
모바일에서는 사파리 특유의 부드러움을 위해 가상 키보드 생성시 동적 화면 변경을 처리하는 방식에서 가상 공간이 나타난다. 스크롤 할 때 키보드를 비활성화 하는 방식으로 이를 해결했다.

tailwind 만들어보기
개발자가 미리 약속된 class 이름만 써준다. 빌드 시점에 그 약속된 CSS를 만들어 준다. 아이디어만 놓고 보면 정말 단순한데, 이 단순함을 구현해서 전 세계적으로 인기 있는 라이브러리를 만들다니

오픈소스에 기여
label을 string으로만 받는 코드였는데 커스텀 할 수 있도록 타입을 ReactElement로 바꾸고 PR을 날렸다. 머지되었다.

모달 렌더링 속도 66% 향상 (150ms -> 50ms)
레이지 로딩이 안되는 문제를 처리하는 과정에서 display:none과 react-slick이 일으키는 레이아웃 쓰래싱을 발견하고 모달 전체 렌더링 속도를 66% 향상시켰다. (150ms -> 50ms)

랜딩페이지 최상단 섹션 렌더링 속도 개선
지하철 모바일 환경에서의 랜딩페이지 최상단 섹션의 렌더링 속도를 개선하기 위한 작업들을 했다. 가장 빠르게 확인 할 수 있는 작업인 lazy loading과 폰트 최적화를 하고 전,후 변화를 측정했다. 모바일 라이트 하우스가 18% 개선되었다.

자이온을 퇴사하고 새로운 회사에 입사하기까지
4달 전에는 돈을 벌려고 일을 하는 거면 돈만 벌면 되지 않나? 라는 생각을 했고, 4달간의 삽질을 통해 나는 나를 더 사랑해주어야겠다는 결론을 내렸다.

캘린다이어리
동네친구의 아이디어로 만든 일기공유 서비스

랜딩페이지, 이벤트페이지 외주 안되는거 없습니다
랜딩페이지, 이벤트페이지 외주 안되는거 없습니다.

canvas.toBlob을 이용한 이미지 압축 (약 97% 압축)
base64로 이미지를 전송하다보니 서버에서 413에러로 튕겨냈다. canvas.toBlob을 이용해서 브라우저에서 직접 압축했는데 약 97% 압축되었다. (4.5MB -> 94.6KB)

딸깎DD를 하며 느낀 것
사람들은 가치를 느끼면 돈을 낸다. 그렇기 때문에 뭘 만들지보다 어떻게 팔 수 있을까 부터 생각해야 한다. 팔 수 있는걸 만들어야 한다.

마케팅이 중요한듯
뭘 하는진 중요하지 않다 어떻게 하는지가 중요하다. 아무리 열심히 만들어도 사람들에게 알려지지 않으면 잊혀지는거다

img 태그의 referralPolicy
이미지에서 액박이 뜰대는 referralPolicy 속성을 이용하면 된다.

한국어 받아쓰기 서비스 sitemap 동적 생성
한국어 받아쓰기 서비스 sitemap 동적 생성하여 별도 작업없이 추가된 컨텐츠 구글에 자동노출

유튜브 쇼츠 기반의 받아쓰기 서비스
유튜브 영상으로 받아쓰기 하는 기능 생성

제품팀은 PO 중심으로 움직여야 한다.
제품은 문제를 해결해야 하고, PO의 역할은 문제를 정의하는 것이다. 그렇기 때문에 제품팀은 PO 중심으로 움직여야 한다.

경험
경험

React 외부에서 상태관리 하여 컴포넌트 호출하기(toast)
useToast를 만들어 쓰고 있었는데 이는 컴포넌트, 훅 외부에서 사용할 수 없다는 한계가 있다. this는 메소드가 자신을 호출한 객체를 가리킨다는 성질을 이용하여 React 외부에서 상태를 변경 할 수 있다.

잘하자
지난 1년동안은 그냥 떠다니는 유령처럼 산 것 같다. 꿈도 없었고 그래서 목표가 희미했기 때문이다.

Icon 컴포넌트 개발기
svg 중복 생성을 방지하기 위해 피그마 정보를 이용한 Icon 컴포넌트를 만들었다.

서버 컴포넌트에서 prefetch하여 깜빡임 해결하기
서버 컴포넌트에서 데이터를 prefetch하여 클라이언트에서 즉시 활용할 수 있도록 구성했다.

module federation에서 코드 수정 후 저장하면 새로고침 되는 문제
HMR은 단일 어플리케이션 내에서 모든 의존성 그래프를 파악하고 있는 상태에서 동작하지만 module federation은 독립된 webpack을 가진 앱들이 커스텀 이벤트로 통신하기 때문에, HMR의 전제(모든 의존성 그래프 파악)과 맞지 않는다.

Props변화와 리렌더링은 무관하다.
Props 변경이 리렌더링을 일으킨다는 글들이 많다. 사실이 아니다.

폐쇄망에서 겪은 서버컴포넌트 문제
폐쇄망 서버에서는 해당 인프라의 hosts 에 등록되지 않은 도메인에 접근할 수 없다. 하지만 브라우저는 로컬 PC의 hosts 파일을 참조하기 때문에 폐쇄망 서버와 무관하다.

설계 리뷰
1. 할 일과 하지 않아도 되는 일을 명확히 함으로써 에너지를 흩뿌리지 않는 것. 2. 서로 동일한 이해도를 갖는 것

빨리 만드는게 가장 중요한 상황
그러면 잠재적 버그가 가득해도 상관없다는 말인가? 세분이 차례차례 답변을 해주셨는데, 결론은 다음과 같다. 일단 레퍼런스를 쌓고, 데이터를 쌓고, 사용자를 늘려야 하는 상황이다. 재무재표를 보는 사람과, 기술자의 차이를 다시 한번 느꼈다. 나는 회사에 돈을 벌어줘야 하는 기술자다.

Next.js에서 런타임에 환경변수를 설정 할 수 있게 하는 법
Node.js가 없는 고객사 PC에서 환경변수를 수정하려면 본사인원에게 빌드를 요청하고 파일을 메일로 주고받는 번거로움이 있었다. 하지만 런타임에서 환경변수를 설정 할 수 있게 되면, docker-compose만 수정하면 되므로 빌드 없이 어떤 환경에서든 즉시 배포가 가능해진다.

Array 메소드에 async await 넣으면 순서 보장 안된다.
회사에서 리포트 발행 기능을 만드는데, 리포트 페이지가 뒤죽박죽으로 발행되었다.

일이 되게 하는 방향으로
준열님 오시고 나서 주간회의도 하고 아사나도 하게 되어서 좋은 것 같아요. 업무 공유도 되고 협업하는게 편해졌어요

함께 자라기
팀을 성장시키는데 중요한 요소는 심리적 안전감이다. 심리적 안전감은 일상에서 조금씩 쌓아가는 상호간의 존중에 기반한다. 우리팀을 최고의 팀으로 만들기 위해 내가 지금 바로 할 수 있는 행동은 동료를 존중해주는 것이다.

동시성 렌더링
동시성 렌더링은 두가지 일을 동시에 하는게 아니라 우선순위를 조정해서 동시에 하는 것 처럼 보여주는 것이다.

Git Flow 만든 사람이 Git Flow 쓰지 말라 한 거 아세요?
현재의 소프트웨어 개발 방식은 Git Flow가 구상될 당시와 다르다. 만약 지속적 배포를 통해 고객에게 제품을 전달한다면 더 간단한 workflow를 추천한다. 하지만 다양한 버전들이 고객들에게 제공된다면 여전히 Git Flow가 적합할 수 있다.

내가 생각하는 비제어컴포넌트 이상의 react-hook-form
리렌더링을 줄이니 어쩌니 하는게 중요한게 아니다. Form을 Form답게 관리할 수 있는 것이 중요한거다.

pnpm create mf-app 프로젝트에서 url 접근시 404 뜨는 버그
module federation을 사용하는 프로젝트는 각 어플리케이션들이 자체적으로 라우팅을 처리 할 수 있도록 모든 경로를 index.html로 리다이렉트 시키지 않는다.

시키는대로만 하는 제품팀은 권한없는 책임만 갖게 된다.
만약 '위에서 시키는 대로 해야지' 라며 순응하는 자세였다면 아마 이 프로젝트는 망했을것이고 권한없는 책임만 갖게 되었을 것이다.

Next 환경변수의 비밀: 빌드타임 환경변수
Next.js에서의 환경변수는 빌드타임에 등록된다. 쿠버네티스에서 환경변수는 컨테이너 이미지가 빌드된 후 런타임에 주입된다. 그래서 쿠버네티스+Next.js 조합에서는 둘중에 하나를 변경해주어야 한다.

마이크로 프론트엔드끼리 빌드된 타입 정보 공유
Module federation을 통해 두 마이크로 프론트엔드를 공유할때 타입스크립트에서 타입을 인지하지 못하는 문제가 있었다. 이럴땐 @module-federation/typescript를 이용하여 빌드된 타입정보를 각 마이크로 프론트엔드 간에 공유 할 수 있다.

면담기록
피드백들을 밟고 작은 발전을 이루어가는 과정속에 PO,PD,SE의 전문성이 모두 필요하기 때문에 개발자는 수동적인 존재가 아니라 주도적으로 제품을 개발해야 하는 존재임.

Module Federation을 이용한 Micro Frontend 예제
회사에서 각 기능들을 모듈별로 관리하기로 했다. 하나의 제품안에 있는 여러 기능 모듈들을 효율적으로 그리고 안정적으로 관리하기 위해 Micro frontend를 도입하기로 결정했다.

prefetchQuery 이용해서 로딩제거
prefetchQuery를 이용해서 서버 컴포넌트에서 데이터를 캐싱하고 클라이언트 컴포넌트에서는 캐시에서 데이터를 가져옴으로 로딩을 제거 할 수 있다.

next.js에 다국어 기능 넣기
useTraslation 훅을 통해 언어를 관리하는 경우 새로고침이나 링크 공유시에 언어가 초기화 되는 이슈가 있었다. 페이지 구조를 엎어야 했다.

업무 프로세스 개선에 기여
'다들 문제 없이 잘 하는데 괜히 내가 설치는건 아닌가?' 라는 의심도 들었다. 며칠전 동료분이 '준열님이 오시고 일하는게 편해졌어요.' 라고 해 주셨다. 내가 팀에 조금은 기여한 것 같아서 기분이 좋았다. 함께 일했던 리더분들을 따라하려 했다. 좋은 동료들과 일했던 것이 큰 행운이다.

access 토큰, refresh 토큰
access 토큰과 refresh 토큰의 만료기간을 다르게 두어 UX를 저해하지 않으면서 보안을 강화할 수 있다.

npm의 유령의존성
개발자의 의도와 무관한 패키지들이 node_modules에 설치되고 제거된다면 어떤 버그들이 생길지 알 수 없다. 말 그대로 유령이다

i18n을 위해 Excel을 JSON으로 전환하는 서비스
번역할 내용이 추가 될 때 마다 JSON을 수동으로 만들어야 하는가? 에 대한 고민이 있었는데 excel을 i18n에 적합한 JSON으로 변환하는 간단한 html을 만들었다.

노션 API 이미지 액박 문제 구글드라이브로 우회하여 해결한 경험
노션에 이미지를 업로드하면 1시간 후 노션 S3에서 삭제된다. 이는 유저에게 보여지는 이미지들이 액박이 뜨는 문제로 이어졌다.

code spliting으로 성능 개선
게시글 페이지의 page.js에서 highlight 라이브러리를 분리하여 lighthouse 점수를 78 -> 85 로 증가시켰다.

코드스테이츠 정규직 확정되고 썼던 글 (22.4.14)
여튼 어느 주간회의날, 대화를 하다가 어느 단어에 꽃혀서 순간 감정적으로 PM 동료분께 '일을 주말에 하지 않으면 못끝낼 정도로 일을 주고 있다.' 라고 이야기를 했다. '못하겠다고 해도 괜찮으니까 이제 벅차면 얘기하세요.' 라고 말씀해주셨다.

핵클 개발자한테 뜬금없이 연락해서 문제 해결한 날 (22.3.5)
회사 슬랙이 핵클 커뮤니티에 참여중이었는데 핵클 개발자분께 연락해서 고민이 있다고 여쭤보고 싶은게 있다니까 흔쾌히 약속을 잡아 주셨다. 그 부분을 핵클 개발자분께 여쭤봐서 해결할 수 있었다.

복잡한 비즈니스로직을 프론트에서 구현해야 하는 경우
비즈니스로직이 프론트에 포함된 경우 의존대상과 세부구현을 분리하는 방식에 대해 설명

429에러와 토큰버킷알고리즘
써드파티 라이브러리에 의존하여 작업을 하다보면, 지나치게 낮은 request limit때문에 빈번하게 429 에러를 만날 수 있다. 이는 토큰 버킷 알고리즘으로 request limit에 도달하기 직전에 요청을 지연시켜서 해결 할 수 있다.

setTimeout의 한계와 reqeustAnimationFrame
setTimeout의 delay를 0.5초로 설정하였는데 0.5초가 지나도 call stack이 처리되지 않으면 setTimeout의 callback은 실행되지 않는다. 이렇게 setTimeout이 씹히게 된다.

소프트웨어 장인 독후감
하지만 이것들 보다 가장 중요한건 개발자 개개인이 '소프트웨어 장인 정신'을 갖는 것이다. 소프트웨어 장인 정신이 없다면 나머지는 다 껍데기다.

컴포넌트 라이브러리 npm 배포 (vite,pnpm)
컴포넌트 라이브러리를 npm 배포하는 방법

하이빌리지 : 위치기반으로 가까운 관광지 보여주는 서비스
주말에 어디 놀러갔다 오고 싶어서 구글에 여행지를 검색하면 티스토리 광고글이 가장 상단에 있는 경우가 많다. '시각적으로 한눈에 가까운 관광지를 볼 수 있으면 좋겠다' 라는 생각이 들었다. 그래서 내 주변 가까운 관광지를 보여주는 서비스를 만들었다.

사파리에서 클립보드 복사 이슈
사파리에서는 보안상의 이유로 유저 액션을 통해서만 클립보드 복사가 동작한다.

SSR에서 고려해야 할 것들
next는 SSR을 할 수 있는 리액트 프레임워크이다. JSX문법으로 렌더링 할 코드를 작성하면, next 서버에서 html을 만들어주고 그 이후 hydration이 진행되면서 리액트(CSR)이 진행된다.

자동저장 기능 구현시 고려해야 할 것
지원선발 시스템에서 제출한 설문지의 모든 답변이 초기화 되는 이슈가 있었는데, 재현이 되지 않았다. 나중에 알고보니 다중탭 문제였다. 또한 setInterval이 react 라이프 사이클과 맞물려 작동하지 않는 이슈도 있었다.

도메인 주도 설계란 무엇인가? (Domain Driven Design Quickly)
개발자가 일하는 방식이 지난 십수년간 많이 변화했지만, 동료들과 함께 제품을 만든다는 사실은 변하지 않는다. CTO님께서 이 책은 DDD의 시작에 불과하다고 말씀해주셨다.

블로그 제작기
티스토리에서 블로그를 운영하고 있지만 프론트엔드 개발자가 쌩으로 만든 블로그 하나는 갖고 있어야 하는것 아닌가? 하는 생각에 블로그를 만들게 되었다.

메모이제이션이 필요한 순간
메모이제이션은 자주 쓰이는 값(or 함수)를 캐싱하여 리렌더링시 새로 만들지 않게 하는 것이다. 리액트에서는 `useMemo`, `useCallback`, `memo` 를 통해 구현할 수 있는데 여기서 굳이 설명하지는 않는다.

UI 시스템
UI 시스템의 효과는 두가지이다. 개발자 작업 시간 단축, 디자이너 작업 시간 단축 서로가 서로를 배려하다보니 아무 발전도 하지 못한 지난 1년이었다. 갈등은 더 심각한 갈등을 피하기 위한 것이다. 갈등이 없으면 아무 발전도 없다.

바탕화면 구현을 위해 Draggable.tsx 만들기
Drag and Drop 기능을 만들기 위해 라이브러리들을 검색해봤는데, 바탕화면을 구현하기에 적당한 라이브러리가 없었다. 그래서 직접 만들기로 했다.

Next App router에서 use client가 CSR을 뜻하지는 않는다.
분명히 서버컴포넌트로 렌더링되는건 아닌데,, use client를 사용하면 CSR로 된다는 뜻이 아닌가? 하고 공식문서를 보았다. 공식문서에서 클라이언트 컴포넌트 (use client) 가 어떻게 렌더링 되는지 잘 작성되어 있다.

개발자 류준열 이력서
안녕하세요 기술로 가치를 전달하는 개발자 류준열입니다.