Webpack 훑어보기 - 개념, 목적

Lee Sang Hyuk·2023년 4월 20일
0

Bundling

목록 보기
1/2
post-thumbnail

이해하기 전

웹 개발을 한번쯤 해봤으면 “모듈(Module)”이라는 단어를 들어봤을 것이다. 자바스크립트 관련 코드를 작성하고 다른 코드에 재사용을 위해 특정 함수나 변수들을 export 하는 경우가 많다. 과거에는 모듈 개념에 대해서 크게 신경 쓰지 않았지만, 자바스크립트에 의존하는 기능이 복잡해지고 커지면서 코드의 가독성 및 유지 관리를 위해 모듈의 중요성을 보여주고 있다.

// index.html

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

// 간단한 Module 파일 생성
// module.js

const combine = (a, b) => {
	return a + b;
}

const DEFAULT_SIZE = 5;

export { combine, DEFAULT_SIZE }

무작정 모듈화 시키는 것은 문제를 발생시킬 수 있다. 아래와 같은 HTML 파일에 두 개의 자바스크립트 파일을 적용시키면 동작에는 문제가 없지만 예상 밖의 결과를 이끌어 낼 수 있다.

해당 코드는 getNumber 함수를 통해 10의 결과를 도출하고 싶지만, 아래 main.js에 중복 변수 선언으로 인해 다른 값으로 출력된다. 이렇게 다른 파일이라도 같은 변수명으로 선언하여 개발하는 경우가 많은데 이는 스코프 문제를 일으키고 의존성 관리에도 문제가 생겨 모듈화 구현에 힘들 수 있다.

// index.html

<script src="./module.js"></script>
<script src="./main.js"></script>
<script>
	getNumber(); // 20
</script>

// module.js

var num = 10;
function getNumber() {
	console.log(num);
}

// main.js

var num = 20;
function getNumber() {
	console.log(num);
}

Webpack을 왜 사용해야 해?

  • 모듈 번들링 Webpack에서는 Javascript 모듈뿐만 아니라 웹에서 사용하는 모든 자원(HTML, CSS, JS, Image, Font 등)들을 각각 하나의 모듈이라고 정의하며 웹 애플리케이션을 구동할 때마다 필요하는 자원들을 하나의 파일로 병합 및 압축해준다.
  • 웹 애플리케이션의 로딩 및 성능 향상
    • HTTP 요청 수 줄이기
      사용자가 특정 웹 사이트에 접근할 때 평균적으로 5초 이내에 화면으로 표시되지 않으면 사이트에서 벗어나거나 집중을 잃는다고 한다. 그래서, 개발자들은 웹 사이트 로딩 속도를 높일 수 있는 많은 방법 중 대표적인 서버로 요청하는 파일을 줄인다고 한다. 하지만, Webpack 같은 모듈 번들링을 이용하면 웹 사이트에 필요한 파일 수를 줄일 수 있다고 한다.

      참고로, 브라우저마다 한 번에 서버로 보낼 수 있는 HTTP 요청 숫자는 제약되어 있다고 하니 요청 수를 줄이는 것이 중요하다
  • Dynamic Loading & Lazy Loading 해결
       동적으로 다른 모듈을 사용하려면 라이브러리(Require.js)를 사용해야 했지만 Webpack에서 사용하고 있는 Code Spliting을 통해 원하는 모듈들을 원하는 순간에 로딩할 수 있다고 한다.

주요 속성

entry

웹 자원들을 변환하기 위해 필요한 최초 진입점이다. 쉽게 말해서, 웹 root시점의 자바스크립트 파일 경로를 설정하는 것이다. 그리고 지정된 자바스크립트 파일은 웹 애플리케이션에 필요한 모든 의존도들이 담겨져 있어야 Webpack이 모듈들의 관계도를 분석하고 빌드할 수 있다.

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

// index.js
import LoginView from './LoginView.js';
import HomeView from './HomeView.js';

const App = () => {
	LoginView.init();
	HomeView.init();
}

App();

output

entry를 빌드하고 나서 나온 결과물의 파일 경로를 지정하는 속성입니다. 속성 옵션들이 있어 상황에 맞게 옵션을 설정하고 결과 파일을 생성하면 된다.

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

