입사 첫 주, 팀장님이 슬랙으로 메시지를 보내셨다.
"이 컴포넌트 파악해서 기능 하나 추가해줘요. 간단한 거예요 😊"
파일을 열었다. 스크롤이 끝나지 않았다. 변수 이름은 a, temp2, finalFinal_v3. 주석은 세 줄짜리 TODO인데 날짜가 2019년. 그리고 어디에도 테스트 코드는 없었다.
그 순간, 학원에서 배운 깔끔한 컴포넌트 구조와 현실의 간극이 얼마나 큰지를 온몸으로 실감했다.

처음엔 그냥 읽으려고 했다
첫 번째 시도는 "일단 전부 읽어보자"였다. 파일 하나가 1,200줄이었다. 컴포넌트 하나에 API 호출, 상태 관리, UI 렌더링이 모두 뒤섞여 있었다. 어떤 함수가 어디서 호출되는지 따라가다 보면 다른 파일로 넘어가고, 거기서 또 다른 파일로 넘어갔다. 2시간을 읽다가 머릿속이 하얘졌다.
그때 선배 개발자 한 분이 옆에서 한마디를 해주셨다. "코드 읽지 말고, 동작 먼저 봐요."
동작을 먼저 파악한다는 것의 의미
브라우저를 열고 실제로 화면을 클릭해봤다. 어떤 버튼을 누르면 어떤 변화가 생기는지, 어떤 입력에 어떤 결과가 나오는지를 먼저 손으로 기록했다. 마치 QA 테스터처럼. 그 다음에 코드를 열면 달랐다. "아, 이 함수가 저 버튼의 핸들러구나"가 눈에 들어오기 시작했다.
코드는 맥락이 있어야 읽힌다. 맥락 없이 코드를 읽는 건 줄거리 모르고 영화 대본을 읽는 것과 같다.
변수 이름이 최악이라면, 직접 붙인다
가장 고통스러운 건 의미 없는 변수명이었다. 실제로 마주쳤던 코드 일부를 재현하면 이런 식이었다.
const x = getData();
const temp = x.filter(v => v.flag === 1);
const result2 = temp.map(item => ({
...item,
val: item.price * 1.1
}));
flag가 뭔지, val이 뭔지, 왜 1.1을 곱하는지 아무것도 적혀 있지 않았다. 나는 주석을 달기 시작했다. 코드를 수정하는 게 아니라, 내가 파악한 내용을 임시로 써넣는 것이다.
const x = getData(); // 전체 상품 목록
const temp = x.filter(v => v.flag === 1); // flag=1: 판매 중인 상품만
const result2 = temp.map(item => ({
...item,
val: item.price * 1.1 // 부가세 10% 포함 가격
}));
이렇게 하면 두 가지가 생긴다. 첫째, 내가 틀렸을 때 코드리뷰에서 잡힌다. 둘째, 맞았을 때 진짜 리팩토링의 기반이 된다. 이 작업을 나는 "코드 번역"이라고 불렀다.
건드리기 두려울 때 — "작은 실험"의 힘
기능 하나를 추가해야 했는데, 솔직히 무서웠다. 내가 이 코드를 건드렸다가 다른 뭔가가 깨지면 어쩌지. 테스트도 없고, 문서도 없고.
그래서 나는 console.log를 적극적으로 활용했다. 수정하기 전에 현재 상태를 전부 콘솔에 찍어보고, 내가 바꿀 부분이 어떤 값을 가지는지 확인했다. 그리고 변경을 최소화하는 방향으로 접근했다.
선배에게 물어보는 타이밍
처음에는 모르는 게 생기면 혼자 너무 오래 붙잡았다. 2~3시간을 혼자 씨름하다가 결국 물어보면 선배가 1분 만에 설명해줄 때의 그 허탈함. 반대로, 너무 자주 물어봐서 눈치를 보게 될 때의 불편함도 있었다.
내가 정한 기준은 이것이다. 30분 안에 진전이 없으면 물어본다. 단, 물어보기 전에 내가 시도한 것들을 정리해서 같이 가져간다. "이게 왜 안 되죠?"보다 "이렇게 해봤는데 이 부분에서 막혔어요"가 훨씬 빠르게 해결된다. 선배도 맥락을 알아야 도와줄 수 있으니까.
레거시를 마주하고 나서 바뀐 것
3개월이 지나자 그 컴포넌트가 나름 손에 익었다. 무섭던 코드가 "아 이건 이래서 이렇게 짜였구나"로 보이기 시작했다. 완벽하진 않지만, 그 코드가 왜 그 모양이 됐는지의 역사가 조금씩 보였다.
마감에 쫓겨서 임시방편으로 짠 코드, 당시에는 최선이었지만 요구사항이 바뀌면서 덕지덕지 붙은 조건문들. 레거시 코드는 나쁜 개발자가 만든 게 아니었다. 시간과 압박과 변화 속에서 자연스럽게 만들어진 결과물이었다.
신입 시절 내게 해주고 싶은 말
한 번에 다 이해하려 하지 마라. 레거시 코드는 며칠 만에 파악되지 않는다. 한 번에 한 함수, 한 번에 한 흐름. 작은 단위로 쪼개서 접근하다 보면 어느 날 갑자기 전체 그림이 눈에 들어오는 순간이 온다.
그리고 무엇보다, 모르는 게 당연하다는 걸 인정하는 것부터 시작해라. 신입이 레거시를 처음 보고 바로 이해한다면, 오히려 그게 더 이상한 일이다.
1. 코드보다 동작을 먼저 파악하라
2. 이해한 내용을 주석으로 즉시 기록하라
3. 리팩토링과 기능 추가는 분리하라
4. 30분 막히면 물어봐라, 단 시도 내용을 정리해서
5. 레거시 코드에는 역사가 있다 — 욕보다 먼저 이해하려 해라
혼자 무작정 읽다가 포기하셨나요, 아니면 나름의 방법을 찾으셨나요? 신입 시절 레거시 코드 때문에 겪었던 에피소드가 있다면 댓글로 공유해 주세요 😄 비슷한 경험을 가진 개발자들끼리 이야기 나눠봐요!