로더 (Loader)
[ 설명 ]
[ 로더(loader) 란 ? ]
- 로더는 빌드 도구를 통한 빌드 과정에서 각 파일을
import 혹은 load할 때 모듈의 소스코드를 변형시키는 전처리 과정을 수행
Typescript 같은 다른 언어를 Javascript로 변환하고, image를 data url로 바꾸며, css파일의 import를 JS코드로 옮길 수 있음
webpack은 기본적으로 JS / JSON 파일만 이해할 수 있어서, other type의 파일을 convert 해줘야 한다
webpack은 모든 것을 하나의 모듈로 처리 (CSS파일, JS파일 등등)
webpack에서 로더의 적용은 배열 뒤 -> 앞 방향으로 적용한 순서대로 실행
- 번들링된 결과에
hash값을 붙이는 것은, 브라우저가 로컬 캐시로 이전 데이터를 바라보지 않게 하기 위함
- 빌드할 때
clean-webpack-plugin 플러그인을 통해 해시값이 바뀌면서 불필요하게 쌓이는 빌드 파일을 없앨 수 있다
- webpack concepts : https://webpack.js.org/concepts/#loaders
[ 자주 사용되는 로더 ]
css-loader
style-loader
file-loader / url-loader
- 둘 다
webpack5에서 Asset 파일을 처리하기 위해 내장된 모듈인 Asset Modules 에 기능이 통합됨
file-loader => type : asset/resource
url-loader => type : asset/inline
babel-loader
[ css-loader / style-loader ]
[ css-loader ]
JS파일 내부에서 css 파일을 불러오는 역할을 하는 로더
- 내부적으로 번들링된 js 파일에
string 값으로 css 데이터들이 존재하게 된다
style-loader와 함께 사용해서 실제 dom으로 추가해서 css가 반영한다
- 링크
[ style-loader ]
css-loader를 통해 웹팩 의존성 트리에 존재하게 되는 css 코드를 브라우저에 적용해주는 로더
- 내부적으로
<style> 태그를 통해 CSS를 DOM에 추가하는 원리
- 즉,
css-loader와 주로 함께 사용
- 링크
[ 적용 예시 ]
{
module: {
rules: [
{
test: /\.css$/,
use : [
'style-loader',
'css-loader'
]
}
]
}
}
[ file-loader / url-loader ]
[ file-loader ]
- 이미지 같은 파일(
file)을 가져오는 코드를 해석하고 로드하는 목적으로 사용
- 기본적으로 해당 파일도 번들 결과가 존재하는 output 경로에 복사
실제 코드에서 새롭게 복사된 경로인 output에 존재하는 파일을 참조할 수 있도록 publicPath 옵션을 지정해야 한다
webpack5에서 Asset Modules의 type : asset/resource 으로 사용 가능
[ url-loader ]
- 네트워크 리소스 없이 이미지 리소스를 사용하는 Data Url Scheme 적용을 자동화 해주는 로더
- 내부 로직 : 이미지를
base64 인코딩 + data url scheme 처리
- 주로
크기가 작은 이미지들을 대상으로 사용하면 적합 -> 크기가 큰 이미지는 오히려 부담;
limit 옵션을 통해 특정 크기 이하의 파일을 대상으로 정할 수 있다
limit을 초과하는 파일들에 대해서 기본적으로 file-loader를 이용해 지정한 output 경로에 파일을 생성
webpack5에서 Asset Modules의 type : asset/inline 으로 사용 가능
[ 적용 예시 - webpack 4 ]
{
module: {
rules: [
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
publicPath: './dist/',
name: '[name].[ext]?[hash]'
}
},
{
test: /\.(png|jpg|gif|svg)/,
loader: 'url-loader',
options: {
publicPath: './dist/',
name: '[name].[ext]?[hash]',
limit: 20000,
}
}
]
}
}
[ 적용 예시 - webpack 5 ]
{
output: {
filename: "[name].js",
path: path.resolve("./dist"),
assetModuleFilename: "images/[name][ext]",
},
module: {
rules: [
{
test: /\.(png)/,
type: "asset/resource",
},
{
test: /\.(jpg)/,
type: "asset/resource",
generator: {
filename: "static/[name][ext]",
},
},
{
test: /\.(svg)/,
type: "asset/inline",
},
]
}
}
플러그인 (Plugin)
[ 설명 ]
[ 플러그인(Plugin) 이란 ? ]
Loader가 파일 단위로 처리하는 반면, Plugin은 번들링된 결과물을 처리
Loader는 함수로 정의하지만, Plugin은 클래스로 정의
Plugin은 bundle optimization / asset management / injection of environment 등으로 활용 가능
webpack concepts : https://webpack.js.org/concepts/#plugins
- 자주 사용하는 플러그인
BannerPlugin
DefinePlugin
HtmlTemplatePlugin
CleanWebpackPlugin
MiniCssExtractPlugin
[ BannerPlugin ]
[ 설명 ]
[ 적용 예시 ]
{
plugins: [
new webpack.BannerPlugin({
banner: `
Build Date : ${new Date().toLocaleString()}
Commit version : ${childProcess.execSync('git rev-parse --short HEAD')}
Author : ${childProcess.execSync('git config user.name')}
`
})
]
}
... bundle js code
[ DefinePlugin ]
[ 설명 ]
compile time에 코드에 있는 특정 변수를 다른 값이나 표현으로 바꿀 수 있다
phase 환경 마다 상이한 정보들을 관리할 때 유용한 플러그인
- 생성시 빈 객채를 전달해도 기본적으로
process.env.NODE_ENV 값은 넣어준다
process.env.NODE_ENV = 'production'
process.env.NODE_ENV = 'development'
webpack v4부터는 mode를 설정하면 자동으로 DefinePlugin을 통해 process.env.NODE_ENV 값을 세팅한다
(webpack.config.js의 mode 값을 바라본다)
+ mode: 'development'
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
+ mode: 'production',
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
[ 적용 예시 ]
{
plugins: [
new webpack.DefinePlugin({
data: JSON.stringify('3+4'),
api_domain: JSON.stringify('https://dev.api.domain.com')
})
]
}
[ HtmlTemplatePlugin ]
[ 설명 ]
bundle을 제공하기 위해 HTML 파일 생성을 단순화하는 third party 플러그인
template으로 지정한 html에 번들링 된 JS, CSS파일을 자동으로 넣어준다
- 링크
[ 적용 예시 ]
{
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(개발용)' : ''
},
minify: process.env.NODE_ENV === 'production' ? {
collapseWhitespace: true,
removeComments: true,
} : false
})
]
}
[ CleanWebpackPlugin ]
[ 설명 ]
이전 빌드 결과물을 삭제해주는 third party 플러그인
- 링크
[ 적용 예시 ]
{
plugins: [
new CleanWebpackPlugin()
]
}
[ 설명 ]
bundle된 JS코드 내부에 string으로 들어간 CSS코드를 추출해 별도의 파일로 분리해주는 third party 플러그인
- JS 내부에 삽입되는
CSS 스타일 시트의 크기가 큰 경우 불러오는 데 오래 걸릴 수 있기에 분리해주는 것이 좋다
- 주의 :
style-loader 대신 별도로 제공하는 MiniCssExtractPlugin.loader 를 사용해야 한다
webpack guide : https://webpack.js.org/plugins/mini-css-extract-plugin
[ 적용 예시 ]
{
module: {
rules: [
{
test: /\.css$/,
use: [
process.env.NODE_ENV === "production"
? MiniCssExtractPlugin.loader
: "style-loader",
"css-loader",
],
},
]
},
plugins: [
...(process.env.NODE_ENV === 'production' ? [new MiniCssExtractPlugin({filename: '[name].css'})] : [])
]
}