// 해당 파일의 경로 기준으로 ./dist/bundle.js 결과물 출력
module.exports = {
	output: {
		filename: 'bundle.js',
		path: path.resolve(__dirname, './dist')
	}
}

// filename 옵션들
// name : entry 파일명
// id : 모듈 ID
// hash : 매 빌드시 붙이는 고유 해시 값
// chunkhash : 각 모듈 내용 기준으로 생성된 해시 값

module.exports = {
	output: {
		filename: '[name, id, hash, chunkhash].bundle.js'
	}
}

loader

웹 자원들 중 자바스크립트 파일이 아닌 HTML, CSS, 이미지, 폰트 등들을 변환할 수 있는 속성이다. 예를 들어 index.js 안에 css 파일을 import한 상태에서 webpack을 이용해 결과물을 출력하면 css 파일을 해석할 수 없기에 그에 대응하는 loader가 필요하다는 에러가 뜰 것이다.

// webpack.config.js
module.exports = {
	entry: './app.js',
	output: {
		filename: 'bundle.js'
	},
	// loader 부분
	// npm i css-loader -D를 실행한 후
	module: {
		rules: [
			{ test: /\.css$/, use: 'css-loader' },
			{ test: /\.ts$/, use: 'ts-loader' },
		]
	}
}

rules 배열 안에 test, use가 담긴 객체 한 쌍을 추가하여 원하는 loader를 사용할 수 있다.

  • test : loader를 적용할 파일 유형(일반적으로 정규 표현식 사용)
  • use : 해당 파일에 적용할 loader의 이름

필요한 loader들은 npm을 통해서 다운 받을 수 있고 종류도 다양하다. 그래서 babel, sass, file, vue, ts 등으로 속성에 등록하여 사용하기도 한다. 또한, 여러 개의 loader를 사용할 경우, 순서대로 적용하기 때문에 주의해야 한다.

plugin

Webpack의 기본 동작 이외에 추가적인 기능을 이용할 수 있게 하는 속성이다. 이것도 마찬가지로 npm을 통해서 설치 후 추가할 수 있고 loader랑 유사하지만 역할이 살짝 다르다. loader는 파일을 해석하고 변환하는 역할인 반면, plugin는 해당 결과물의 형태를 바꾸는 역할을 수행한다.

// webpack.config.js

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

module.exports = {
	plugins: [
		new HtmlWebpackPlugin(),     // Webpack으로 빌드한 결과물로 HTML 파일 생성
		new webpack.ProgressPlugin() // Webpack의 빌드 진행률을 표시
	]
}

아래와 같은 플러그인들이 자주 쓰인다고 한다.

그 외 속성들,

  • mode : 모드 설정, [’none’, ‘development’, ‘production’] 중으로 설정 가능, default 값은 ‘production’
  • resolve : import 사용 시에 대한 절대경로 설정을 custom할 수 있는 속성
  • devServer : Webpack Dev Server라는 도구를 사용할 때 적용할 속성, proxy 및 HMR(Hot Module Replacement) 설정 용도로 사용
  • devtool : 개발 모드에 대한 속성, 대표적으로 소스 맵을 이용해 디버깅에 도움이 되는 용도로 사용

처음부터 무작정 React 프로젝트를 이용할 때 당연하다고 생각하면서 개발했지만, 나중에 알게 된 것은 React도 Webpack을 포함한 상태로 빌드해주는 것이였다. 정확하게 말하면 CRA를 통해서 Webpack, Babel, ESLint 등 다양한 패키지를 포함한 상태에서 제공하기 때문에 우리가 React로 쉽게 웹 사이트를 개발할 수 있었다.

기업들은 꼭 CRA를 이용해서 개발하는 것도 아니였다. 이유는 기업에 제공하는 서비스별마다 개발 환경이 다르기 때문에 필요하지 않는 패키지들을 설치한 상태로 제공한다는 단점에 의해서 원하는 패키지들로 조합한 Boilerplate을 만들어 프로젝트를 구성한다.

참고자료

profile
개발자가 될 수 있을까?

0개의 댓글