하루에 한 문제

웹팩 (WebPack) 본문

카테고리 없음

웹팩 (WebPack)

dkwjdi 2021. 4. 26. 21:50

우선 모듈에 대해 이야기 해보자. 문법 수준에서 모듈을 지원한것은 es6부터이다.

import/export 구문이 없던 모듈 이전 상황을 보면 웹팩의 필요성을 느끼는데 수월하다.

 

math.js

function sum(a, b) {
    return a + b;
}

 

app.js

console.log(sum(1, 2));

위 코드는 모두 하나의 HTML파일 안에서 로딩해야만 실행된다.

math.js가 로딩되면 app.js는 이름 공간에서 'sum'을 찾은 뒤 함수를 실행한다.

문제는 'sum'이 전역공간에 노출된다는 점이다.

만약 다른 파일에서 sum=1; 처럼 사용하게 된다면 충돌이 일어난다.

 

 

IIFE 방식의 모듈

IIFE는 즉시 실행 함수 표현을 말한다.

(function () {
  //code
})();

 

위의 방식의 문제점을 해결하기 위해 스코프를 사용한다.

함수 스코프를 만들어 외부에서 안으로 접근하지 못하도록 공간을 격리하는 것이다.

스코프 안에서는 자신만의 이름 공간이 존재하므로 스코프 외부와 이름 충돌을 막을 수 있다.

 

math.js

var math = math || {};

(function () {
	function sum(a,b){
    	return a+b;
    }
    
    math.sum = sum;
})();

 

app.js

console.log(math.sum(1,2));

같은 코드를 즉시실행함수로 감쌌기 때문에 다른 파일에서 이 안으로 접근할 수가 없다. 심지어 같은 파일일지라도 말이다. 자바스크립트 함수 스코프의 특징이다. 'sum'이란 이름은 즉시실행함수 안에 감추어졌기 때문에 외부에서는 같은 이름을 사용해도 괜찮다. 전역에 등록한 'math'라는 이름 공간만 잘 활용하면 된다.

 

 

이러한 방식으로 자바스크립트 모듈을 구현하는 대표적인 명세가 AMD와 CommonJS다.

CommonJs는 자바스크립트를 사용하는 모든 환경에서 모듈을 하는 것이 목표다. exports 키워드로 모듈을 만들고 require() 함수로 불러 들이는 방식이다. 대표적으로 서버 사이드 플래폼인 Node.js에서 이를 사용한다.

 

math.js

exports function sum(a, b) { return a + b; }

 

app.js

const math = require("./math.js")
math.sum(1, 2) // 3

 

AMD(Asynchronous Module Definition)는 비동기로 로딩되는 환경에서 모듈을 사용하는 것이 목표다. 주로 브라우져 환경이다.

 

이렇게 각 커뮤니티에서 각자의 스펙을 제안하다가 ES2016(ES6)에서 표준 모듈 시스템을 정의했다.

지금은 바벨과 웹펙을 이용해 모듈 시스템을 사용하는 것이 일반적이다.

 

math.js

export function sum(a, b) {
  return a + b
}

app.js

import * as math from "./math.js"
math.sum(1, 2) // 3

export를 통해 모듈을 만들고 import구문을 통해 가져올 수 있다.

 

브라우져의 모듈 지원

모든 브라우져에서 모듈 시스템을 지원하지는 않는다. 인터넷 익스플로러를 포함한 몇 몇 브라우져에서는 여전히 모듈을 사용하지 못한다. 가장 많이 사용하는 크롬 브라우져만 잠시 살펴보자.

 

index.html

<script type="module" src="app.js"></script>

근데 브라우저에 무관하게 모듈을 사용하고 싶은데 우쨰야할까....

그답이 바로 웹팩이다!

 

 

웹팩은 여러개 파일을 하나의 파일로 합쳐주는 번들러(bundler)다. 하나의 시작점(entry Point)으로부터 의존적인 모듈을 모두 찾아내서 하나의 결과물을 만들어낸다. app.js 부터 시작해 math.js 파일을 찾아 하나의 파일로 만들어준다.

 

간단하게 웹팩으로 번들링 작업을 한번 해보자.

번들 작업을 하는 webpack 패키지와 웹팩 터미널 도구인 webpack-cli를 설치하자

npm install -D webpack webpack-cli

설치를 완료하고 package.json을 확인해보면 아래의 그림처럼 나올 것이다. 

 

또한 node_modules/.bin 폴더에 webpack과 webpack.cli가 설치된 것을 확인할 수 있을 것이다.

 

--help 옵션으로 사용방법을 한번보자.

 node_modules/.bin/webpack --help

 --mode <value>                         Defines the mode to pass to webp
                                     [선택: "development", "production", "none"]
 --entry <value...>                     The entry point(s) of your appli [문자열]
  -o, --output-path <value>              Output location of the file gene

--mode, --entry, --output--path(-o) 세 개 옵션만 사용하면 코드를 묶을 수 있다.

--mode : 말그대로 모드를 선택하는 것이다(개발, 배포..)

--entry : 시작점

--output-path(-o) : 아웃풋이 저장될 경로 

 

node_modules/.bin/webpack --mode development --entry ./src/app.js --output-path  dist/main.js

위의 명령어를 실행하면 dist/main.js에 번들된 결과가 저장된다.

그 후

 <script src="dist/main.js/main.js"></script>

 

index.html을 위의 내용처럼 고치게 되면 실행이 잘 되는것을 볼 수 있다!

 

지금은 필수인자 3개만 주었지만 이후에는 꽤 많은 옵션을 설정할 것이다.

매번 터미널에 입력하기는 귀찮으니 webpack설정파일을 하나 만들어보자.

 

우선 다시 --help를 통해 config옵션을 확인해보자

-c, --config <value...>                Provide path to a webpack configuration file e.g. ./webpack.config.js.
  --config-name <value...>    

이 옵션은 웹팩 설정파일의 경로를 지정할 수 있는데 기본 파일명이 webpack.config.js 혹은 webpackfile.js다. webpack.config.js 파일을 만들어 방금 터미널에서 사용한 옵션을 코드로 구성해 보자.

 

webpack.config.js

const path = require("path")

module.exports = {
  mode: "development",
  entry: {
    main: "./src/app.js",
  },
  output: {
    filename: "[name].js",
    path: path.resolve("./dist"),
  },
}

터미널에서 사용한 옵션인 mode, entry, ouput을 설정한다.

  • mode는 'development' 문자열을 사용했다.
  • entry는 어플리케이션 진입점인 src/app.js로 설정한다.
  • ouput에 설정한 '[name]'은 entry에 추가한 main이 문자열로 들어오는 방식이다.
    • output.path는 절대 경로를 사용하기 때문에 path 모듈의 resolve() 함수를 사용해서 계산했다. (path는 노드 코어 모듈 중 하나로 경로를 처리하는 기능을 제공한다)

웹팩 실행을 위한 NPM 커스텀 명령어를 추가한다.

 

package.json

{
  "scripts": {
    "build": "webpack"
  }
}

 

 

참고

jeonghwan-kim.github.io/series/2019/12/10/frontend-dev-env-webpack-basic.html

webpack.js.org/

Comments