Webpack의 기본 개념
Webpack은 핵심 개념 4가지만 알면 설정 파일 읽는 게 어렵지 않다.
Webpack을 왜 쓰는가
예전에는 HTML에 <script> 태그를 여러 개 넣어서 JavaScript를 로드했다. 파일이 많아지면 순서도 신경 써야 하고, 네트워크 요청도 많아지고, 전역 변수 충돌 문제도 생겼다.
Webpack은 여러 파일을 하나로 묶어주고, 의존성도 알아서 관리해준다. 거기에 Babel로 최신 문법 변환하거나, CSS 번들링까지 다 처리할 수 있다.
핵심 개념 4가지
Entry
번들링의 시작점이다. 여기서부터 import를 따라가면서 의존성 그래프를 만든다.
// webpack.config.js
module.exports = {
entry: './src/index.js'
};
멀티 페이지 앱이면 여러 개 지정할 수도 있다.
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js'
}
};
Output
번들 결과물을 어디에 뱉을지 정한다.
const path = require('path');
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
};
entry가 여러 개면 [name]으로 동적 파일명을 줄 수 있다.
output: {
filename: '[name].bundle.js' // app.bundle.js, admin.bundle.js
}
Loader
Webpack은 기본적으로 JS랑 JSON만 읽을 줄 안다. CSS나 이미지, TypeScript 같은 건 Loader가 처리한다.
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
}
};
use 배열은 오른쪽에서 왼쪽으로 실행된다. 위 예시에서 CSS 파일은 css-loader가 먼저 처리하고, 그 결과를 style-loader가 DOM에 주입한다.
자주 쓰는 것들:
babel-loader- ES6+ → ES5 변환 (preset-env 참고)css-loader- CSS를 JS 모듈로style-loader- CSS를 DOM에 주입ts-loader- TypeScript 컴파일
Plugin
Loader가 파일 단위 변환이라면, Plugin은 번들 전체에 대한 작업을 한다. HTML 생성, CSS 추출, 환경변수 주입 같은 것들.
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
HtmlWebpackPlugin은 거의 필수로 쓴다. 번들 파일명에 해시가 붙으면 HTML에서 일일이 수정하기 귀찮은데, 이걸 자동으로 해준다.
실제 설정 예시
프로젝트 시작할 때 복붙해서 쓰는 기본 설정이다.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset/resource'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
devServer: {
hot: true,
port: 3000
}
};
mode는 development랑 production 두 가지가 있는데, production으로 하면 자동으로 압축이랑 트리 쉐이킹이 적용된다. 개발할 때는 development로 해야 빌드가 빠르고 소스맵도 제대로 나온다.
개발 서버
webpack-dev-server 쓰면 파일 저장할 때마다 자동으로 새로고침된다.
npm install webpack-dev-server -D
{
"scripts": {
"dev": "webpack serve",
"build": "webpack --mode production"
}
}
Hot Module Replacement(HMR) 켜두면 페이지 새로고침 없이 변경된 모듈만 교체해준다. React 개발할 때 상태 날아가지 않아서 편하다.
마무리
정리하면:
- Entry: 시작점
- Output: 결과물 위치
- Loader: JS 외 파일 처리
- Plugin: 번들 전체에 대한 작업
이 4가지만 알면 Webpack 설정 읽는 게 어렵지 않다. 나머지는 필요할 때 찾아보면 된다.