React

리액트 - 타입스크립트 시작하기 (without CRA)

하늘을난모기 2020. 9. 8. 15:28

CRA(create-react-app)는 분명 편하긴 하지만, 결국 다 학습해야 하는 입장에서, 필요하지 않은 패키지도 추가한다는 입장에서 너무 비대한 기능이다.

CRA를 사용하지 않고, 초기 react - typescript를 세팅하는 법을 알아보려고 한다.

1. 프로젝트 생성하기
> 아무것도 없는 빈 폴더를 만든다.

2. npm 설정하기

npm init

3. npm package 추가하기

// 웹팩 설치
npm install --save-dev webpack webpack-dev-server webpack-cli

// 바벨 설치
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react babel-preset-es2015

// 리액트 설치
npm install --save react react-dom

// 타입스크립트 설치
npm install --save @types/react @types/react-dom

4. webpack.config.js 설정하기
> 루트 디렉토리에 webpack.config.js를 생성한다.

module.exports = {
    entry: [
        './src/index.tsx'
    ],
    output: {
        filename: "bundle.js",
        path: __dirname + "dist",
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx|ts|tsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            }
        ],
    },
    resolve: {
        extensions: ['*', '.js', '.jsx', '.ts', '.tsx']
    }
};

5. tsconfig.json 설정하기
> 루트 디렉토리에 tsconfig.json을 생성한다.

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es5",
    "jsx": "react"
  },
  "include": [
    "./src/**/*"
  ]
}

6. .babelrc 설정하기
> 루트 디렉토리에 .babelrc를 생성한다.

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

7. index.html 추가하기
> 루트 디렉토리에 index.html을 생성한다.
주의) <div id='root'></div> 아래에 <script src='./bundle.js'></script>를 추가해야 한다는 것!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="root"></div>
    <script src="./bundle.js"></script> <!-- 번들 파일 추가 -->
</body>
</html>

8. src/index.tsx 추가하기
> src 디렉토리를 생성하고, 그 아래 index.tsx 파일을 추가한다.

import * as React from "react";
import * as ReactDOM from "react-dom";

// 함수형 컴포넌트
const Component: React.FunctionComponent<{ name: string }> =
    ({
         children,
         name
     }) => <div title={name}>{children}</div>;

// 클래스형 컴포넌트
class Root extends React.Component {

    render() {
        return (
            <div>
                <Component name={"모기"}>
                    요로로롤
                </Component>
            </div>
        )
    }
}

ReactDOM.render(<Root/>, document.getElementById('root'));

9. package.json에 script 추가하기
> "start": "webpack-dev-server --config ./webpack.config.js --mode development"를 scripts 안에 추가한다.

// package.json 전체 코드
{
  "name": "todo-react",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development", // 추가
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "todo"
  ],
  "author": "Mos",
  "license": "ISC",
  "dependencies": {
    "@babel/preset-typescript": "^7.10.4",
    "@types/react": "^16.9.49",
    "@types/react-dom": "^16.9.8",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "babel-loader": "^8.1.0",
    "babel-preset-es2015": "^6.24.1",
    "typescript": "^4.0.2",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
}

디렉토리 구조

 

10. npm start
> localhost:8080에 들어가서 정상 출력 확인.