Webpack

Webpack 이해하기(1) - Webpack5와 Typescript를 이용한 react app basic setup

JakeTheMaverick 2023. 12. 19. 17:29

코스 구성

  1. webpack5와 TS를 이용한 react app basic setup  [ Now We Are Here ! ]
  2. images 와 SVGs 렌더링 허용을 위한 웹팩 구성하기.
  3. dev , prod와 같은 다중 환경 웹팩 설정 셋업하기.
  4. react refesh 추가하기.
  5. ESLInt 로 린팅하기.
  6. 코드 포매터 with pretttier 사용하기
  7. Husky 사용하기 ( local 환경에서 Git hooks 을 쉽게 관리할 수 있게 해주는 도구)
  8. next steps

초기 셋업

  1. git init
  2. add .gitignore
    • build 폴더 ignore에 추가 (빌드 생산물을 깃에 저장하지 않을 것임)
    • node_modules
  3. add [src] folder
    • 소스코드
  4. add [build] folder
    • 배포를 위한 빌드 생산물들이 저장되는 디렉토리
  5. npm init —y (프롬프팅 없이 디폴트 값으로 세팅 , package.json을 생성하는 과정)
  6. [src] > add index.html
<!DOCTYPE html>
<html lang="en">
	<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React Template</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

기초 의존성 패키지 설치

1. React app을 생성할 것이므로 아래의 패키지 설치

  • yarn add react
  • yarn add react-dom

2. 타입스크립트 관련 dev dependencies 설치

  • yard add -D typescript @types/react @types/react-dom

 

3. TS를 사용하는 프로젝트이므로

  • add tsconfig.json ( 기본 설정 파일 형태 복붙 )

4. Root component 추가

  • App.tsx

5. 엔트리 포인트 파일 추가

  •  index.tsx
// Entry Point 
import  ReactDOM  from "react-dom";
import App from "./App";

//App컴포넌트를 html문서의 root id를 가진 돔 엘리먼트 내부에 렌더링
ReactDOM.render(<App />, document.getElementById('root'))


6. 바벨 설정파일 및 바벨 디펜던시 추가

  • yarn add -D @babel/core @babel/preset-env @babel/preset-react
    1. @babel/core : js코드 변환 기본엔진 제공 , 다양한 js버전 사이에 호환성 제공 및 구버전 코드로의 변환 기능 제공.
    2. @babel/preset-env: ES2015+ 버전의 JavaScript를 변환하는 데 사용, 브라우저 또는 환경에 따라 필요한 변환과 폴리필(polyfill)을 자동으로 결정.
    3. @babel/preset-react : JSX문법을 JS로 바꿔주는 엔진 제공
    4. .babelrc 바벨 설정파일 추가

7. 모듈 번들러 Webpack 사용하기

  • yard add -D webpack webpack-cli webpack-dev-server html-webpack-plugin

8. 바벨 로더 설치

  • yard add -D babel-loader
    • babel, webpack을 사용해 js를 트랜스파일링 해주는 바벨 로더 패키지 설치

9. root > [webpack] > webpack.config.js 파일 추가하기

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

module.exports = {
  entry: path.resolve(__dirname, '..', './src/index.tsx'),
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\\.(ts|js)x?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
          },
        ],
      },
      {
        test: /\\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\\.(?:ico|gif|png|jpg|jpeg)$/i,
        type: 'asset/resource',
      },
      {
        test: /\\.(woff(2)?|eot|ttf|otf|svg|)$/,
        type: 'asset/inline',
      },
    ],
  },
  mode: 'development',
  output: {
    path: path.resolve(__dirname, '..', './build'),
    filename: 'bundle.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '..', './src/index.html'),
    }),
  ],
  stats: 'errors-only',
}

webpack.config.js 설정 상세 설명

  • 1) 의존성 그래프 생성의  [엔트리 포인트] 가 되는 파일을 정의
  entry: path.resolve(__dirname, '..', './src/index.tsx'),
