Front End/React

[React] CRA 쓰지 않고 리액트 개발환경 구축 | webpack.config.js

옐 FE 2022. 1. 4. 09:07

출처 : https://webpack.js.org/ 웹팩 공식문서 스크린샷

리액트로 개발을 하는 사람이라면 직접 개발환경을 구축하기보다는 npx create-react-app my-app 이라는 명령어로 개발환경을 구축하는 경우가 많을 것 같다. 나는 리액트를 처음 시작할 때, 개발환경을 직접 구축할 수 있다는 생각을 하지 못했고 위의 명령어를 사용하는 것이 리액트를 사용하는 방법이라고만 알고 있었다. 그런데 리더님이 넘겨주신 자료를 보며, babel과 webpack을 포함하여 직접 리액트의 개발환경을 구축할 수 있다는 사실을 알게 되었다. CRA로 개발환경을 구축하면 편리하다는 장점이 있지만, 사용하지 않는 기능까지 포함하여 모듈의 크기가 크다는 단점을 꼽을 수 있다. 

 

프론트엔드 스터디의 1주차 과제로 리액트 개발환경 구축하기를 하고 이를 계기로 webpack에 대한 궁금증이 커졌는데 유튜브에서 생활코딩 이고잉님의 webpack 관련하여 영상을 보니 왜 이렇게 쓰는 지 몰랐던 코드들이 조금씩 눈에 들어오기 시작했다.

https://www.youtube.com/playlist?list=PLuHgQVnccGMChcT9IKopFDoAIoTA-03DA 

 

Webpack

 

www.youtube.com

총 11개의 강의로 구성되어 있는데, 영상 하나당 길이가 길지 않아서 금방 다 볼 수 있었다. 

 

 

그리고 웹팩의 공식문서는 감사하게도 한글로 번역을 해주신 분들이 있고, 잘 정리되어 있어서 한번 훑어봐야겠다!

https://webpack.kr/

 

Concepts | 웹팩

웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.

webpack.kr

 

 

리액트 개발환경을 구축할 때 리더님이 주신 노션문서를 보고서 그대로 따라서 쳤는데 node.js와 관련된 공부도 조금씩 해야하나 싶었다.

 

 

일단 webpack.config.js 파일을 생성한다.

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

require라는 함수를 여기서 처음 써봤는데, webpack을 사용하기 위해서 구성하는데 필요한 코드를 이렇게 맨 위에 적어준다.

 

리액트는 index.html의 body에서 하나의 div element 안에다가 블럭을 하나하나 조립하는 것이라고 생각한다. 그리고 이를 코드가 시작되는 지점, entry point가 index.js로 정하고 시작한다. 블럭, 그러니까 모듈을 import 해줬으면 export를 통해서 쓰는 걸 webpack을 통해서 구성해준다.

module.exports = {
  entry: './src/index.tsx',
  mode: 'development',
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    modules: [path.join(__dirname, 'src'), 'node_modules'] // Configure a absolute path
  },
  module: {
    rules: [
      {
        test: /.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: 'public/index.html',
      filename: './index.html'
    })
  ],
  devServer: {
    static: {
      directory: path.join(__dirname, 'public')
    },
    compress: true,
    host: 'localhost',
    port: 3000
  }
};

 

 

 

module.exports = {
  entry: './src/index.tsx',
  mode: 'development',

entry: module의 시작점(entry)의 속성을 적어주는데 기본값으로는 './src/index.js'지만, 리액트와 타입스크립트의 조합으로 쓸 것이기 때문에 './src/index/tsx'로 적어준다.

 

mode: 모드의 기본값은 'production'이고 'development'과 'none'이 더 있는데 웹팩에 내장된 환경별 최적화를 할 수 있다고 한다.

 

 

  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    modules: [path.join(__dirname, 'src'), 'node_modules'] // Configure an absolute path
  },

resolve: extensions에 넣어준 옵션의 확장자를 확인하고, 상대경로보다 절대경로로 하는 게 더 편해서 'src' 폴더 안에 있는 파일들은 절대경로로 사용할 수 있도록 옵션을 넣어주었다.

 

 

  module: {
    rules: [
      {
        test: /.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },

module: rules에 객체 배열을 넣어주었는데, 타입스크립트로 쓰여진 것을 자바스크립트로, 그리고 ES2015 자바스크립트의 문법으로 쓰여진 경우, 이를 모든 브라우저에서 잘 작동할 수 있도록 역시 바벨을 사용하게끔.

 

밑에 쓰여진 항목은 웹사이트의 코드를 네트워크가 받아올 때 css를 따로 받아오는 것이 아니라, 엔트리 포인트 안에서 스타일링까지 불러올 수 있도록 쓰여진 것. 이고잉님 강의를 들었을 때, uses 옵션의 순서도 중요하다고 언급하셨다. .css 확장자를 찾아서 css-loader로 불러오고 이를 style 태그 안에 넣는 작업을 style-loader가 한다고 한다.

 

 

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },

output: 시작 지점이 있으면 끝나느 지점도 있어야 하는데, 이를 dist 이름의 디렉토리 안에 'bundle.js' 파일을 만든다.

 

  plugins: [
    new HtmlWebPackPlugin({
      template: 'public/index.html',
      filename: './index.html'
    })
  ],

plugins: 웹팩의 기본 구성이고 로더가 할 수 없는 다른 작업을 수행할 목적으로 제공된다고 한다. 여기에서 HtmlWebPackPlugin은 script를 사용하여 'bundle.js' 파일을 포함하는 index.html 파일을 생성한다.

 

 


 

 

참조