oris9
[TypeScript] 자바스크립트에서 타입스크립트로 마이그레이션하기 (빌드 업데이트) ! 본문
자바스크립트로 작성한 리액트 프로젝트를 타입스크립트로 마이그레이션 할 일이 생겼다.
기존 프로젝트는 CRA로 빌드되어 있었기에 빌드도구도 Vite로 업데이트 하기로 결정했다.
Vite를 선택한 이유 ,
우선 CRA에 비해 최근까지 계속 업데이트가 진행되고있고, CRA가 지속적으로 업데이트를 진행하지 않으면서 리액트 자체에서도 CRA가 아닌 Vite를 이용해서 프로젝트를 시작할 것을 권하고 있다고 알고 있다.
이게 지금 나에게는 가장 큰 이유였고, 이를 계기로 자세히 찾아보니
CRA는 webpack을 이용해 모든 코드를 번들로 만드는데, vite는 개발모드에서 ES모듈을 이용해 브라우저에서 직접 모듈을 로드한다고한다. 따라서 개발서버 시작시간이 더 빠르다 (vite는 요청시에 동적으로 모듈을 변환, CRA는 서버시작시 한번에 변환) 또한 Rollup을 이용해(Rollup은 tree-shaking을 활용하기때문에 빌드결과물이 더 가볍다) 빌드하기때문에 빌드속도가 CRA에 비해 빠르다. 그리고 vite가 추가적으로 기본 설정을 해주는게 많기 때문에 조금더 편리하다고 한다!
+ Vite는 개발 과정에서 빠른 HMR을 제공한다 (Hot Module Replacement로, 실시간으로 코드를 관찰하면서 변경사항이 생기면 해당 모듈만을 즉시 업데이트하고 적용하는 기능을 말하며 새로고침없이 코드 변경사항 확인이 가능해 개발 효율성을 향상시켜준다)
Vite와 CRA는
1. package.json의 scripts가 다르다
2. index.html 위치가 다르다
3. tsconfig.json 설정이 다르고 Vite에는 tsconfig.node.json 추가 설정 파일이 있다
4. Vite에는 vite(vite.config.ts), eslint(.eslintrc.cjs) 설정 파일이 기본으로 있다
5. index.ts가 아닌 main.ts 이라는 이름을 사용한다
6. 등등.. 세부설정이 다르거나 폴더구조가 다르거나 하는 점이 있다
아래와 같은 순서로 진행하면 마이그레이션을 할 수 있다.
(대부분 https://onlydev.tistory.com/185 을 참고해서 적었다)
0. .jsx 파일을 .tsx로 변경
`find . -type f -name "*.jsx" -exec bash -c 'mv "$0" "${0%.jsx}.tsx"' {} \;`
1. Vite 설치
`npm install vite @vitejs/plugin-react --save-dev`
2. CRA 의존성 제거
`npm uninstall react-scripts`
3. package.json scripts 변경
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
}
4. vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
host: 'localhost',
port: 3000, // 포트 설정. 기본값은 5173
open: true, // 서버 시작 시 브라우저 자동 열기
},
build: {
outDir: 'build',
},
});
5-1. tsconfig.node.json
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true
},
"include": ["vite.config.ts"]
}
5-2. tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
6. react-app-env.d.ts 제거 vite-env.d.ts 생성
기본적인 모듈 타입 설정해주는 파일이다
7. index.html 옮기기 %PUBLIC_URL% 제거
%PUBLIC_URL% 을 사용할 필요가 없기 때문에 지워준다 (넣으면 오류가 난다)
8. main.tsx root 타입 오류 해결
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { ThemeProvider } from "styled-components";
import theme from "./styles/theme";
import GlobalStyle from "./styles/global";
const rootElement = document.getElementById("root");
if (!rootElement) throw new Error("Failed to find the root element");
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<ThemeProvider theme={theme}>
<App />
<GlobalStyle />
</ThemeProvider>
</React.StrictMode>
);