새로운 프론트엔드 앱 개발 환경 구축 에 대한 경험 을 공유 합니다 . 
 ( 이 글 은 스 포카 기술 블로그 에 올렸 던 글 의 edit 입니다 . ) 
 안녕 하 세요 . 저 는 이번 에 도도 포인트 앱 의 프론트엔드 를 재 작성 하 는 프로젝트 를 진행 했 는데 , 새로운 프론트엔드 개발 환경 을 구축 하 고 싶 으신 분 들 께 도움 이 될까 하 여 경험 을 공유 해 봅니다 . 
 도도 포인트 의 경우 
 스타트업 은 유연 한 조직 구조 와 빠른 제품 개발 속도 로 기존 의 기업 들 을 앞지를 수 있 습니다 . 스 포카 는 도도 포인트 라는 서비스 를 운영 하 는 스타트업 으로서 , 고객 들 이 원 하 는 제품 에 대한 기능 들 을 빠른 속도 로 제공 해 줄 수 있 어야 하 며 , 또한 서비스 는 안정 적 이 어야 합니다 . 
 도도 포인트 서비스 는 빠른 개발 속도 를 만족 시키 기 위해 HTML 5 기반 의 SPA ( Single Page Application ) 구조 를 가지 고 있 습니다 . 간단히 말 하 자면 , 웹 앱 서비스 라고 볼 수 있 습니다 . 기존 앱 은 Backbone 등 의 라이브러리 들 을 이용 해 작성 되 어 있 었 습니다 . 
 Backbone 은 현장 에서 충분히 많이 사용 하 므로 , 검증 된 라이브러리 라 할 수 있 습니다 . 소위 말 하 는 battle - tested lib 인 것 입니다 . 하지만 많 은 사람 들 이 사용 하 는 것 이 문제 를 자연히 해결 해 주 지 는 않 습니다 . 수년 간 의 개발 진행 후 도도 포인트 앱 은 더 이상 scale up 이 버거울 정도 로 커졌 습니다 . 
 기존 앱 을 수선 할 것 인가 , 재 작성 할 것 인가 
 너무 자세 하 게 이야기 하 면 주제 가 바뀔 수 있 는 바 , 스 포카 개발 팀 이 겪 고 있 었 던 문제 를 간단 하 게 이야기 하 고자 합니다 . 
 도도 포인트 는 빠른 개발 속도 가 중요 하 다 보 니 요구사항 이 충분히 잘 정의 되 지 못한 상태 에서 스케일 업 을 할 때 가 많 았 습니다 . 그러 다 보 니 자연히 모듈 과 함수 들 의 정의 또한 잘 정의 되 지 못하 고 , 재 사용 성 이 떨어지 는 코드 를 작성 하 게 되 었 습니다 ( 주관 적 인 견해 이 나 , Backbone 은 lightweight JavaScript MVC 를 지향 하 다 보 니 그 에 따른 장점 도 있 지만 추상화 가 어렵 고 장황 한 코드 를 작성 하 게 되 는 경향 이 있 다고 생각 합니다 . 이 를 보완 하 는 여러 가지 라이브러리 들 이 있 긴 하 지만 , 도입 하 기 에 는 이미 늦 은 상태 였 습니다 ) . 이 는 자연히 유닛 테스트 의 부재 등 여러 가지 이슈 로 이어지 게 되 었 습니다 . 
 이러 한 문제 로 점점 개발 속도 는 느려 지 게 되 었 으며 SPA 앱 의 특성 상 장애 또한 빈번 하 게 발생 하 게 되 었 습니다 . 이런 앱 구조 에 대한 문제 의식 을 계속 가지 고 앱 을 개선 해 나가 던 와중 , 프론트엔드 를 재 작성 하 자는 이야기 가 개발 팀 안 에서 조금 씩 나오 기 시작 했 습니다 . 
 개발자 라면 한 번 쯤 은 들 어 봤 을 법 한 글 이 지만 , Joel Spolsky 는 Things You Should Never Do 에서 앱 을 재 작성 하 는 것 은 절대 해서 는 안 될 일 이 라고 주장 한 바 가 있 습니다 . 그 의 논지 는 충분히 설득력 이 있 습니다 . 하지만 앱 을 단순히 재 작성 하 는 것 이 아닌 , 더 좋 은 도구 들 을 이용 하 기 위한 기반 을 만드 는 것 이 라면 어떨까 요 ? 
 더 새로운 것 은 더 좋 은 것 이 다 . 아마도 
 Finally a JavaScript book from O ' Reilly that just speaks to me pic . twitter . com / Eg 7 F 91 KwLb 
 — λ Calrissian ( @ mattpodwysocki ) May 13 , 2015 
 모두 들 좋 다 카더라 
 새로운 개발 환경 을 만들 기 위하 여 서베이 를 해 본 결과 , React [ ^ 1 ] 를 이용 해 앱 을 새로 작성 하 는 것 이 좋 겠 다는 결론 에 이르 렀 습니다 . 비록 한국 에 는 리퍼 런 스 가 많 지 않 지만 해외 에 는 굉장히 큰 리 퍼런 스 들 을 많이 가지 고 있 고 , React 팀 의 rationale 에 스 포카 개발 팀 이 공감 했 기 때문 이 기 도 합니다 . 오픈 소스 일 뿐 만 아니 라 , Github 로 대부분 의 진행 상황 을 트래킹 할 수 있 으며 이슈 트래커 와 IRC , SNS 를 통해 적극 적 인 자세 로 도와 주 는 React 팀 의 자세 도 plus 가 되 었 습니다 . 
 React 로 개발 한다는 것 은 기존 의 웹 페이지 기반 의 개발 을 한다는 것 과 또 다른 이야기 가 될 수 있 습니다 . 하나 의 도구 를 연장 에 추가 한다는 것 이상 의 , 어떤 문화 를 받아들이 는 것 입니다 . Minified file 을 웹 사이트 에 들어가 서 다운 받 고 , AMD 모듈 디펜 던 시 를 일일히 추가 하 던 시절 이 있 었 습니다 ( 기존 앱 은 그렇게 개발 되 고 있 었 습니다 ) . JavaScript 의 가능 성 을 막 알 아 가 던 옛날 과 는 달리 , 이제 는 Node . js compatible API 로 작성 된 성숙 한 에 셋 파이프라인 을 구축 할 수 있 습니다 . 또한 QUnit 같 은 라이브러리 를 이용 해 웹 페이지 를 열 어 테스트 를 돌려 봐야 만 했 던 시절 과 는 달리 커맨드 라인 에서 자세 한 아웃풋 을 보 며 테스트 를 진행할 수 있 습니다 . 또한 가독성 이 훨씬 좋 은 ES 2015 [ ^ 2 ] 언어 명세 를 이용 해 앱 을 작성 할 수 있 습니다 . 
 ' 하지만 이 모든 것 이 너무 새롭 지 않 은가 ? ' 
 그렇게 생각 할 수 도 있 습니다 . 하지만 오래 된 것 이 더 안정 적 인 것 도 아니 며 , 새로운 것 이 더 사용 하 기 어려운 것 도 아닙니다 . React 를 처음 사용 해 시험 프로젝트 를 진행 해 본 결과 , UI 를 만드 는 건 너무나 쉬워 져서 trivial task 가 되 었 습니다 . 
 React 와 Flux 를 만나 다 
 ( 사실 React 에 관한 내용 을 자세히 쓰 자면 너무 길 어 질 것 같 아 , 이 또한 이 글 에서 는 짧 게 쓰 도록 하 겠 습니다 . ) 위 에서 React 팀 의 Rationale 에 대해서 이야기 했 는데 , React 팀 의 여러 가지 문제 의식 중 공감 한 부분 들 은 다음 과 같 습니다 . 
 기존 웹 앱 들 의 Raw DOM manipulation 은 다양 한 문제 를 수반 하 므로 , 추상 화 해서 선언 적 인 UI 상태 명세 를 따르 도록 해야 한다 . 
 웹 앱 UI 작성 의 문제 는 상태 를 관리 하 기 가 너무 어렵 다는 것 으로 , 상태 변화 는 최소 의 범위 에서 이루어지 도록 관리 해야 한다 . 
 기존 의 도도 포인트 앱 은 UI 의 상태 관리 가 굉장히 어려운 문제 중 하나 였 습니다 . 대부분 의 UI 상태 의 기술 이 imperative 했 고 , DOM 조작 을 일일히 해 줌 으로서 상태 변화 를 일일히 관리 해야 했 기 때문 입니다 . 따라서 서버 의 데이터 와 다른 내용 을 보여 주 거나 할 가능 성 을 최소 화 하 기 위해서 사람 들 이 직접 QA 를 열심히 하 는 수 밖 에 없 었 습니다 . React 는 이런 문제 를 해결 하 는 굉장히 좋 은 솔루션 이 라고 할 수 있 습니다 . [ ^ 3 ] 
 React 는 one - way dataflow 를 지향 하 는데 , 이 는 약간 코드 기술 을 장황 하 게 만들 여지 가 있 습니다 . 이 에 대한 해결책 으로 리 액트 팀 은 Flux architecture 를 대안 으로 제시 하 는데 , Flux 는 scheme 일 뿐 솔루션 은 아니 므로 스 포카 개발 팀 은 Reflux 라는 구현 체 를 이용 했 습니다 . Flux 구현 체 중 에서 는 가장 성숙 한 API 와 사용 례 를 가지 고 있 는 라이브러리 입니다 ( Reflux 는 ES 5 로 작성 되 었 으므로 ES 2015 명세 를 적극 적 으로 도입 하 는 React 0 . 13 . 0 ^ 부터 시작 하 시 는 분 이 라면 Flummox 를 고려 해 봐도 좋 을 듯 합니다 ) . 
 위 에서 도 기술 했 지만 , React 를 사용 하 면 자연히 CommonJS / ES 모듈 과 Browserify , Webpack 과 같 은 모듈 번 들러 의 사용 이 권장 되 기 마련 입니다 . 모듈 번 들러 라는 개념 이 생소 한 분 들 을 위해 설명 하 자면 , AMD 와 CommonJS 와 같 은 모듈 명세 들 을 구현 한 모듈 들 을 이해 하 고 ( 의존 성 추적 ) 조작 , 변형 하 거나 하나 또는 이상 의 파일 로 뭉치 는 작업 을 하 는 도구 입니다 . 또한 자바 스크립트 모듈 이 아니 라 이미지 나 blob 등 도 encode 해서 모듈 형태 로 번들 링 해 줄 수 도 있 습니다 . 
 스 포카 개발 팀 에서 는 Browserify 대신 Webpack 을 선택 했 는데 , 기본 적 인 수준 에서 필요 한 기능 ( 예 를 들 자면 , file watch ) 별도 의 모듈 확장 들 을 통해 확장 해야 하 는 Browserify 와 달리 기본 기능 들 이 하나 의 메인 테 이 너 손 으로 잘 만들 어 져 있 기 때문 입니다 . 또한 플러그인 과 확장 들 이 충분히 많이 개발 되 어 있 다고 판단 된 점 , React 메인 테 이 너 가 적극 적 으로 추천 하 는 점 등 도 결정 에 참고 가 되 었 습니다 . 
 모듈 번 들러 의 신뢰도 는 어떨까 요 ? 사실 Webpack 도 굉장히 빠른 속도 로 개발 되 는 도구 로서 때때로 문제 를 일으키 기 도 합니다 . 한 번 은 개발자 의 테스트 를 위한 코드 때문 에 업그레이드 후 CI 가 깨진 적 이 있 었 는데 , 굉장히 빠른 속도 로 대처 해 줘서 좋 은 인상 을 받 은 적 이 있 습니다 . 
 미래 를 내 손안 에 : ES 2015 
 위 에서 계속 ES 2015 이야기 를 했 는데 , 현재 재 작성 된 도도 포인트 의 코드 는 ES 2015 언어 명세 를 부분 적 으로 사용 했 습니다 . 기존 앱 은 ES 5 를 굉장히 부분 적 으로 만 사용 하 고 대부분 의 경우 ES 3 언어 명세 에 맞춰 작성 되 어 있 었 는데 , 사실 도도 포인트 는 최신 의 브라우저 API 를 이용 할 수 있 는 제한 적 인 플랫 폼 ( 태블릿 ) 에서 돌아가 면 되 는 SPA 이 므로 별로 좋 은 선택 은 아니 었 다고 볼 수 있 습니다 . 기존 앱 과 같 은 가독성 문제 를 줄이 기 위해서 새로 작성 하 는 모듈 들 은 class 등 의 ES 2015 언어 명세 를 적극 적 으로 활용 하 기 로 했 습니다 . 
 ES 2015 는 모든 브라우저 에서 사용 할 수 있 는 것 은 아닙니다 . 그렇 기 때문 에 트랜스 파일 을 통해 ES 5 언어 명세 에 맞 는 코드 아웃풋 으로 변환 해 주 는 것 이 트랜스 파일러 인데 , Webpack 을 이용 하 면 loader 를 이용 해 쉽 게 기존 시스템 에 붙일 수 있 습니다 . 기존 에 는 react - tools 를 활용 한 jsx - loader [ ^ 4 ] 를 사용 하 다 Babel , 정확히 는 babel - loader 을 이용 하 고 있 습니다 . ( 스 포카 는 who ' s using Babel 섹션 에 도 등록 되 어 있 습니다 ! ) Babel 은 ES 2015 기술 을 먼저 이용 하 자는 취지 의 트랜스 파일러 플랫 폼 이 긴 하나 , React 의 템플 릿 기술 언어 인 jsx 의 파 서 도 구현 하 고 있 으므로 React 를 사용 하 는 사람 들 은 얼마 든지 이용 할 수 있 습니다 . 
 트랜스 파일러 의 신뢰도 에 대해 의문 을 가진 분 들 도 계실 것 입니다 . 트랜스 파일러 는 experimental 한 기술 인 것 은 분명 하 며 , 아웃풋 또한 언제나 신뢰 할 수 있 는 것 은 아닙니다 . 개인 적 인 견해 는 , 너무 많 은 부분 에 의존 하 면 나중 에 뒷 통수 를 맞 을 가능 성 또한 적 지 않 다고 생각 해서 , Generator 같이 복잡 한 구현 은 피하 는 식 으로 구현 이 비교 적 간단 한 명세 위주 로 작성 하 고 있 습니다 . [ ^ 5 ] 
 Karma 와 Mocha 를 이용 한 고속 테스 팅 
 이전 도도 포인트 앱 은 별도 의 자바 스크립트 유닛 테스트 가 존재 하 지 않 았 습니다 . 유닛 테스트 가 있 었 다면 좋 았 겠 지만 , 비즈니스 로직 과 뷰 로직 이 충분히 잘 분리 되 어 있 지 않 았 기 때문 에 testability 가 많이 떨어지 는 관계 로 유닛 테스트 를 할 수 없 었 고 , 이런 상황 에 대해 참고 할 만 한 예제 도 적 었 습니다 . 하 지만 React 를 도입 하 기 시작 하 면서 테스트 예제 들 을 인터넷 에서 충분히 쉽 게 구할 수 있 었 고 , 테스트 작성 을 도와 주 는 라이브러리 의 선택 가능 범위 가 넓 어 지 면서 고민 에 빠지 게 되 었 습니다 . 
 ' 어떤 것 을 사용 할 것 인가 ? ' 
 첫 후보 로 는 React 팀 에서 추천 하 는 Jest 가 물망 에 올랐 습니다 . 하 지만 Jest 는 다음 과 같 은 약점 이 있 어 선택 받 지 못했 습니다 . 
 JSDOM 을 이용 하 여 DOM API 를 simulate 한다 . 하지만 브라우저 와 작동 이 똑같 지 는 않 다 . 
 브라우저 에서 테스트 를 해 보 는 것 이 아니 라 Node . js ( or equivalent ) 환경 에서 테스트 하 므로 엔진 이 다르 다 . 
 Node . js 환경 이 므로 디버깅 을 하 려면 Node debugger 나 node - inspector 같 은 별도 의 도구 를 이용 해야 한다 . 
 Jasmine 을 사용 한다 . 
 추후 알 수 없 는 브라우저 quirk 에 의한 문제 가 발생 하 는 상황 을 맞이 하 는 것 보다 는 , 브라우저 에서 직접 유닛 테스트 를 돌려보 는 것 이 낫 겠 다는 생각 이 들 어 Karma 를 선택 했 습니다 . 또한 BDD 스타일 의 assertion API 를 가진 Jasmine 보다 는 pytest 처럼 assert ( ) 를 선호 하 는 구성원 들 의 취향 을 생각 해 , Mocha 에 Chai . assert 를 붙여서 사용 하 기 로 했 습니다 . 결과 적 으로 React 컴포넌트 에 대한 테스트 케이스 는 다음 과 같 은 모양 이 됩니다 . [ ^ 6 ] 
 / / test - component . spec . jsx 
 그 외 에 rewire , sinon . js 같 은 테스트 헬퍼 라이브러리 들 도 유용 하 게 사용 하 고 있 습니다 . Sinon 은 기능 이 꽤 많 은데 주로 많이 사용 하 는 기능 은 sinon . spy , sinon . stub , sinon . fakeServer 입니다 . fakeServer 는 약간 사용 이 까다롭 습니다 만 [ ^ 7 ] , 꽤 복잡 한 의존 성 주입 을 하 지 않 는 한 테스트 하 기 힘든 비동기 Ajax 요청 을 하 는 함수 등 을 테스트 할 때 요긴 하 게 사용 합니다 . 
 Always Check Your Radar 
 여기 까지 전체 적 인 새 앱 의 overview 를 해 보 았 습니다 . 새 도도 포인트 앱 은 이제 정말 새로운 기술 로 가득 합니다 . 하지만 누군가 는 그렇게 새로운 기술 들 을 사용 해도 괜찮 을지 질문 할 수 도 있 습니다 . 언제 메인 테 이 너 가 변덕 으로 메인 테 이닝 을 중단 할 지 모르 는 오픈 소스 들 에 의존 하 는 것 도 아슬아슬 한데 , 몇 년 되 지 도 않 은 라이브러리 와 도구 들 을 잔뜩 도입 한다는 것 은 위험 한 선택 처럼 보일 지도 모릅니다 . 
 하 지만 Github 와 Node . js 생태 계 의 hype 활력 을 무시 할 수 는 없 습니다 . 누구 나 만들 기 쉽 고 , 누구 나 자신 의 작업 을 올리 기 쉬운 환경 이 존재 하 는 한 활력 은 계속 될 것 이 라고 봅니다 . 지금 보다 언젠가 더 나 은 라이브러리 가 나올 수 있 고 , 그렇 다면 그걸 쓸 수 도 있 을 것 입니다 . 더 이상 뭔가 가 나올 필요 가 없 을 것 같 아 보이 는 JavaScript MVC 의 세계 에서 도 발전 은 계속 되 고 있 습니다 . [ ^ 8 ] 
 어쨌든 , 문제 가 발생 하 면 어떻게 할까요 ? 
 충분히 경험 을 가진 개발자 여러분 들 은 이미 잘 아실 테 지만 , 문제 를 해결 하 는 방법 은 여러 가지 가 있 습니다 . 그리고 어떤 문제 들 은 굉장히 쉽 게 해결 되 는 반면 , 어떤 문제 는 많 은 시간 과 비용 을 요구 하 기 도 합니다 . 어떤 문제 는 입도 에서 발생 하 기 도 하 며 , 어떤 문제 는 끝단 에서 발생 하 기 도 합니다 . 충분히 테스트 된 것 같 은 제품 도 버그 를 가지 고 있 기 마련 입니다 . 
 예 를 들 자면 현재 도도 포인트 의 유닛 테스트 를 작성 하 는 과정 에서 위 에서 언급 했 던 Rewire 에 관련 된 문제 를 겪 었 는데 , 이것 을 디버깅 하 는 것 은 상당히 어려운 일 이 었 습니다 . 왜냐하면 Webpack 과 Babel 과 Rewire 세 개 의 프로덕트 에 걸친 문제 를 가지 고 있 기 때문 입니다 . 문제 는 한 곳 에서 만 발생 하 지 않 을 수 도 있 으므로 , 전체 인프라 가 어떤 식 으로 작동 하 는지 충분히 알 고 있 어야 ( 혹은 디버깅 을 하 면서 파악 ) 할 필요 가 있 습니다 . 그래야 Duct - tape solution 이 든 long - term solution 이 든 내놓 을 수 있 기 때문 입니다 . :) 
 [ ^ 1 ] : 저 는 발 만 담구 긴 했 지만 React 한국어 문서 번역 도 존재 합니다 . 
 [ ^ 2 ] : 보통 EcmaScript , 소위 사람 들 이 자바 스크립트 라고 부르 는 구현 체 의 다음 버 젼 언어 명세 는 EcmaScript 6 , 즉 ES 6 으로 지칭 되 어 왔 습니다 만 ES 7 등 다음 버 젼 의 명세 작업 에 TC 39 가 착수 하 면서 ES 2015 라고 부르 자는 커뮤니티 의 합의 가 있 었 습니다 . 이 글 에서 는 일단 " ECMA - 262 , 6 th Edition " 과 기타 미래 의 언어 명세 와 제안 을 ES 2015 로 지칭 합니다 . 
 [ ^ 3 ] : 해외 에 는 좋 은 튜토리얼 과 블로그 글 이 많이 있 지만 국내 에 는 거의 없 는 편 인데 , ditto 님 의 jQuery to React 의 일독 을 권해 봅니다 . 
 [ ^ 4 ] : 최근 에 는 react - tools 가 deprecate 된 관계 로 jstransform 을 사용 하 긴 합니다 . 
 [ ^ 5 ] : kangax 의 EcmaScript 지원 차트 를 보 면 Babel 은 굉장히 많 은 언어 명세 를 지원 하 는데 , 부분 적 으로 는 core - js 폴 리필 을 이용 하 는 것 까지 포함 합니다 . 유닛 테스트 의 커버리지 와 지원 을 보 면 신뢰 할 수 있 는 프로젝트 지만 , 엄밀히 말 하 자면 폴 리필 의 정상 작동 여부 는 브라우저 런타임 에서 만 알 수 있 으므로 조심 해서 사용 하 는 것 이 좋 다고 생각 합니다 . 
 [ ^ 6 ] : Arrow Function 은 lexical binding 을 위한 것 이 지 짧 은 함수 표기 를 위한 것 이 아니 라는 주장 도 있 으며 공감 합니다 만 , 예시 를 위해 사용 해 봤 습니다 . 
 [ ^ 7 ] : 비동기 함수 사용 의 어려운 부분 이 라고 하 는 게 더 맞 을 지도 모르 겠 습니다 만 , 어쨌든 fakeServer 인 스턴스 가 이해 할 수 있 는 타임 프레임 에 예측 한 테스트 요청 이 가 지 않 았 을 경우 에러 를 내 는 것 이 아니 라 404 를 반환 해서 약간 어리둥절 하 게 하 는 behavior 가 있 습니다 . 
 [ ^ 8 ] : Ember . js 에 React 에 영향 을 받 은 Virtual DOM 구현 체인 Glimmer 렌더링 엔진 이 들어간 것 이 하나 의 예 라고 볼 수 있 습니다 .