TOC
들어가며
이틀 전인 1월 14일, 토스에서 Frontend Fundamentals라는 멋진 이름의 문서를 공유했어요. 예고도 없이 "변경하기 쉬운 프론트엔드 코드를 위한 지침서" 라는 부제를 내걸고 등장했고, 개발 업계가 떠들썩했습니다.

가감 없이, 이틀동안 주변에서 공유해준 내용을 본 게 링크드인에서 3개, 카톡방에서 4개는 되는 것 같아요. 물론 제가 프론트엔드 생태계 속에 있어서 그렇지만 그만큼 프론트엔드 업계에선 엄청난 파급력을 보여준 것 같습니다.


내용 정리
변경하기 쉬운 코드
처음으로 코드와 관련해 등장한 서두를 장식한 첫 문장이었어요. 변경하기 쉬운 코드. 실용주의 프로그래머라는 책을 책 스터디에서 읽은 적이 있었는데, 그때 당시에도 책 전반적으로 ETC(Easy To Change) 에 대한 내용들이 꾸준히 강조되었어요. 결국 변화에 유연하게 대응할 수 있어야 하는 것은 프로그래밍의 기본이자 진수인 것 같습니다.
좋은 코드를 위한다고 한 문서이지만, 사실은 '변경하기 쉬운 코드'의 4가지 요소(가독성, 예측가능성, 응집도, 결합도)에 대해서 구체적인 예시로 풀어주는 내용이었어요. 변경하기 쉬운 코드가 좋은 코드라고 못을 박은 것 같았습니다. (저도 동의합니다.)
와닿는 내용 모음
코드 품질 여러 각도로 보기
좋은 코드를 위한 4가지 기준을 모두 한꺼번에 충족하기는 어려워요. 프론트엔드 개발자는 현재 직면한 상황을 바탕으로, 깊이 있게 고민하면서, 장기적으로 코드가 수정하기 쉽게 하기 위해서 어떤 가치를 우선해야 하는지 고민해야 해요.
가독성
가독성을 지키려면 코드가 한 번에 가지고 있는 맥락이 적어야 해요. 하나의 컴포넌트가 가지고 있는 맥락이 다양하면 컴포넌트의 역할을 한눈에 파악하기 어려워져요.
코드에서 추상화
코드에서도 구현 상세를 지나치게 드러내는 경우, 이 코드가 어떤 역할을 하는지 정확하게 파악하기 어려워요. 한 번에 6~7개 정도의 맥락을 한 번에 고려해 가면서 읽을 수 있도록, 보다 작은 단위로 추상화하는 것이 필요해요.
로직 종류에 따라 합쳐진 함수 쪼개기
- 이 Hook이 담당할 책임이 무제한적으로 늘어날 가능성이 있어요. 새로운 쿼리 파라미터가 추가되면, 무의식적으로 이 Hook이 관리하게 되죠.
- 좋은 성능을 위해서는 특정한 상태 값이 업데이트되었을 때 최소한의 부분이 리렌더링되도록 설계해야 해요.
저의 경험
제가 hook에 대한 클린한 코드 개념이 없었을 때, 딱 이렇게 컴포넌트 전체에서 쓰이는 로직 전체를 hook에 몰아넣고 관리한 적이 있어요. 그리고 컴포넌트 자체가 도메인 단위별로 쪼개지니 괜찮지 않은가 나름의 정당함도 있었죠. 하지만 그게 아니라는 사실을 알고 많이 바뀌었습니다. 제 과거의 코드를 보는 것 같아 민망하네요.
이름 겹치지 않게 관리하기
- 같은 이름을 가지는 함수나 변수는 동일한 동작을 해야 해요. 작은 동작 차이가 코드의 예측 가능성을 낮추고, 코드를 읽는 사람에게 혼란을 줄 수 있어요.
저의 경험
블로그에서 Lottie를 사용할 일이 있었는데, Lottie가 내부적으로는 Client Component여서 Server Component에서는 오류가 발생했어요. 하지만 저는 Lottie를 위해 Server Component를 Client Component로 변경하고 싶지 않았습니다. 그래서LottieClient
를 별도로 만들고 props까지 더 편하게 사용할 수 있도록 설계했던 경험이 있어요.Lottie
로 이름을 중복해서 지을까 하다가 피했던 기억이 있네요.
함께 수정되는 파일을 같은 디렉토리에 두기
- 함께 수정되는 소스 파일을 하나의 디렉토리에 배치하면 코드의 의존 관계를 명확하게 드러낼 수 있어요. 그래서 참조하면 안 되는 파일을 함부로 참조하는 것을 막고, 연관된 파일들을 한 번에 삭제할 수 있어요.
저의 경험
실제로 고전적인 아키텍처는 api, hook, constant, type 등등 큰 계열로 나누고 도메인을 쪼개놓은 구조에요. 회사에서도 사용해봤던 구조이고요. 그런데 한 가지 도메인을 추가할 때 물리적으로 멀리 떨어져있는 깊은 폴더 속에 가서 작은 코드들을 각각 쪼개 넣어주어야 하는 것이 너무 불만이었어요. 그래서 저희도 서비스 전반적에 사용되는, 도메인이 묻지 않은, general한 요소들은 그대로/src/shared
위치에 폴더를 두어 다루는 도메인(ex. /time, /regex 등)에 따라 폴더를 분리해 유지해줬어요. 그리고 도메인마다 tree 구조로 쪼개어 각 계층에서 서브 도메인을 붙여 사용했죠.
└─ src
│ // 전체 프로젝트에서 사용되는 코드
├─ components
├─ containers
├─ hooks
├─ utils
├─ ...
│
└─ domains
│ // Domain1에서만 사용되는 코드
├─ Domain1
├─ Domain.tsx
├─ Domain.style.ts
├─ domain.api.ts
├─ domain.util.ts
├─ domain.type.ts
└─ ...
이제는 팀원들 모두 너무 만족하는 아키텍처 방식입니다.
중복 코드 허용하기
- 처음에는 비슷하게 동작한다고 생각해서 공통화한 코드가, 이후 페이지마다 다른 특이한 요구사항이 생겨서, 점점 복잡해질 수 있어요. 동시에 공통 코드를 수정할 때마다, 그 코드에 의존하는 코드들을 일일이 제대로 테스트해야 해서, 오히려 코드 수정이 어려워지기도 하죠.
- 중복코드에 냉철해질 필요가 있겠네요. "중복코드라고 모두 합쳐야 해!"가 아니라, 현재와 미래를 고려해 판단해야 하겠습니다.
적용해볼 내용 모음
복잡한 조건에 이름 붙이기
- 익명 함수와 조건이 복잡하게 얽혀 있어요. filter와 some, && 같은 로직이 여러 단계로 중첩되어 있어서 정확한 조건을 파악하기 어려워졌어요.
- 조건에 명시적인 이름을 붙이면, 코드를 읽는 사람이 한 번에 고려해야 할 맥락을 줄일 수 있어요.
저의 경험
조건을 언제는 이름을 붙여 분리하고, 언제는 그대로 두는 게 나을지 애매할 때가 많았어요. 길이로 따지자니 길기만 하고 간단해서 바로 읽히는 경우가 있거나, 난이도로 따지자니 주관적이었죠. 하지만 이러한 기준에 대해서도 정리주어서 이를 참고해 코드를 개선하려 해요. (조건식에 이름을 붙이는 기준)
시점 이동 줄이기
- 시점 이동 : 코드를 읽을 때 코드의 위아래를 왔다갔다 하면서 읽거나, 여러 파일이나 함수, 변수를 넘나들면서 읽는 것
- 코드를 위에서 아래로, 하나의 함수나 파일에서 읽을 수 있도록 코드를 작성하면, 읽는 사람이 동작을 빠르게 파악할 수 있게 돼요.
checkIs...Valid
- 반환 타입을
{ ok: boolean, reason?: string }
등으로 통일한다. - 이후에 현업에서 새로 프로젝트를 구성한다면,
checkIs...Valid
함수에 반환 타입을 적용해봐도 좋을 것 같다고 생각했어요. 서비스 특성상 toast message나 error nudge 등을 줄 일이 많은데, validation check util에서 함께 관리되면 편하겠다고 생각했습니다.
소감
나는 얼마나
'나는 이 내용 중에 얼마나 많은 내용을 지키고 있었나...' 하는 반성을 했어요. 물론 토스 FE Accelerator 멘토링을 진행하며 관심사별로 코드의 응집도를 높이고 서로 결합도를 낮추는 모듈 방식으로 개발하려고 노력하면서 코드 스타일이 많이 좋아졌다고 주변으로부터 평을 듣고 있어요. 하지만 아직 갈 길이 멀다는 생각도 듭니다.
한 번만 보고 지나치는 게 아니라, 앞으로도 필요할 때 지침서대로 종종 보면서 코드 스타일에 대한 검토와 리뷰의 기준으로 삼아보려 합니다.
고민을 공유해보자
사실 개발을 하다보면 이 코드가 좋은 코드인가, 더 좋은 방식은 없을까 고민하고 설계하는 시간이 많아요. 팀원과 코드 구조와 방식에 관해 갑론을박이 이어지는 경우도 많고요. 이럴 때 커뮤니티를 활용해봐도 좋겠다는 생각을 했습니다.
또 한편으로는 다른 사람의 고민과 커뮤니티의 반응을 보며, 개발 방향의 합리적인 근거를 얻어갈 수 있겠다는 점도 매력적이어 보여요. 앞으로도 잘 활용하며 디스커션의 글을 보기도, 저도 고민거리에 대해 글을 쓰기도 해볼 생각입니다.

