0%

CRA 없이 React + TypeScript 세팅하기

보통, cra typescript를 위해서

1
npx create-react-app [project-name] --template typescript

를 쓰지만,

이번에는 직접 만들어보면서 react library의 작동 원리를 살펴보려고 한다.

Adding TypeScript | Create React App

세팅 과정

  1. npm을 세팅한다.

    1
    npm init -y // -y로 default 설정 적용
  2. npm pkg를 설치한다.

    1. typescript

      1
      npm i --s typescript @types/react @types/react-dom
    2. react

      1
      npm i --s react react-dom
    3. babel

      1
      npm i --s-d babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
    4. webpack

      1
      npm i --s-d webpack webpack-dev-server webpack-cli
  3. 타입스크립트 설정하기

    1. 타입스크립트 설정 파일을 만들기 위해,

      • 전역으로 설치된 경우 tsc --init
      • 해당 프로젝트에만 설치된 경우 직접 파일을 명시해야 하기 때문에 node_modules/.bin/tsc --init

      을 수행한다.

    2. 그럼 tsconfig.json 이 생성되는데, 다음과 같이 주석을 해지해주면 된다. (꼭 밑과 같지 않아도, 경우에 맞게/ 입맛에 맞게 설정해두면 두고두고 용이함!)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      {
      "compilerOptions": {
      "outDir": "./dist/",
      "sourceMap": true,
      "noImplicitAny": true,
      "module": "commonjs",
      "target": "es5",
      "jsx": "react"
      },
      "include": ["./src/**/*"]
      }
  4. 리액트 Entry File 설정

    보통 cra 시 다음과 같은 디렉토리를 갖게 된다. (직접 만들어야 하는 파일만 명시해둠)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    node_modules
    public
    index.html
    src
    App.tsx
    index.tsx
    package.json
    tsconfig.json
    ...

    따라서 먼저 Component를 만들어보자.

    1
    import * as React from "react";// 함수형 컴포넌트const App: React.FunctionComponent<{ name: string }> = ({ children, name }) => (  <div title={name}>{children}</div>);export default App;

    그리고 html에서 script로 읽을 index.js를 생성하자.

    1
    import * as React from "react";import * as ReactDOM from "react-dom";import App from "./App";// 클래스형 컴포넌트class Root extends React.Component {  render() {    return (      <div>        <App name="test"> test </App>      </div>    );  }}ReactDOM.render(<Root />, document.getElementById("root"));

    원래는 따로 클래스 정의 없이 ReactDOM.render() 에 클래스 컴포넌트 렌더 안에 들어있는 코드를 적어 바로 컴포넌트를 전달한다. 축약하면 다음과 같다.

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

    이제 최종적으로 js 파일을 전달할 public/index.html 을 정의하자!

    1
    <!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <title>채용 프로세스 이메일 템플릿</title>  </head>  <body>    <div id="root"></div>    <!-- 번들 파일 추가 -->    <script src="./bundle.js"></script>  </body></html>

    html은 id="root" 를 통해 index 파일의 document.getElementById("root") 를 읽어나가기 때문에, 따로 script를 적용하지 않는다. 하지만, 이 src/index.js 를 읽기 위해 webpack 번들러를 설정하였으므로, 해당 bundle.js 파일을 script로 적용해야 한다!

    <div id="root"></div> 밑에 전달해야 한단다.
    내 생각에는 html을 읽는 순서 때문에 그런듯.

  5. Babel 설정하기

    1. trans-compile을 위해 .babelrcbabel.config.js 로 설정한다.

      1
      {  "presets": [    "@babel/preset-env",    "@babel/preset-react",    "@babel/preset-typescript"  ]}
  6. webpack 설정하기

    1. 이 모든 과정을 연결하기 위해 번들러 webpack을 설정한다. 바벨과 같이 webpack.config.js 를 루트 폴더에 만들면 됨!

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

      resolve: 확장자나 경로를 알아서 처리할 수 있도록 설정하는 옵션이다.
      module: 이 옵션에 설치한 ts-loader와 babel-loader를 설정하면 된다. loader들은 오른쪽에서 왼쪽 방향으로 적용되기 때문에 ts-loader를 babel-loader보다 오른쪽에 위치시켜야 한다.
      output: 번들화 된 파일을 export할 경로와 파일명을 설정한다.

  7. 마지막으로, package.json 에서 script 를 설정해주면 된다.

    1. npm start 또는 npm run start 로 script를 실행할 수 있도록 다음과 같이 설정하면 됨!

      npm run 시 script 내부의 명령어을 적용할 수 있다!

      1
      "scripts": {    "start": "webpack-dev-server --config ./webpack.config.js --mode development",    "test": "echo \"Error: no test specified\" && exit 1"  },

FAQ

  • 웹팩 설정에서 사용된 inline 모드는 무엇일까?

    네트워크 방화벽 구성과 동일하게 모든 트래픽이 해당 보안장비를 거쳐야만 목적지로 전송될 수 있도록 네트워크를 구성하는 방식

    [네트워크] 인라인 모드와 미러링(스니핑) 모드의 차이점

  • hot 모드는?

    Hot Module Replacement(HMR)는 응용프로그램 실행 중에 추가 또는 제거된 모듈들을 페이지 리로드 없이 교체하는 기능입니다.

Reference

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

위 블로그 기반으로,

CRA없이 React + TypeScript 셋팅하기! - chanyeong

위 블로그는 심화형임