언어/TypeScript

JS 프로젝트 마이그레이션하기

calendar2 2024. 11. 1. 00:02

타입스크립트에 대한 강의도 끝났고 알아야 할 대부분의 문법들을 배웠다. 역시 강의 구성이 굉장히 좋다고 느꼈는데 단순히 타입스크립트를 적용하기보다는 JS에서 TS로 마이그레이션하는 과정을 강의에 넣은 것이 꽤 놀랍게 느껴졌다.

어쨌든 제 블로그를 보신 분들을 위해 저도 마이그레이션 과정을 정리하려 한다.

 

이미 많은 프로젝트가 TS로 구축되어 있겠지만 아직 FE 웹 개발을 배운 지 얼마 안된 분들이나 혹은 굉장히 레거시한 환경에서 업무하신 분들의 경우 JS로 구축된 프로젝트를 TS로 변환해야 하는 경우가 있을 수 있다. 또는 프로젝트 생성을 JS로 잘못 진행했다든가. 하여튼 차근차근 따라가보자.

1. 구축 환경

구축 환경은 CRA + JS로 프로젝트를 생성하려 한다. CRA 의 업데이트가 중단되었고 Vite의 선호도가 많이 올라갔지만 Vite의 경우 프로젝트 생성 시 JS와 TS를 선택하게끔 되어있어 개발자들이 착각할 가능성이 매우 낮다. 또한, Vite의 경우 CRA 환경보다 package나 config가 더 디테일하게 잡혀있어 기본적인 원리를 살펴보기에는 CRA로 보여주는 게 더 나아보였다.

 

그러면 CRA 환경으로 프로젝트를 생성하는 cli 명령어를 터미널 창에 입력해주자.

npx create-react-app .

 

그러면 다음과 같이 프로젝트가 생성된다.

CRA 프로젝트

 

저기서 마이그레이션에 다소 불필요한 파일인 App.test.js / logo.svg / reportWebVitals.js / setupTests.js 4개의 파일을 삭제하겠다. 여러분들의 개발환경에서는 필요할수도 있지만 제가 지금 마이그레이션 과정을 보여줄 때는 괜히 수정할 파일만 늘어나기에 이 부분은 양해바란다.

그럼 4개 파일을 삭제하면 프로젝트가 다음 구조로 되어있을 것이다.

CRA 프로젝트 2

 

파일 일부를 삭제했으니 index.js와 App.js도 수정을 해야한다. 우선, index.js는 reportWebVitals가 있는 코드를 삭제해서 다음 사진처럼 만들어준다.

index.js

 

그리고 App.js는 모든 내용과 logo에 해당하는 코드를 삭제해서 다음과 같이 만들어준다.

App.js

2. 타입 선언 패키지 설치하기

구축환경이 마무리되었다면 다음으로 타입 선언 패키지를 설치해야 한다. package.json을 살펴보자.

package.json

 

CRA로 프로젝트를 생성했다면 아마 devDependencies가 없고 dependencies가 위 사진과 같을 것이다.

타입 선언 패키지란 @types가 붙은 패키지를 말한다. 이 부분에 대해서는 아래 좀 더 자세히 정리할 예정이다.

일단 다음 명령어를 이용해 4개의 패키지를 설치하자.

npm i @types/node @types/react @types/react-dom @types/jest

3. TS 컴파일러 옵션 설정하기

이제 TS 문법을 JS 문법으로 컴파일하기 위한 컴파일러 옵션을 추가해야 한다.

이미 잘 아시겠지만 root 디렉토리에 tsconfig.json 파일을 생성하고 다음과 같이 기본적인 몇 가지 옵션만 설정해주자.

tsconfig.json 1

 

tsconfig.json을 설정하면 아마도 필자와 같은 오류가 발생할 것이다.

이는 TS 컴파일러가 JS 파일을 컴파일하지 못 해서 발생하는 에러로 다음과 같이 옵션을 하나 더 추가해줘야 한다.

tsconfig.json 2

 

