서론
리펙토링을 본격적으로 시작하기 전에 오류를 방지하고 유지보수가 쉽도록 기존 React 코드를 타입스크립트로 마이그레이션하기로 했습니다. 이전에 종종 시도하고자 했을 때 어디서부터 손을 대야할지 막막했는데 이펙티브 타입스크립트를 참고하여 시작해 봤습니다.
그럼... 시작합니다!
과정
allowJS 같이 사용하기
이펙티브 타입스크립트에서 권장하는 방식에서는 모던 자바스크립트로 작성하기, @ts-check나 JSDoc 이야기가 앞서 있었지만 굳이 그 단계를 하지 않아도 될 것 같기도 하고 시간이 더 걸릴 것 같아서 생략하고 allowJS 같이 사용하기로 넘어습니다.
allowJS를 활성화하면 JavaScript 파일과 TypeScript 파일이 공존 할 수 있어 마익으레이션을 좀 더 쉽게 할 수 있었습니다.
내 tsconfig.json 설정
{ "compilerOptions": { "jsx": "react", "target": "es5", "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": false, "allowJs": true, "skipLibCheck": true, "outDir": "./dist" }}이 상태로 마이그레이션을 진행하였습니다.
의존성 관계에 따라 모듈단위로 전환하기
타입스크립트로 마이그레이션하려는 생각은 전부터 하기도 했고 간단해보이는 컴포넌트부터 시작하려고 하니... 막막해서 어떻게 해야할지 모르겠었는데 이펙티브 타입스크립트에서 의존성 관계에 따라 모듈단위로 전환하라는 이야기와 함께 "madge"라는 도구를 이용해 의존성 관계도를 만들 수 있었는데 이게 막막했던 나에겐 아주 도움이 되었습니다. 완전 추천드려요!

이 당시에 파일을 나누는 기준이 없었어서 그런지 보는게 심적으로도 힘들고 여러모로 힘드네요...
어쨌든 이 의존성관계도에서 오른쪽에 있는 파일(덜 의존적인 파일)들부터 마이그레이션 해나갔습니다. 이 프로젝트는 결합도가 높아서 간혹 한 파일을 고칠 때 연관된 파일들이 조금 있었던 것 같지만 무사히 타입스크립트로 마이그레이션해나갔습니다.
초기에는 명시적으로 타입을 굳이 넣지 않은 부분이 많아서 걱정이 됐는데 왜냐하면 뒤에 noImplicitAny 를 활성화 시킬 것이기 때문이었습니다.
noImplicitAny 활성화
noImplicitAny?

그럼... 활성화 해봅니다!

많은 에러가 나타났습니다...
다시 한번 의존성 관계도를 확인하며 명시적으로 타입을 기입하여 에러를 해결해 나갑니다. 많은 에러에 잠시 혼미해졌지만 타입 안정성이 적용되지 않았던 부분이 시각적으로 드러나서 좋았습니다.
strict 모드 활성화
strict 활성화는 어느정도 프로젝트가 정리가 되면 하기로 했습니다. 마이그레이션하면서 불필요한 props를 넘기는 것 한 컴포넌트가 쓰일 때 마다 받는 props가 너무 달라서 이걸 좀 정리를 먼저 해야할 것 같습니다.
결론
타입스크립트로 마이그레이션 하는 과정에서 타입스크립트가 왜 필요한지에 대한 체감이 확 됐던 것 같다. 나는 타입스크립트로 마이그레이션 하기 이전에 너무 파일을 쓸데 없이 분리해둬서 통합하는 리펙토링을 했는데... 이 과정에서 무슨 일이 있었던 것인지 아니면 애초에 잘못 작성했던 것인지
불필요한 props 를 잔뜩 넘기고 있었다. 솔직히 아직 무서워서 주석처리 해두고 완벽히 지우진 못했지만 이 부분이 꽤 된다는 점에서 놀랐다.
그리고 확실히 type을 지정해줌으로써 내가 예상하지 않는 방향으로 작동하는 것을 예방할 수 있겠구나라고 많이 느꼈다.
책에서도 그랬는데 마이그레이션을 하다보면 고치고 싶은 부분이 아주 많아질거라고 그랬는데 정말이었다. 하지만 꾹 참고 우선 마이그레이션부터 하는게 우선이라는 말에 꾹 참고 마이그레이션 해나갔습니다.
마이그레이션 하면서 내가 느낀 문제점
- 일관되지 않는 네이밍, props 전달 방식
- 불필요한 코드 및 불필요한 props 전달
- props drilling과 높은 결합도
- 폴더 구조 변경 시 벌어진 버그들
- 유지보수하기 힘든 프로젝트 폴더 구조
- 함수형 프로그래밍 원칙을 지키지 않은 코드들
후에는 이 부분을 고쳐나가는 과정을 적어보고자 합니다!