React webpack을 뜯어보자

김정현·2022년 10월 27일

React

목록 보기
6/7

예전에 webpack에 관한 짧은 글을 올렸었습니다.
그때는 webpack이 어떠한 것이다 정도로만 알고 넘어갔었는데, 최근 webpack에 대한 관심이 생기면서 현재 진행중인 웹 포트폴리오 개발에 사용된 CRA는 어떠한 webpack설정을 하고 시작하는지 궁금해져 한번 뜯어보려고 합니다.

❗️아직 webpack에 대해 많은 공부를 하고 있어 설명이 다소 부족할 수 있습니다.

📦 CRA에서 webpack 찾기

React프로젝트 시작을 위해 많이 사용하는 CRA는 기본적으로 webpack 설정을 숨겨놓습니다.
이러한 설정 관련 파일들을 볼 수 있도록 CRA로 생성된 프로젝트의 package.json에는 eject 스크립트가 기본적으로 정의되어 있습니다.
따라서 다음과 같이 eject를 실행해 줍니다.

	npm run eject

그러면 아래 사진과 같이 숨겨진 config 폴더가 나오게 됩니다.

config 폴더 내의 webpack.config.js 파일을 열게 되면 CRA로 설정된 기본 webpack 설정들이 나타나게 됩니다.

양이 너무 많아 모든 것을 확인할 순 없고, 일단 설정에 관련된 것들만 보겠습니다.

target

특정 환경을 대상으로 하도록 webpack에 지정합니다. browserslist 설정이 없으면 'browserslist' 혹은 'web'으로 설정됩니다.

target으로 설정할 수 있는 종류는 다음과 같습니다.

💡 [[X].Y]는 버전을 표시합니다.

OptionDescription
async-node[[X].Y]Node.js와 유사한 환경에서 사용할 수 있도록 컴파일합니다.
electron[[X].Y]-main메인 프로세스를 위해 Electron으로 컴파일합니다.
electron[[X].Y]-renderer렌더러 프로세스를 위해 Electron으로 컴파일하여 JsonpTemplatePlugin, 브라우저 환경을 위한 FunctionModulePlugin, CommonJS와 Electron의 내장 모듈을 위한 NodeTargetPlugin 및 ExternalsPlugin을 사용하여 대상을 제공합니다.
electron[[X].Y]-preload렌더러 프로세스를 위해 Electron으로 컴파일하여 asyncChunkLoading을 true로 설정한 NodeTemplatePlugin, 브라우저 환경을 위한FunctionModulePlugin, NodeTargetPlugin, CommonJS 및 Electron의 내장 모듈을 위한 ExternalsPlugin을 사용하여 대상을 제공합니다.
node[[X].Y]Node.js와 유사한 환경에서 사용할 수 있도록 컴파일 합니다. (Node.js require를 사용하여 청크를 로드합니다..
web브라우저와 동일한 환경에서 사용하기 위하여 컴파일합니다. (기본값)
webworker웹 워커로 컴파일합니다.
esX지정된 ECMAScript 버전으로 컴파일합니다. 예: es5, es2020
browserslistbrowserslist-config에서 (browserslist config를 사용할 수 있는 경우 기본값) 플랫폼과 ES 기능을 추론합니다.

CRA에선 browserlist를 target의 기본값으로 설정합니다.
만약 target: false일 경우 원하는 플러그인을 선언하지 않으면 자동으로 es2015를 기본값으로 설정합니다.

mode

프로젝트의 모드를 설정합니다. development, none, production 중 선택할 수 있습니다.

각 모드에 따라 번들링 시 파일의 용량이 다릅니다.

development

동일한 파일을 development 모드로 번들링 할 경우 출력된 결과물의 크기는 40kb 입니다.

none

none 모드로 번들링 할 경우 출력된 결과물의 크기는 35kb 입니다.

production

production 모드로 번들링 할 경우 출력된 결과물의 크기는 12kb 입니다.

entry

번들링을 시작하는 기준 파일을 설정합니다.
webpack은 여러개의 자바스크립트 모듈을 하나로 묶어주는 번들러이므로 모든 모듈과 연관된 최상위 파일을 기준으로 의존 트리를 만들며 번들링을 합니다.
따라서 entry 속성으로 지정된 파일을 기준으로 의존 트리를 만들며 번들링을 진행합니다.

// src 폴더 내의 index.js 파일을 기준으로 번들링을 진행합니다.

module.exports = {
  entry: './src/index.js'
}

output

번들링의 결과물을 저장할 위치를 설정합니다.
filename 속성을 통해 번들링 된 파일의 이름을 설정할 수 있으며 path 속성을 통해 번들링 된 파일의 저장 경로를 설정할 수 있습니다.

module.exports = {
  output: {
    path: __dirname,
    filename: "build.js",
  },
};

loader

webpack이 자바스크립트 파일이 아닌 다른 파일(css, images 등)의 변환을 도와주는 옵션입니다.

기본적으로 다음과 같은 파일을 webpack으로 번들링하게 되면 에러가 발생합니다.

// app.js
import './common.css';

console.log('css loaded');
/* common.css */
p {
  color: blue;
}
// webpack.config.js
module.exports = {
  entry: './app.js',
  output: {
    filename: 'bundle.js'
  }
}

위 에러 메시지는 webpack이 css 해석의 어려움이 있으니 적절한 loader를 추가해달라는 뜻입니다.
이렇게 webpack은 기본적으로 자바스크립트와 연관된 css 및 이미지 같은 파일들을 번들링하기 위해 다음과 같이 loader를 설정합니다.

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['css-loader']
      }
    ]
  }
}

위의 module 쪽 코드를 보면 rules 배열에 객체 한 쌍을 추가했습니다. 그리고 그 객체에는 2개의 속성이 들어가 있는데 각각 아래와 같은 역할을 합니다.

  • test : 로더를 적용할 파일 유형 (일반적으로 정규 표현식 사용)
  • use : 해당 파일에 적용할 로더의 이름
    정리하자면 위 코드는 해당 프로젝트의 모든 CSS 파일에 대해서 css-loader를 적용하겠다는 의미입니다.

적용 후 빌드하면 정상적으로 실행되는 것을 알 수 있습니다.

💡 만약 여러개의 loader를 사용해야 할 경우 다음과 같이 rules 속성에 추가해주면 됩니다.

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
      { test: /\.ts$/, use: 'ts-loader' },
      // ...
    ]
  }
}

이 외에도 webpack의 세계에는 훨씬 많은 설정들을 할 수 있으나 추후에 필요로 하면 추가적인 포스팅을 진행하도록 하겠습니다 😄

profile
프론트엔드 개발자(가 되고싶은 주니어)

0개의 댓글