지원서 리뉴얼 프로젝트를 진행하면서 팀원들이랑 소통했던 내용 중에 enum
과 as const
에 대한 논의가 있었는데, discussion 중에 이게 눈에 딱 띄어서 링크를 남겨둡니다.
투표도 있어서 얼마나 많은 사람들이 어떤 방식을 채택해 사용하고 있는지 데이터도 확인해볼 수 있어요. 저희는 as const
를 채택해 사용했는데, 무려 73%가 as const
를 사용하고 있네요.
적극적인 세상 사람들
이렇게 각 글의 giscus 댓글을 열어두어 유저들이 글을 쓸 수 있게 되어있는데요, 많은 유저들이 자신들의 고민과 생각들을 적어두고 이에 대해 소통을 하고 있습니다. 공식 사이트에 쓴 댓글인만큼 성심성의껏 댓글을 달아주신 분들이 많으니 discussion이 아니더라도 댓글을 천천히 읽어보는 것도 좋은 공부가 될 것 같아요.

대단한 영향력이다
과연 토스구나 싶었습니다. 회사를 다니는 몇몇이 모여 '좋은 코드의 기준'이라는 이름을 걸고 공식적으로 무언가를 낼 수 있다니, 그 개발 생태계를 위한 헌신과 노력, 그리고 능력과 자신감에 놀랐어요.
또 회사 차원에서도 이를 공식적으로 지지해주고, 번듯한 사이트를 만들어 모든 프론트엔드 개발자들에게 영향력을 행사하는 이 광경이 참 멋지기도 했습니다. 역시 개발에 진심인 회사구나 싶었어요.
재미 있는 사실
화질구지네요
처음엔 이 Frontend Fundamentals를 출퇴근이나 오가면서 틈틈히 보려고 홈 화면에 저장
을 했는데, 저장된 아이콘이 상당히 많이 깨지는 걸 볼 수 있었습니다. 뭔가 잘못됐나? 하고 지우고 다시 해봤는데 역시나 같았습니다.