그러면 에러 메시지가 바뀌어 있을텐데 이번 에러는 TS 컴파일러가 .js 확장자명 파일에서는 JSX 문법을 해석하지 못 하기에 발생하는 에러이다.

따라서, JSX 문법을 사용하고 있는 index.js와 App.js 파일을 .jsx 파일로 변경해줘야 한다.

깔끔한 상태 1

 

JSX 문법을 사용하는 파일의 확장자명을 .jsx로 변경하고 TS 컴파일러가 js 파일도 컴파일 가능하게 allowJs 옵션을 켜줌으로써 에러를 모두 해결했다.

하지만 우리는 JS를 TS로 마이그레이션하는 것이 목적이므로 .jsx 파일을 .tsx 파일로 변경해주어야 한다.

4. JS 파일 TS 파일로 마이그레이션 하기

우선, index.jsx 파일 하나만 index.tsx 파일로 변경해보자.

아마도 아래와 같이 파일에 온갖 에러 메시지가 나타날 것이다.

index.tsx

 

바로 이것이 아까 위에서 일부 파일을 삭제한 이유이다. 어쩔 수 없이 JS 문법을 TS 문법으로 마이그레이션하기 위해서는 파일 하나하나 수정해주어야 하는데, 파일이 많다면 그만큼 노동력이 많이 필요하다.

그러므로 이미 프로젝트 규모가 꽤 크게 잡혀있다면 마이그레이션보다는 새롭게 TS로 만드는 것을 추천한다.

 

아무튼, index.tsx부터 에러를 하나씩 해결해보자.

우선, 가장 위에 있는 import React 구문 에러를 살펴보면 모듈은 'esModuleInterop' 플래그를 ~~~ 이라고 메시지가 있다.

그리고 import ReactDOM 구문 에러의 경우 모듈 ~~~~에는 기본 내보내기가 없습니다. 라는 메시지가 있다.

이 에러들은 컴파일 옵션에서 esModuleInterop 옵션을 킴으로써 해결할 수 있다.

tsconfig.json에 다음과 같이 옵션을 추가해주자.

esModule 1

 

그러면 사진과 같이 에러가 해결된 것을 확인할 수 있다.

 

다음으로, root.render 아래에 동일한 에러 두 개가 발생했다. '--jsx' 플래그를 제공하지 ~~~ 라는 메시지인데 이는 TS 컴파일러가 JSX 문법을 해석하지 못해 발생하는 에러이다. 이 또한 옵션을 추가하여 해결할 수 있다.

tsconfig.json에 jsx 옵션을 다음과 같이 추가해주자.

jsx

 

이제 마지막으로 document 구문에 에러가 하나 남아있는데 해당 에러 메시지가 다음과 같이 되어있을 것이다.

'HTMLElement | null' 혀식의 인수는 ~~~ / 'null' 형식은 'Container' 형식에 ~~~

이는 document.getElementById("root") 값이 타입 검사로 HTMLElement 타입과 null 타입을 가질 수 있어 발생하는 경고문이다.

하지만, 프로젝트에서 해당 값이 null이 발생할 일이 없으므로 타입 단언을 통해 해결해주면 된다.

타입 단언

 

이렇게 document 구문에 as HTMLElement 단언을 해줌으로써 index.tsx로의 마이그레이션이 완료되었다.

이 과정을 App.jsx도 진행해주면 되는데, App.jsx의 대부분의 내용을 삭제했기에 아마 tsx로 파일을 변경해도 문제가 발생하지 않을 것이다.

가끔 tsx로 변경하면 tsconfig.json에서 App.jsx 파일을 찾을 수 없다고 나오는 경우가 있는데 이럴 경우 vscode에서 Ctrl + Shift + P를 눌러 TypeScript: TS 서버 다시 시작 이라는 명령을 실행해주면 해결된다.

타입 선언 패키지

