npm install -D webpack@4
npm install -D webpack-cli@3
npm install -D css-loader@3
npm install -D file-loader@5
npm install -D style-loader@1
npm install -D url-loader@3
npm install -D html-webpack-plugin@3
npm install -D mini-css-extract-plugin@0
npm install -D optimize-css-assets-webpack-plugin@5
웹팩
은 오픈소스 자바스크립트 모듈 번들러로 ECMAScript2015 모듈시스템을 쉽게 사용하도록 돕는 역할을 한다.
모듈 번들러
웹 애플리케이션을 구성하는 자원(HTML, CSS, JavaScript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 결과물을 만드는 도구를 의미한다.
하나의 시작점으로부터 의존적인 모듈을 전부 찾아내서 하나의 결과물을 만들어 낸다.
--mode
: 웹팩 실행 모드--entry
: 시작점 경로--output
: 번들링 결과물 경로const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js',
},
output: {
path: path.resolve('./dist'),
filename: '[name].js',
},
};
{
'script': {
'build': './node_modules/.bin/webpack'
}
}
$ npm run build
this[kHandle] = new _Hash(algorithm, xofLen);
에러 해결 방법$ export NODE_OPTIONS=--openssl-lagacy-provider
로더는 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해 주거나 이미지를 data URL 형식의 문자열로 반환해줍니다. 뿐만 아니라 CSS 파일을 자바스크립트에서 직접 로딩할 수 있도록 해줍니다.
css-loader
, style-loader
)css-loader
를 이용해서 CSS 파일을 모듈처럼 볼러와 사용하고 style-loader
를 통해 모듈로 변경된 스타일 시트를 돔에 추가합니다.
// webpack.config.js
module.exports = {
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader'], // style-loader를 앞에 추가!!
}]
}
}
배열을 설정하면 뒤에서부터 앞의 순서대로 로더가 동작하기 때문에 css-loader
, style-loader
순으로 적용할 수 있도록 설정합니다.
file-loader
)file-loader
를 통해 소스코드에서 사용하는 모든 파일을 모듈로 사용하게끔 할 수 있습니다.
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg)/,
loader: 'file-loader',
options: {
publicPath: './dist/', // prefix를 아웃풋 경로로 지정
name: '[name].[ext]?[hash]', // 파일명 형식
}
}
]
}
}
publicPath
: file-loader
가 처리하는 파일을 모듈로 사용할 때 경로 앞에 추가되는 문자열입니다.name
: 로더가 파일을 아웃풋에 복사할 때 사용하는 파일 이름입니다.url-loader
)url-loader
는 Data URL Scheme을 이용할 수 있도록 이미지를 Base64로 인코딩하여 문자열 형태로 소스코드에 넣어줍니다.
Data URL Scheme
data:
스킴이 접두어로 붙은 URL로 작은 파일을 문서 내에 인라인으로 임베드하기 위한 URL 스킴입니다. 주로 아이콘 등의 작은 이미지 파일에 사용됩니다.
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: \/.png$\,
use: {
loader: 'url-loader',
options: {
publicPath: './dist/',
name: '[name].[ext]?[hash]',
limit: 5000 // 5kb 미만 파일만 data url로 처리
}
}
}
]
}
}
로더가 파일 단위로 처리하는 반면 플러그인은 번들된 결과물을 처리합니다. 번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용합니다.
BannerPlugin
)BannerPlugin
을 통해 번들된 결과물에 빌드 정보나 커밋 버전같은 걸 추가할 수 있습니다. 배너 정보가 많다면 별도 파일로 분리하는 것을 권장합니다.
// banner.js
const childProcess = require('child_process')
module.exports = function banner() {
const commit = childProcess.execSync('git rev-parse --short HEAD')
const user = childProcess.execSync('git config user.name')
const date = new Date().toLocaleString()
return (
`commitVersion: ${commit}\n Build Date: ${data}\n Author: ${user}`
)
}
// webpack.config.js
const webpack = require('webpack')
const banner = require('./banner.js')
module.exports = {
plugins: [
new webpack.BannerPlugin(banner)
]
}
DefinePlugi
)애플리케이션은 개발환경과 운영환경으로 나눠서 운영합니다. 환경에 따라 API 서버 주소가 다를 수 있습니다. 같은 소스 코드를 두 환경에 배포하기 위해서는 이러한 환경 의존적인 정보를 소스가 아닌 곳에서 관리하는 것이 좋습니다. 웹팩은 이러한 환경 정보를 제공하기 위해 DefinePlugin
을 제공합니다.
// webpack.config.js
const webpack = require('webpack')
export default {
plugins: [new webpack.DefinePlugin({
VERSION: JSON.stringify('v.1.2.3'),
PRODUCTION: JSON.stringify(false),
MAX_COUNT: JSON.stringify(999),
'api.domain': JSON.stringify('http://dev.api.domain.com'),
})],
}
HtmlWebpackPlugin
)HtmlWebpackPlugin
은 HTML 파일을 후처리하는데 사용합니다. 빌드 타임의 값을 넣거나 코드를 압축할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<title>타이틀<%= env %></title>
</head>
<body>
</body>
</html>
타이틀 부분에 ejs 문법을 이용해서 env
변수 값을 출력하려고 합니다. HtmlWebpackPlugin
은 이 변수에 데이터를 주입시켜 동적으로 HTML 코드를 생성합니다.
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 템플릿 경로 지정
templateParameters: { // 템플릿에 주입할 파라미터 변수 지정
env: prosecc.env.NODE_ENV === 'development' ? '(개발용)': '',
},
minify: process.env.NODE_ENV === 'production' ? {
collapseWhitespace: true, // 빈칸 제거
removeComments: true, // 주석 제거
} : false,
})
]
}
CleanWebpackPlugin
)CleanWebpackPlugin
을 통해 빌드 이전 결과물을 제거할 수 있습니다.
// webpack.config.js
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
plugins: [new CleanWebpackPlugin()],
}
MiniCssExtractPlugin
)스타일시트가 점점 많아지면 하나의 자바스크립트 결과물로 만드는 것이 부담일 수 있다. 번들 결과에서 스타일시트 코드만 뽑아서 별도의 CSS 파일로 만들어 역할에 따라 파일을 분리하는 것이 좋다. 브라우저에서 큰 파일 하나를 내려받는 것보다 여러 개의 작은 파일을 동시에 다운로드하는 것이 빠르다.
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
plugins: [
...(process.env.NODE_ENV === 'production'
? [new MiniCssExtractPlugin({ filename: `[name].css]`})
: []),
]
}