본문 바로가기
항해 플러스

항해 플러스 프론트엔드 4주차 회고(클린코드와 리팩토링 with 바이브 코딩)

by 이의찬 2025. 8. 4.

페어 팀 결성

1~3주차까지는 별개의 팀으로 진행되었지만, 클린코드와 리팩토링 챕터가 시작되는 4주차부터는 2개의 팀을 합쳐 페어팁으로 진행되게 되었다. 나는 6명의 팀장에서 12명의 팀장으로 진화했고, 더 큰 권력을 손에 넣게 되었다.

이번주의 과제

이번주의 과제는 거대하고 더러운 JavaScript 파일 하나로 된 서비스 코드를 나누고, 클린하게 수정한 다음 최종적으로는 React와 TypeScript로 마이그레이션 하는 과제였다.

var totalAmt = 0
var PRODUCT_ONE = 'p1'
var p2 = 'p2'
var product_3 = 'p3'
var p4 = "p4"
var PRODUCT_5 = `p5`
var cartDisp
function main() {
  var root;
  var header;
  var gridContainer;
  var leftColumn;
  var selectorContainer;
  var rightColumn;
  var manualToggle;
  var manualOverlay;
  var manualColumn;
  var lightningDelay;
  totalAmt = 0;
  itemCnt = 0;
  lastSel = null;
  //...

이번 과제를 내준 테오가 발제 때 AI를 적극적으로 사용해보라고 권장했기에 단 하나의 코드도 직접 입력하지 않고, Cursor의 Agent를 사용해서 자연어를 사용한 바이브 코딩만으로 과제를 해결하는 것을 목표로 삼았다. 그렇기에 1주차보다 2주차에서, 2주차보다 3주차에서, 그리고 3주차보다 이번 주차에서 더 AI를 적극적으로 사용하게 되었다.

이번 과제의 진행 방식

우선 ESlint와 Prettier를 설정하고 나서, Cursor Rules(토스 펀더멘탈과 Clean Code 관련 규칙 사용)를 세팅하고

이 다음에 어떻게 해야할지 막막해서 다른 분들이 어떻게 하는지 여쭤보러 다녔는데, 성진님과 지훈님이 "AI에게 docs를 참조해서 개선이 필요한 포인트를 mark down으로 작성시킨 후 진행하고 있다." 라고 하시기에 따라해서 도입했다.

  • 이 부분이 정말 좋았는데, 과제를 하는 동안 늘 Task 분리가 어려워서 고생했었기에 추후에도 계속 사용하려고 한다.
  • 물론 과제의 상세한 요구사항과 클린코드에 대한 지침이 충분해서 가능했을테니, 좀 더 요구사항과 명확한 지침 작성의 중요성을 느꼈다.

단계별로 나눠둔 checklist를 포함한 문서를 작성해주자, 이를 기반으로 다시 AI에게 코딩을 시켰다.

  • 그렇다고 무지성 바이브코딩은 안되니까, 코드를 작성하기 전에 이 코드를 작성했을때의 장점과 단점이 뭔지 작성하도록 시켰다.
    • 만약 이해가 잘 안가면 다시 되물어보면서 해당 작업이 필요여부를 판단하려고 했다.
    • 작업이 필요하다면 해당 작업을 진행하고, 문서를 업데이트 한 후 커밋하도록 했다.
  • AI한테 넣어준 프롬프트는 아래의 '과제를 하면서 신경 쓴 부분'에 작성되어 있다.

AI를 적극적으로 사용하고 느낀 점

1. 확실히 AI를 쓰면 코딩할 때 편하다

AI를 사용하는 동안에는 내가 생각을 덜해도 된다. 코드를 귀찮게 하나하나 읽으면서 이해하지 않아도 되고, 또 직접 수정할 필요도 없었다. 내가 할 일은 AI한테 일을 어떻게 해야할지 생각하고, 그에 따라서 진행하라는 명령 뿐이였다.

AI를 사용해서 나아가는 길은 편했다. 전기 자전거를 요즘 자주 타는데. 페달을 살짝만 밟아도 슝슝 나간다. AI를 사용해서 코딩을 할 때마다 전기 자전거를 떠올리곤 한다. 약간의 노력만 해도 적절하게 보이는 코드를 쭉쭉 만들어주니까.

이런 경험을 하면서, 테오가 '인간은 편리함을 맛본 뒤에는 못돌아가는 존재'라고 말한 것이 생각났다.  앞으로 AI 없이 코딩을 하는 미래는 없을 것이라는 생각이 더 확고해졌다.

2. 하지만 AI를 사용하는게 정말 생산성을 높이는지는 잘 모르겠다

내가 위에 적절하게 보이는 코드를 만들어준다. 라고 적은걸 눈치챘나?

전기 자전거 예시를 들어서 말인데, 전기 자전거는 모터가 있어서 일반 자전거보다 훨씬 무겁다. 만약 자전거가 갈 수 없는 길이거나, 배터리가 떨어지거나, 고장이 난다면? 그냥 커다란 짐덩이가 되는거다.

AI로 코딩하는 것도 마찬가지인데, 얘가 내 명령을 이해하지 못하거나, 제대로 코드를 작성하지 못하면 결국 사람이 직접 코드를 작성해야한다. 그때까지 제대로 확인하지 않았던 코드를 가지고.

이번 과제에서도 이 부분을 실감할 수 있었다. 처음에는 무서워서 ask로만 쓰다가, agent 모드를 조금씩 써보다가, 나중에는 그냥 기능 구현 전에만 확인하도록 했다. 그렇게 슝슝 나가다보니 어느 순간부터 얘가 코드를 박살내고 있었다.

정확히는 심화 과제인 React로 마이그레이션 하는 작업에서 개판이 났는데, 지금 생각해보니 얘한테 정확히 어떤 작업을 해달라고 명시하지 않고 그냥 React로 마이그레이션해줘라고 대충 명령했던게 가장 큰 원흉이였던 것 같다.

결국은 열심히 AI를 두들겨패서 어떻게 해내긴 했는데, 다음 과제에서는 지금보다는 AI 사용 비율을 낮추려고 한다. 일단 task를 가능한 나눠서 먹이는건 당연하고, 매 commit 전에는 AI가 작성한 코드를 리뷰하고 넘기는 식으로 해볼까한다.

AI가 잘 못하는것도 많은 것 같다. 코드에서 중복되는 부분을 찾아서 적절하게 추상화하는 거라든지...

과제를 하면서 신경 쓴 부분

1. 이해하면서 넘어가기

3주차 과제에서는 우선 과제를 완료하고 그 후에 돌아보면서 코드를 이해해보자라고 생각하고 진행했는데, 막상 완료하고 나니까 자연스럽게 과제를 잘 안돌아보게 되더라. 그래서 이번 과제에서는 그냥 넘어가지 않고 매 부분마다 왜 필요한지 설명을 요구하고, 납득이 가면 진행하려고 노력했다.

2. 테스트가 깨지지 않도록 하기

이미 서비스는 다 구현되어 있고, 코드만을 클린하게 리팩토링하는 것이 목표였기에 작성된 Test가 깨지지 않도록, 그리고 UI가 변경되지 않도록 다음과 같이 프롬프트를 입력해서 사용했다.

- 코드의 동작이나 구현이 바뀌면 안되고 반드시 구조 변경(리팩토링)만 해야해
- 사용자에게 보여지는 문구는 절대로 변경되면 안돼.
- 공통으로 쓰이는 파일만 공통 폴더에 넣어두고, 비즈니스 로직이 담긴 경우, 관심사끼리 묶어 폴더로 관리해야해
- src/basic/tests/basic.test.js, src/advanced/tests/advanced.test.js 테스트 코드가 모두 하나도 빠짐없이 통과해야해
- 테스트 코드 검증 여부는 main.basic.js 를 기준으로 검사해야만해. origin 파일은 의미없어.
- 커밋 메세지는 반드시 한국어로 작성해줘. commit title은 `{category}: {titleMessage}`의 형태로 작성해줘 
    - category에는 feature, refactor, fix, docs, style 등의 단어를 적절하게 사용해줘.
- 코드를 작성하기 전, 코드를 작성했을때의 장점과 단점이 뭔지 나에게 알려줘.

-> 결과파일은 main.basic.js 에 적용해줘
-> 작업 후 마지막으로 절대 원칙이 지켜졌는지 한번 더 컴토 후 올바르게 고치고 알려줘

과제를 하면서 아쉬운 점

1. 클린코드에 대한 생각을 정리하기

어쨌건 클린코드 주차에서 어떤 코드가 클린하고, 어떤 코드가 클린하지 않은가를 경험적으로 느꼈다. 하지만 어떤 코드가 클린하고, 어떤 코드가 클린하지 않으며, 어떻게 해야 안티패턴을 피하고 클린한 코드를 작성할 수 있는가? 에 대한 생각은 아직 정리하지 못해서 아쉽다.

2. Cursor 토큰 아껴쓰기

컨텍스트가 쌓이면서 토큰이 엄청나게 들어갔고, 기본 과제를 마무리할 즈음에는 거의 다 토큰이 만료되었다. 결국 심화과제를 위해서 추가적으로 결제를 진행했어야 했다. 준일님 멘토링 시간에 토큰을 어떻게 아끼는지에 대한 질문이 나왔는데, 진작에 컨텍스트를 분리하면서 진행했다면 토큰을 아끼면서 진행할 수 있었을 것 같아 아쉽다.

3. 진작에 심화 과제에서 Task 나눠서 처리하도록 했어야

심화 과제에서 Task를 제대로 나누지 않고 해줘를 했더니 기존 JavaScript 코드를 그대로 가져와서 React에서 DOM을 조작하는 방식을 전혀 사용하지 않고 그대로 갖다박았더라. 바로 다시 다 엎어버리고, 요구사항을 추가해서 Task를 분리해달라고 요청했다.

4. React로 마이그레이션 하는 과정에서 좀 더 React스러운 코드란 무엇인가를 고려해서 추가했으면 좋았을 것

엎은 후 다음 요구사항들을 추가해서 Task 분리를 진행했다.

  1. 로직은 훅, 화면은 JSX로 분리할 것
  2. 직접 DOM 조작 금지
  3. 도메인별로 상수/타입/컴포넌트 분리

하지만 위 사항들이 React스러운 코드를 작성하기 위해 충분한 지시였던 것은 아닌것 같다. 이에 대한 규칙을 명확하게 나만의 언어로 작성해보고 싶다.