//1.현재 config파일이 존재한 디렉토리(__dirname)에서 '..' 상위폴더로 이동
//2. (./)현재위치에서 src 폴더의 index.tsx 파일을 엔트리 포인트로 설정.

*Cf.) path.resolve ()의 동작 

path.resolve(__dirname, '..', './src/index.tsx') 구문에 대한 설명은 다음과 같습니다.

  • path.resolve(): 이 메소드는 주어진 경로의 조각들을 절대 경로로 결합합니다.
  • __dirname: __dirname은 Node.js에서 현재 실행 중인 파일의 디렉토리의 절대 경로를 나타내는 변수입니다. 예를 들어, 현재 파일이 /home/user/project/folder/script.js에 위치해 있다면, __dirname은 /home/user/project/folder를 반환합니다.
  • '..': 이 문자열은 "상위 디렉토리로 이동"을 의미합니다. 따라서, __dirname에서 한 단계 상위 디렉토리로 이동하게 됩니다.
  • './src/index.tsx': 이 경로는 현재 디렉토리(.)에서 시작하여 src 폴더 내의 index.tsx 파일을 가리킵니다.
  • 요약: path.resolve() : 파라미터 문자열을 이어서 절대경로를 생성
    • path.resolve(__dirname, ‘..’ , ‘./src/index.tsx’ )
    • __dirname(현재파일의 부모디렉토리) → ‘..’ ( 상위폴더로) → ‘./src/index.tsx’ ( (.)현재상태에서 src로 이동후 index.tsx 까지 경로를 반환
  • 2) App 구성 요소를 가져올 때 인식하는 확장자명의 순서 정의
resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
// 확장자명 tsx -> ts -> js 순으로 인식해서 가져옴  
  • 3) module rule 정하기
module: {
    rules: [
      {
        test: /\\.(ts|js)x?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
          },
        ],
      },
}
// **tsx, ts, jsx, js 확장자에 대해 바벨 로더를 사용해야 함을 명시.**
  • 4) 번들링 output을 어느 위치, 어느 파일명에 저장할 것인지 설정
output: {
    path: path.resolve(__dirname, '..', './build'), // webpack.config.js 파일이 위치하는 곳 기준으로 상위폴더 -> build폴더 
    filename: 'bundle.js', // build폴더에 생성될 파일명 bundle.js 
  },
  • 5) Webpack이 개발 모드(Development Mode)로 실행되어야 함을 지정
mode: 'development',
  • webpack 플러그인 설정 (HtmlWebpackPlugin)
plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '..', './src/index.html'),
    }),
  ],
// bundle.js 파일을 index.html(in build folder)에 삽입하고, 배치해주는 역할 
// -> 이로인해 src폴더 내의 index.html에서 스크립트 태그를 직접 지정하지 않아도 됨.

10. package.json → npm (run) starts scripts 정의

"scripts": {
    "start": "webpack serve --config webpack/webpack.config.js --open",
...
}
// 1. "start": "webpack serve --config webpack/webpack.config.js --open" 명령은,
// 2. [webpack serve] Webpack 개발 서버를 시작하고, 
// 3. [--config ~filename]특정한 webpack.config.js 파일로 구성을 지정하며, 
// 4. [--open] 서버가 시작되면 자동으로 브라우저를 열어 개발을 바로 시작할 수 있게 해줍니다

 

Cf. ) 코드스플리팅 권장 alert 발생시 webpack.config.js에 아래의 설정 코드 추가 

// 진입점 파일 크기가 244kb를 초과하는 경우 코드스플리팅 권장 alert 해제
performance : {
hints : false
},

 

 

 

References
- https://webpack.kr/concepts/entry-points
- https://www.youtube.com/watch?v=Elpu7CIuqjY&list=PLC3y8-rFHvwiWPS2RO3BKotLRfgg_8WEo&index=1

- https://stackoverflow.com/questions/41157472/webpack-warning-entrypoint-size-limit-bundle-js