위에 2번 단계에서 설치한 타입 선언 패키지에 대해 좀 더 자세히 설명하겠다. 프로젝트를 진행하다보면 굉장히 많은 외부 라이브러리를 설치하는 경우가 있다. 그런데 대부분의 라이브러리들은 업데이트가 잘 되거나 혹은 타입스크립트 이후에 생성되면서 타입스크립트 환경에서도 잘 적용할 수 있는데, 일부 라이브러리는 JS 문법으로만 작성되어 TS 환경에서 에러가 발생하는 경우가 종종 있다.

대표적으로 다음 라이브러리가 있다.

lodash

 

lodash는 객체와 배열 사용에 도움을 준다고는 하는데, 필자는 사용해보지 않아 자세히 모르겠다...

어쨌건 다운로드 수도 굉장히 많고 꽤 유명한 라이브러리인 것 같긴하다.

사진을 보면 lodash 글자 오른쪽에 DT라는 마크를 볼 수 있는데 이는 lodash 라이브러리가 TS 문법을 지원하지 않는다는 의미이다.

따라서, lodash라는 라이브러리를 TS 환경에서 사용하고 싶다면 lodash의 타입 선언 패키지를 추가로 설치해야 한다.

아래 lodash 패키지의 사이트를 공유하겠다.

lodash - npm

 

lodash

Lodash modular utilities.. Latest version: 4.17.21, last published: 4 years ago. Start using lodash in your project by running `npm i lodash`. There are 195659 other projects in the npm registry using lodash.

www.npmjs.com

 

사이트를 들어가서 lodash 제목 옆에 DT 마크를 클릭해보자.

그러면 다음과 같이 lodash의 타입 선언 패키지로 이동할 수 있다.

lodash 2

 

마크를 다시 살펴보면 이번에는 TS라고 적혀있는 것을 확인할 수 있다. 이는 해당 라이브러리가 TS 문법을 지원한다는 의미이다. 그리고 해당 패키지 이름을 살펴보면 @types로 시작되는 것을 볼 수 있다.

@types라는 용어가 lodash 라이브러리의 타입 정보를 제공한다는 의미를 갖는다는 것을 알 수 있고, 앞서 설치한 @types/node, @types/react 등등 역시 같은 의미를 같은 패키지이다.

 

마지막으로 직접 설치해서 타입 선언 패키지가 있고 없고가 어떤 상황을 발생하는지 확인해보자.

우선, lodash를 설치하기 위해 다음 명령어를 입력한다.

npm i lodash

 

설치하고 아무 파일에서 lodash를 import하면 다음과 같이 에러가 발생하는 것을 확인할 수 있다.

lodash 3

 

그러면 이제 lodash의 타입 선언 패키지를 추가해보자.

npm i @types/lodash

 

사진에서 보이는 것처럼 lodash의 타입 선언 패키지 추가와 함께 해당 에러가 사라지는 것을 확인할 수 있다.

lodash 4

 

TS 환경에서의 작업은 생각보다 많은 에러를 마주칠텐데 이 글이 그런 상황에서 조금이나마 도움이 되길 바란다.

그리고 필자의 정리와 설명보다 강의가 정보 전달이 비교가 안 될 정도로 좋으니 타입스크립트를 제대로 공부하고자 하는 사람들에게는 해당 강의를 추천드린다.

참고자료

한 입 크기로 잘라먹는 타입스크립트(TypeScript)

 

한 입 크기로 잘라먹는 타입스크립트(TypeScript) 강의 | 이정환 Winterlood - 인프런

이정환 Winterlood | 문법을 넘어 동작 원리와 개념 이해까지 배워도 배워도 헷갈리는 타입스크립트 이제 제대로 배워보세요! 여러분을 타입스크립트 마법사🧙🏻‍♀️로 만들어드립니다., 프론

www.inflearn.com

 

'언어 > TypeScript' 카테고리의 다른 글

유틸리티 타입 2  (1) 2024.10.29
유틸리티 타입 1  (0) 2024.10.29
infer - 타입 추론하기  (1) 2024.10.17
분산적인 조건부 타입  (0) 2024.10.16
조건부 타입  (1) 2024.10.15