오늘은 강의를 통해 웹팩에 대해 간단히 알아보았습니다.

예전에 CRA없이 리액트를 설정해보았었는데요.

이번엔 웹팩에 대해 간단하게 정리하는 시간이 될듯하네요.


1. Module

commonJS 방식

일반적인 commonJS를 이용한 모듈 사용입니다.

index.js

/**
 * 1. 원의 넓이는 구하는 공식
 * 2. PI 정의
 * 3. 공식을 통해 결과 얻기
 */
const { getCircleArea } = require('./mathUtil');

const result = getCircleArea();
console.log(result);

mathUtil.js

// mathUtil.js
const PI = 3.14;
const getCircleArea = r => r * r * PI;

// 객체 형태로 내보내겠습니다.
module.exports = {
  PI,
  getCircleArea
}

// 아래와 같은 축약형도 가능하지만 한 가지 방법으로 통일하는 것이 좋습니다.
exports.PI = PI;
exports.getCircleArea = getCircleArea;

ESM 방식

NodeJS는 commonJS를 기본방식으로 사용하기 때문에 외부 모듈이 필요합니다.

yarn add esm

그리고 파일을 실행하기 위해 아래 script를 사용해야 합니다.

node -r esm index.js

index.js

/**
 * 1. 원의 넓이는 구하는 공식
 * 2. PI 정의
 * 3. 공식을 통해 결과 얻기
 */
import { getCircleArea } from './mathUtil';

const result = getCircleArea();
console.log(result);

mathUtil.js

const PI = 3.14;
const getCircleArea = r => r * r * PI;
const getSquareArea = r => r * r;

// 아래처럼 default를 사용할 경우 index.js에서는 객체 이름을 따로 설정해서 받아야합니다.
export { PI, getCircleArea, getSquareArea };

readline

NodeJS 내부 모듈인 readline인데요, 주로 알고리즘문제에 자주 사용됩니다.

유저에게 값을 입력받을 수 있습니다.

// index.js
import readline from 'readline';
import { getCircleArea, getSquareArea } from './mathUtil';
import { logInput, logResult, logFigureError } from './log';

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('넓이를 구하고자 하는 도형의 종류 (정사각형, 원) : ', figure => {
  console.log(`선택된 도형 : ${figure}`);

  switch (figure) {
    case '정사각형':
      rl.question('변의 길이를 입력하세요 : ', input => {
        console.log(logInput(input));
        console.log(logResult(figure, getSquareArea(input)));
        rl.close();
      });
      break;
    case '원':
      rl.question('반지름 길이 : ', input => {
        console.log(logInput(input));
        console.log(logResult(figure, getCircleArea(input)));
        rl.close();
      });
      break;
    default:
      console.log(logFigureError);
      rl.close();
      break;
  }
});
// log.js
const logInput = input => `입력받은 값 : ${input}`;
const logResult = (figure, input) => `${figure}의 넓이는 : ${input}입니다.`;
const logFigureError = `지원되지 않는 도형 입력입니다`;

export { logInput, logResult, logFigureError };

2. Bundle

서로 참조관계가 있는 모듈들을 모아 하나의 파일로 모으는 것입니다.

Bundle의 장점

  • 모든 모듈을 로드하기 위해 검색하는 시간이 단축됩니다.

  • 사용하지 않는 코드를 제거해줍니다.

  • 파일 크기를 줄여줍니다.

3. Webpack

WebPack 기본 구조

// index.js
import bar from './bar';

bar();


// bar.js
export default function bar() {
  // something bar;
}

위처럼 된 두 파일을 dist/bundle.js로 합쳐주는 역할을 합니다.

웹팩설정파일의 내부를 간단하게 보겠습니다.

// dist/bundle.js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist');
    filename: 'bundle.js'
  }
}
  • Entry : 모듈의 의존 관계를 이해하기 위한 시작점을 설정합니다.

  • Output : Webpack이 생성하는 번들 파일에 대한 정보를 생성

[ EXAMPLE ]

이전 모듈에서 사용했던index.js , mathUtil.js, log.js를 그대로 사용하겠습니다.

먼저 웹팩 패키지를 설치합니다.

yarn add --dev webpack webpack-cli

webpack.config.js 파일을 생성하고 작성해봅니다.

// webpack.config.js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  target: 'node'
};

이후 이전에 작성했던 index.js, log.js, mathUtil.js를 src폴더 내에 넣어줍니다.

웹팩 내용을 보면 entry는 src폴더 내의 index.js이고, output은 dist폴더가 있죠?

npx webpack 을 실행하면 dist폴더 내에 bundle.js가 생성됩니다!

Mode 설정

위에서 npx webpack을 실행하면 mode를 설정안했다고 경고가 나옵니다.

package.json에 "scripts"에 "build" : "webpack" 을 추가해줍니다.

그리고 webpack.json에 mode: "none"을 추가해줍니다.

yarn build를 실행해보면 에러가 없어집니다.

단, none으로 설정 시 bundle.js의 최적화가 되지 않습니다.

production모드 설정

mode: 'production'만 추가해도 되지만 공통된 부분을 제거하기 위해 패키지를 설치합니다.

yarn add webpack-merge --dev 로 설치하고, webpack.common.js를 생성합니다.

사용할 공통된 부분을 입력합니다.

 // webpack.common.js
 const path = require('path');

 module.exports = {
 entry: './src/index.js',
 output: {
  path: path.resolve(__dirname, 'dist'),
  filename: 'bundle.js'
 },
 target: 'node'
 };

이후 webpack.prod.js를 생성하고 작성합니다.

 // webpack.prod.js
 const merge = require('webpack-merge');
 const common = require('./webpack.common');

 module.exports = merge(common, {
 mode: 'production'
 });

이제 package.json에서 production모드로 수정합니다.

 "scripts": {
  "start": "node -r esm index.js",
  "build": "webpack --config webpack.prod.js"
 },

이제 yarn build 를 하면 제대로 최적화가 되는 것을 확인할 수 있습니다.

Loader

다양한 모듈들을 입력받아 처리하는 역할을 합니다.

webpack.config.js에 module을 추가하고, rules키의 값에 loader를 추가합니다.

Plugin

번들파일에 변화를 주기도 하고,

개발모드에서 개발 편의성 제공하며,

프로덕션모드에서 코드 최적화하기도 합니다.

module.exports = {
  plugins: [new Plugin({ ...option})]
}