nextjs는 typescript가 무섭대요
서론
어느 한 겨울의 이야기 입니다. 그는 nextjs와 함께 즐겁게 코드를 짜고 있었습니다. 어느 때와 같이 리덕스 스토어에 사용되는 union type을 수정하고 저장을 한 다음 정상적으로 컴파일된 걸 확인합니다.
그 순간 그의 등줄기를 타고 소름이 돋습니다. 무언가 이상함을 느낍니다.
그는 스크롤을 내립니다. 드르륵- 드드륵- 한 오브젝트가 보입니다. 그는 떨리는 눈으로 오브젝트의 타입을 봤습니다. mapped type, 그는 오래 전에 어느 타입을 이 오브젝트의 키로 사용할 수 있게 만든겁니다. 그렇습니다. 그가 방금 수정한 타입이었습니다. 그는 이윽고 오브젝트를 선명하게 가로지르는 구불구불한 빨간색 선을 보게 됩니다.
그는 키보드에 툭 떨어진 식은땀을 볼 틈도 없이 모니터에 온 신경을 집중합니다. 이게 무슨, 타입 에러가 있다면.. 대체 어떻게 컴파일이 된거지? 으아악!
...... 이라는 괴담을 아시나요?
대부분 타입을 등한시한 타입스크립트의 저주라고 웃고 넘기지만 사실 더 큰 비밀이 숨겨져 있습니다.
사실 nextjs는.. 타입 체킹을 안합니다!!!! 으아아악!
dev와 타입 체킹
nextjs가 타입 체킹을 지원하지 않는다니 이게 무슨 소리인가요, 빌드에서 타입 에러가 뜨는 걸 이 두 눈으로 똑똑히 봤는데!
여러분의 말이 맞습니다. 빌드 때 타입 에러가 잡힙니다. 그렇다면 dev는 어떨까요? 위의 오싹오싹한 괴담과 같은 상황을 만들고 저장을 해보겠습니다.
new
의 경우를 입력하지 않았습니다. 여러분은 someObject
를 가로지르는 빨간 선을 보게 될 겁니다. 타입 에러가 발생했습니다!
터미널에는 어떤 일이 일어났을까요?
우리의 dev는 그런 건 상관하지 않습니다. 미동없이 고요한 터미널을 볼 수 있을 겁니다.
맞습니다. dev는 타입 체킹을 하지 않습니다. 이럴수가...
nextjs는 fast refresh가 필요해요
모든 일은 nextjs 9.4에서 fast refresh가 정식으로 적용되며 일어났습니다. 기존의 핫 리로딩 방식은 변경이 생길 때마다 앱 전체를 리로드 했습니다. 이런 방식은 느리고 에러 해결에도 좋지 않았습니다. 그걸 극복하기 위해 등장한 것이 fast refresh
입니다.
좋은 변화였습니다. 수정한 코드로 인한 변화를 즉각적으로 확인할 수 있음과 더불어 더 정확하게 런타임 에러를 확인할 수 있게 되었습니다. 그런데요, 문제가 발생합니다. 타입 체킹은 너무 시간이 오래 걸렸던 겁니다. 최대한 빠른 리로딩 경험을 제공하고 싶었던 nextjs는 타입 체킹을 빼 버립니다!
이를 되돌리는 옵션도 제공하지 않았습니다. nextjs 개발자 분들의 의지는 확고했던 겁니다.
우리는 타입 체킹이 필요해요
그 확고함과는 달리 항상 typescript의 든든함에 기대고 있던 저는 수정한 즉시 진행되는 타입 체킹이 그리웠습니다. 하지만 nextjs의 버전이 13이 될 때까지도 타입 체킹 지원은 까마득히 멀기만 합니다. 방법을 찾아야만 합니다. 타입 체킹을 다시 불러낼 방법을요. 다행히 저와 같은 생각을 가지고 있는 분들이 꽤 있었습니다.
여러분들에게 두가지 방법을 소개합니다.
vscode
typescript.tsserver.experimental.enableProjectDiagnostics
vscode는 자체적으로 타입 체킹을 지원하지만 열려있는 파일만 가능합니다. 그렇다면 모든 파일을 체크하게 만든다면 어떨까요?
typescript.tsserver.experimental.enableProjectDiagnostics
가 가능하게 합니다. 프로젝트의 파일들을 열지 않아도 발생하는 에러를 확인할 수 있게 만들어 줍니다.
다만 이 기능은 실험적입니다. 에러들이 발생할 가능성이 높으며 개선될 여지는 낮습니다.
tasks
vscode의 tasks
를 사용하는 방법도 있습니다.
tasks
는 실행 중 발생한 에러를 Problems
view에 띄워줄 수 있습니다. 이를 통해 tsc
를 실행하면 어떻게 될까요?
tsc
로 변경된 파일들을 감시하고 발생한 오류를 Problems
view에 표시되게 만들 수 있습니다.
terminal
잠시만요, 타입 체킹 후 발생한 에러를 vscode를 통해 확인하는 게 마음에 들지 않는 경우는요? 수상할 정도로 터미널을 사랑하는 분들은 오직 터미널에서 모든 걸 확인하고 처리하고 싶을 겁니다.
그렇다면 이 방법을 사용하세요.
concurrently
패키지는 명령어의 동시 실행과 함께 [TS]
와 같은 접두사로 어떤 명령어에서 나온 로그인지 구별하기 쉽게 만들어 줍니다. 이를 사용해 nextjs dev 서버와 tsc를 동시에 실행시켜 로그를 확인할 수 있습니다.
TMI
tsconfig.json을 확인하세요
tsconfig.json
가 다음처럼 설정되어 있는지 확인하세요.
noEmit
이true
가 되어야 출력 파일을 만들지 않습니다.tsc
를 타입 체킹의 용도로만 사용할 것이기 때문입니다incremental
이true
여야 incremental compilation이 됩니다. 속도가 더 빠릅니다
타입 에러 발생 시 중단은 안됩니다
사실 타입 에러가 발생했을 때 앱의 실행을 막고 싶었습니다. 무심코 지나치는 일 없이 확실히 해결할 수 있게요!
안타깝게도 그런 방법은 찾을 수 없었습니다. nextjs 자체에서 지원해야 될텐데 현재로서는 가망이 없다고 생각이 듭니다. 타입 체킹 자체가 굉장히x3 빨라지는 날이 온다면 가능할 수도 있지만요! 그 날이 오기까지는 마음 한 켠에 담아두는 걸로 했습니다. 흑흑...
도움이 되었나요?
되었다고요? 다행입니다!!
날씨가 아직도 꽤 춥네요. 오늘도 따뜻하고 즐거운 개발이 되셨음 합니다.
Reference
tasks
[Tasks in Visual Studio Code](https://code.visualstudio.com/Docs/editor/tasks#_examples-of-tasks-in-action)
[Visual Studio Code Tasks Appendix](https://code.visualstudio.com/docs/editor/tasks-appendix)
[Blog - Next.js 9.4 | Next.js](https://nextjs.org/blog/next-9-4)
[TypeScript: Documentation - tsc CLI Options](https://www.typescriptlang.org/ko/docs/handbook/compiler-options.html)
[enableProjectDiagnostics problem · Issue #168410 · microsoft/vscode](https://github.com/microsoft/vscode/issues/168410)
[Feature Request: Show all errors and warnings in project for all JavaScript and TypeScript files, not just opened ones · Issue #13953 · microsoft/vscode](https://github.com/microsoft/vscode/issues/13953)
[Typescript \`next dev\` error reporting · Discussion #33634 · vercel/next.js](https://github.com/vercel/next.js/discussions/33634)
댓글을 작성해보세요.