Webpack && Babel로 React, Typescript 개발환경 구축하기

junsangyu·2023년 1월 15일
0

CRANext.js없이 React 환경을 최소한의 세팅으로 구현하기(React 18 + Webpack 5 + Babel + Typescript + HMR)

[React 18, Webpack 5, Babel]

1. npm 패키지 설치

# react 패키지 설치
npm i react react-dom
# webpack 설치, webpack cli 명령어 패키지 설치(개발할때만 필요하므로 devdep)
npm i -D webpack webpack-cli
# babel 설치, jsx -> js 변환을 위해서 react 프리셋 설치
npm i -D babel-loader @babel/core @babel/preset-react

2. index.html index.js 작성

html에는 webpack에서 번들링될 js파일을 main.js 파일을 script 태그로 작성, body에서 id가 root인 div를 하나 만든다.
js에서는 DOM id가 root인 element를 찾아서 react의 root를 생성한다.
이때 index.js 에서 DOM에서 탐색하는 작업인 document.getElementById 를 실행하기 때문에 script태그에 defer 를 달아줘야 한다.

<!-- dist/index.html -->
<!DOCTYPE html>
<html>
  <head>
    <script src="./main.js" defer></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
// src/index.jsx
import { createRoot } from 'react-dom/client';

const container = document.getElementById('root');

if (container === null) {
  throw new Error('#root element not found');
}

const root = createRoot(container);

root.render(<h1>Hello, World!</h1>);

3. webpack.config.js 작성

const path = require('path');

module.exports = {
  entry: {
    // 번들링 시작점
    main: './src/index.jsx'
  },
  output: {
    // 결과 .js 파일 위치
    // dist/main.js 에 저장되게 설정
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        // .jsx나 .js 파일일때
        test: /\.(jsx|js)$/,
        // node_modules 아래있는 파일 제외
        exclude: /node_modules/,
        // babel에서 컴파일해라
        loader: 'babel-loader'
      }
    ]
  }
}

4. babel.config.json 작성

@babel/preset-react 으로 jsx -> js 컴파일 하기
이때 React 17부터 JSX Transform 으로 인해서 import React from 'react' 를 모든 React 파일에 작성할 필요가 없어졌다.
그러나 Babel에서 이를 자동으로 변환해주지 않기 때문에 { "runtime": "automatic" } 부분을 작성해야 한다.

{
  "presets": [
    ["@babel/preset-react", { "runtime": "automatic" }]
  ]
}

5. 빌드

먼저 package.json에서 build script를 작성해주자

{
  ...,
  "scripts": {
    "build": "webpack --mode development"
  }
}

그리고 npm run build 를 실행하면 dist/main.js 파일으로 번들링 될것이다. 이제 index.html 파일을 브라우저에서 보면 React 코드가 정상적으로 작동 할 것이다.

[... + Typescript]

1. npm 패키지 추가

# babel에서 typescript를 javascript로 컴파일 해주는 프리셋
npm i -D @babel/preset-typescript
# vscode에서 react 코드가 타입에러 나면 설치
# npm i -D @types/react-dom

2. tsconfig.json 작성

strict 옵션은 typescript를 엄격하게 타입체킹하기 위해 사용
jsx 옵션은 타입스크립트에서 jsx 문법 사용을 위해 사용
skipLibCheck 옵션은 npm 라이브러리 타입체크를 꺼주기 위해 사용

{
  "compilerOptions": {
    "strict": true,
    "jsx": "react-jsx",
    "skipLibCheck": true
  }
}

3. webpack.config.js 수정

const path = require('path');

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

4. babel.config.json 수정

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

5. 빌드

index.jsx를 index.tsx로 수정 후 npm run build

[..., HMR]

1. webpack.config.js 수정

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.tsx'
  },
  output: {
    path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js']
  },
  module: {
    rules: [
      {
        test: /\.(tsx|ts|jsx|js)$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },
  devServer: {
    // HMR 기능 ON
    hot: true,
    /*
    이 부분은 github codespaces에서 HMR websocket 주소를 잘못 잡아서 직접 websocket url을 수정함
    allowedHosts: "all",
    client: {
      webSocketURL: 'ws://0.0.0.0/ws',
    }
    */
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html'
    })
  ]
}

2. index.html 작성

<!-- index.html -->
<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
</html>

3. package.json script 추가

{
  ...,
  "scripts": {
    "build": "webpack --mode development",
    "dev": "webpack serve"
  }
}

4. 빌드

npm run dev 하면 자동으로 8080포트에 webpack devserver가 켜짐

profile
👨🏻‍💻

0개의 댓글