뭐... 내부 내용이 좋으니 화질구지면 어떻고 파비콘이 없으면 어떻겠습니까...만은 아쉬운 건 어쩔 수 없네요.
응~ 니 코드 더러워
토스의 프론트엔드 리더이시자 자타공인 스타 개발자, 진유림님께서는 이 Frontend Fundamentals의 1저자(출처 - 저작자)입니다. 진유림님 링크드인을 보게 되었는데 이런 식으로 적혀 있었어요.

이 멋진 글의 제목이 Code Smell Wiki일 뻔 했다니, 믿겨지십니까? 하지만, 거짓말은 아닌 것 같아요. 실제로 문서에 👃 코드 냄새 맡아보기
라는 제목이 꽤나 자주 등장합니다.

하지만, 사람들로부터 흥미를 끌기엔 정말 괜찮은 제목이었다고 생각합니다🤣🤣
Frontend Clean Code
진유림님 이야기가 나와서 말인데, 3년 전 Slash21에서 진유림님께서 발표하신 영상이 있어요. 바로 "실무에서 바로 쓰는 Frontend Clean Code"라는 이름의 영상입니다. 2년 전에 취업준비할 때 유튜브에 있는 개발 영상을 쓸어담으며 보던 당시에 상당히 기억에 남는 영상이었어요.

혹시 안 보신 분들이 계시다면 20분 정도의 영상이니 잠깐 훑어보시는 걸 추천드립니다. 저한테는 깨달음이 있었던 영상이거든요.
마치며
토스는 왜 그럴까?
기업은 이익을 쫓는 집단이에요. 하지만 토스, 그리고 토스의 개발자들은 개발자를 위한 사회적 기업처럼 개발 생태계에 엄청나게 많은 영향력을 행사하고 있어요. es-toolkit은 세계적인 개발 라이브러리에 유틸들을 제공하고 있고, funnel 구조 등 개발 방법론에 대한 제안도 많이 이뤄내고 있고요. 이게 토스에 실력 있는 개발자들을 끌어 모으는 선순환으로 이어지는 것 같습니다. 그게 토스가 생각하는 이익이 아닐까 싶네요.
이 멋진 개개인처럼
이 Frontend Fundamentals를 읽으며 간결하게, 또 임팩트 있게 좋은 코드에 대한 글을 가볍게 되새기게 되었습니다. 좋은 경험이었습니다. 구성원 개개인이 전체 개발 생태계에 미치는 영향력, 그런 노력과 기여가 저에게도 정말 멋지게 다가옵니다. 저도 잘 갈고 닦아서 많은 사람들에게 좋은 영향을 줄 수 있는 사람이 되고 싶네요.
긴 글 읽어주셔서 감사합니다.