React + Typescript 세팅하기(Webpack)
최근에 React + TypeScript 를 배우고 있는데, 생각만큼 잘 되지 않는 부분도 있고 각각의 의미가 다 있는 만큼 한번 정리할 필요가 있어서 글을 쓴다.
React + TypeScript 를 세팅하는 방법에는 두가지가 있다.
- Webpack 을 이용하기
- React App 생성하기
여기서는 Webpack 을 이용해 React + TypeScript 세팅을 해볼 것이다.
Webpack 프로젝트 생성
webpack 은 프로젝트 생성 툴이 아니다. webpack 은 React + TypeScript 와 아무런 상관이 없다. 단지 React + TypeScript 생성을 이용할 수 있는 하나의 방법이다.
webpack 은 CSS, JavaScript 등을 모두 생성해 준다. 특징이 있다면 JavaScript 의 경우에는 하나의 파일로 만들어 준다. 여러가지 파일을 만드는 것이 아니라 오직 한개의 파일로 모두 작성된다.
package.json 파일 생성
nodejs 에 프로젝트 정보파일인 package.json 파일을 생성해 준다. 프로젝트 이름, 의존성, npm 스크립트등을 기재하면 할 수 있지만 일단 최소한의 정보만 입력한다.
1 2 3 4 5 |
{ "name": "myapp", "version": "0.1.0", "description": "My React and TypeScript app" } |
nodejs 의 의존성 패키지들은 npm 명령어로 설치하면 자동으로 package.json 파일에 기재된다.
web page 추가
src 폴더를 생성하고 그 안에 index.html 파일을 작성한다.
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>My app</title> </head> <body> <div id="root"></div> </body> </html> |
React 가 실행되면서 속성값인 id=”root” 의 div 에 내용을 추가해 준다.
TypeScript 추가
npm 명령어를 이용해서 TypeScript 를 추가해 준다. 한가지 주의해야 할 것은 결과물은 어짜피 JavaScript 로 나오기 때문에 개발할때만 TypeScript 만 필요하게 된다. 따라서 npm 을 이용해 설치할 때에는 개발목적으로 설치 하는게 좋다. ‘–save-dev’ 옵션을 사용하면 개발목적으로 설치할 수 있다.
1 |
npm install --save-dev typescript |
위 명령어는 다음과 같이 축약 할 수 있다.
1 |
npm i -D typescript |
설치를 하고 나면 다음과 같이 package.json 파일에 TypeScript 의존성이 추가 된다.
1 2 3 4 5 6 7 8 |
{ "name": "myapp", "version": "0.1.0", "description": "My React and TypeScript app", "devDependencies": { "typescript": "^5.7.3" } } |
‘devDependencies’ 는 개발목적의 의존성을 말하며 그 안에 TypeScript 가 있다. 설치된 버전은 최신버전으인데, 설치할때에 버전을 따로 지정해 주지 않으면 최신버전으로 설치가 된다.
이제 TypeScript 를 위한 설정 파일을 root 폴더에 ‘tsconfig.json’ 이름으로 생성해 준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "compilerOptions": { "noEmit": true, "lib": [ "DOM", "DOM.Iterable", "ESNext" ], "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "jsx": "react", "forceConsistentCasingInFileNames": true, "strict": true }, "include": ["src"], "exclude": ["node_modules","dist"] } |
몇가지 설정은 다음과 같다.
- ‘noEmit’ 를 true 로 하게되면 TypeScript 컴파일러가 아무것도 트랜스파일(trnaspilation)을 하지 않는다.
- ‘allowSyntheticDefaultImports’ 와 ‘esModuleInterop’ 를 true 로 하게 되면 React 를 디폴트 임포트해준다.
- ‘forceConsistentCasingInFileNames’를 true로 설정하면 임포트문에서 참조된 파일 이름의 케이싱이 일관되게 유지되는지 확인할 수 있는 타입 체킹 프로세스가 활성화 된다.
React 추가
이제 React 와 TypeScript 를 설치 한다.
1 |
npm install react react-dom |
‘react’ 는 react 에 코어 라이브러리다. 모든 React 관련 라이브리가 사용한다. ‘react-dom’ 은 웹 앱(web app) 을 빌드하는데 사용되는 라이브러리다.
React 는 TypeScript 를 포함하지 않는다. 따라서 별도로 설치를 해줘야 하는데, 다음과 같이 해준다.
1 |
npm install --save-dev @types/react @types/react-dom |
‘–save-dev’ 옵션을 줘서 개발목적으로만 설치를 한다. 빌드하고 나온 결과물은 Javascript 로 되기 때문에 TypeScript 는 필요가 없기 때문에 개발목적으로만 설치를 하면 된다.
src 폴더에 루트(root) 컴포넌트라고 하는 ‘index.tsx’ 파일을 작성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; const root = createRoot( document.getElementById('root') as HTMLElement ); function App() { return <h1>My Super React and TypeScript App!</h1>; } root.render( <StrictMode> <App /> </StrictMode> ); |
위 코드는 id 가 ‘root’ 인 DOM 에 React 앱을 주입시켜 준다. 확장자가 js 가 아닌 tsx 로 한 이유는 Babel이 트랜스컴파일을 위해 JSX 를 포함하는 TypeScript 파일을 자동으로 찾도록 하고 TypScript 가 타입 체크 프로세스를 진행할 수 있도록 한다. 확장자가 ts 인 경우에는 TypeScript 코드인데 JSX 를 포함할 수 없다.
‘document.getElementById(‘root’) as HTMLElement’ 에서 ‘as HTMLElement’ 를 type assertion 이라고 하는데, TypeScript 를 이용하기 때문에 어떤 타입인지를 명시를 해줘야 한다. ‘document.getElementById’ 은 ‘as HTMLElement’ 거나 null 타입을 가질 수 있는데, ‘as HTMLElement’ 타입을 가지라고 명시하고 있다.
Babel 추가
Babel 은 React 와 TypeScript 코드를 JavaScript 코드로 트랜스파일(transpile, 혹은 transcompile)을 해준다. 역시 결과물은 JavaScript 만 있으면 되는거라서 개발목적으로만 설치하면 된다.
1 |
npm install --save-dev @babel/core |
또, 최신의 JavaScript 기능을 사용하도록 하기 뒤해서 @babel/preset-env 라고 하는 Babel 플러그인을 설치해 준다.
1 |
npm i -D @babel/preset-env |
또, React 를 JavaScript 로 변환하기 위해 @babel/preset-react 라고 하는 Babel 플러그인을 설치해 준다.
1 |
npm i -D @babel/preset-react |
똑같이 TypeScript 를 JavaScript 로 변환하기 위해 @babel/preset-typescript 라고 하는 Babel 플러그인을 설치해 준다.
1 |
npm i -D @babel/preset-typescript |
마지막으로 JavaScript 에 async 와 await 를 사용할 수 있도록 다음 두개의 플러그인을 설치해 준다.
1 |
npm i -D @babel/plugin-transform-runtime @babel/runtime |
Babel 관련해 설치는 마무리 되었다. 이제 .babelrc.json 설정 파일을 다음과 같이 작성해 준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ], "plugins": [ [ "@babel/plugin-transform-runtime", { "regenerator": true } ] ] } |
위 설정은 Babel 에게 설치된 Babel 플러그인들을 사용하도록 하며 설정된 되로 동작하도록 한다.
Webpack 추가
Webpack 은 주로 JavaScript 소스 코드 파일을 함께 묶는 유명한 툴이다. 파일을 스캔하는 것처럼 Babel 과 같은 다른 툴들을 실행시킬 수 있다. 또, 모든 소스 파일을 스캔하고 이것을 JavaScript 파일로 트랜스파일해 준다. Webpack 으로 만들어지는 결과물은 index.html 파일 하나로 작성되며 JavaScript 소스코드로 이 안에 있게된다.
Webpack 설치
Webpack 설치는 다음과 같다.
1 |
npm i -D webpack webpack-cli |
Webpack 은 ‘webpack’ 패키지 안에 TypeScript 타입을 가지고 있어서 별도로 TypeScript 를 설치하지 않아도 된다.
다음으로 Webpack 개발 서버를 설치한다.
1 |
npm i -D webpack-dev-server |
Webpack 개발 서버는 개발하는 동안 사용되는 서버로, 소스코드가 변경되면 자동으로 웹 앱을 업데이트 해준다.
Babel 이 React 와 TypeScript 코드를 JavaScript 로 트랜스파일하도록 Webpack 플러그인을 설치 해줘야 한다. 이 플러그인을 ‘babel-loader’ 라고 한다.
1 |
npm i -D babel-loader |
Webpack 은 React 앱을 호스트 하기 위해 index.html 파일을 생성할 수 있는데, 마치 템플릿 처럼 그리고 React 앱들을 index.html 파일로 번들하기 위해서 index.html 파일을 사용할 것이다. 이러한 기능을 위해서 ‘html-webpack-plugin’ 플러그인을 설치해야 한다.
1 |
npm i -D html-webpack-plugin |
이제 Webpack 과 연관된 라이브러리 설치가 모두 끝났다.
Webpack 설정
Webpack 개발을 위한 설정이 필요하다. 먼저 설정을 TypeScript 형식으로 기술할 수 있도록 ‘ts-node’ 플러그인을 설치한다.
1 |
npm i -D ts-node |
이제 TypeScript 형식으로 Webpack 설정을 할 수 있다. Webpack 개발 설정 파일 이름은 ‘webpack.dev.config.ts’ 로 한다. ts 확정자를 가지고 있기 때문에 TypeScript 를 사용할 수 있으며, 이는 ‘ts-node’ 플러그인 때문에 가능한 것이다.
프로젝트 루트 디렉토리에 ‘webpack.dev.config.ts’ 파일을 다음과 같이 작성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import path from 'path'; import HtmlWebpackPlugin from 'html-webpack-plugin' import { Configuration as WebpackConfig, HotModuleReplacementPlugin, } from 'webpack'; import { Configuration as WebpackDevServerConfig } from 'webpack-dev-server' type Configuration = WebpackConfig & { devServer?: WebpackDevServerConfig; } const config: Configuration = { mode: 'development', output: { publicPath: '/', }, entry: './src/index.tsx', module: { rules: [ { test:/\.(ts|js)x?$/i, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'], } } } ] }, resolve: { extensions: ['.tsx', '.ts', '.js'] }, plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html', }), new HotModuleReplacementPlugin(), ], devtool: 'inline-source-map', devServer: { static: path.join(__dirname, 'dist'), historyApiFallback: true, port: 4000, open: true, hot: true } }; export default config; |
- ‘import path’ 는 webpack 번들이 어디에 위치하는지 지정할 수 있다.
- ‘import HtmlWebpackPlugin’ 은 index.html 파일 생성할 수 있도록 해준다.
- webpack 설정 TypeScript 타입은 ‘webpack’ 과 ‘webpack-dev-server’ 패키지에서 제공된다. intersect type 을 사용해 이를 연결하고 Configuration이라는 타입을 만든다.
‘const config: Configuration’ 에서 Configuration 타입을 사용하는 것을 알 수 있다. 위 설정에 대해서 다음과 같은 의미를 가진다.
- mode: ‘development’ 는 개발 모드를 지정한다. 이 모드는 React 개발 툴을 포함한다는 뜻이다.
- output.publicPath 는 앱의 root 패스다.
- entry 프로젝트에서 React 앱의 엔트리 지점인 index.tsx 가 어디에 있는지를 webpack 에게 알려준다.
- Webpack 은 configuration 객체를 기본적으로 export 되기를 기대하기 때문에 기본적으로 export default config 를 해줘야 한다.
- module 속성은 webpack 에게 다른 모듈을 어떻게 처리해야하는지 알려준다. webpack 에게 .js, .ts, tsx 확정자를 가지는 파일에 대해서 babel-loader 를 사용하라고 알려준다.
- resolve.extensions 속성은 webpack 이 모듈을 해석하는 동안 TypeScript 파일과 JavaScript 파일을 찾을 수 있게 알려준다.
- HtmlWebpackPlugin 은 HTML 파일을 생성하는데, src/index.html 을 생성하도록 한다.
- HotModuleReplacementPlugin 는 모듈이 앱을 실행하는 동안에 전체 릴로드 없이 업데이트 하도록 해준다.
- devtool 속성은 webpack 이 전체 인라인 소스 맵(full inline source map) 을 사용하라고 알려준다. 이는 트랜스파일하기 전에 원본 소스코드를 디버깅할 수 있도록 해준다.
- devServer 속성은 webpack 개발 서버를 위한 설정이다. 이 설정에 따르면, 웹 서버의 포트는 4000 이며 루트 디렉토리는 dist 폴더다. historyApiFallback 는 deep link 를 위해 필요하며, open: true 는 서버가 시직되면 자동으로 브라우저를 열도록 한다.
이제 webpack 서버를 구동하기 위한 Script 를 package.json 파일에 설정해 준다.
1 2 3 |
"scripts": { "start": "webpack serve --config webpack.dev.config.ts" } |
Webpack 웹 서버 실행
이제 모든 준비는 끝이 났다. 다음과 같이 웹 서버를 실행 시켜 준다.
1 |
npm run start |
정상적으로 실행이 되었다면 자동으로 브라우저가 실행되면서 화면이 출력된다.
React + TypeScript 설치 방법중에 한가지로 Webpack 을 이용하는 방법에 대해서 알아봤다.