로더 (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'})] : [])
]
}