webpack을 사용하던 중 다양한 로더와 플러그인의 역할과 기능에 대해 학습하고자 작성하게 되었다.
▶loader와 plugin의 차이
로더는 파일을 해석하고 변환하는 과정에 관여하는 반면, 플러그인은 해당 결과물의 형태를 바꾸는 역할(기본적인 동작에 추가적인 기능을 제공하는 속성)이다.
▶로더(loader)란?
- 로더는 빌드 도구를 통한 빌드 과정에서 각 파일을 import 혹은 load할 때 모듈의 소스코드를 변형시키는 전처리 과정을 수행
- webpack은 기본적으로 JS / JSON 파일만 이해할 수 있어서, other type의 파일을 convert 해줘야 한다
▶자주 사용하는 로더 종류
- css-loader : css 파일이 js 코드로 변경, 즉 JS파일 내부에서 css파일을 불러오는 역할(내부적으로 번들링된 js파일에 string값으로 css데이터가 존재하게 됨)
- style-loader : js로 변경된 css 내용을 동적으로 DOM에 추가(브라우저가 해석하기 위해, 내부적으로 태그를 사용합니다), 따라서 css를 번들링하기 위해서는 css-loader, style-loader를 함께 사용함
- file-loader : 파일을 모듈 형태로 지원, webpack output에 파일을 옮겨줌
- url-loader : data URI scheme를 이용하여 이미지를 Base64로 인코딩하여 문자열 형태로 소스코드에 넣는 처리를 자동화하는 loader(사용하는 이미지 개수가 많으면 네트워크의 자원을 사용하는 부담이 크고, 성능에 영향을 주기때문에 사용한다.)
▶css 파일을 webpack에서 사용하기
css or scss 파일 생성
/css/main.scss
body{ background-color: yellow; }
main.js
import '../css/main.scss // css적용만을 위해 이름 적용x`
main.js위와 같이 css or scss파일을 main.js파일에 import하여 사용할 수 있도록 도와주는 역할은 loader가 담당합니다.
module: {
rules: [{
test: /\.s?css$/,
use: [ // 뒤(sass-loader)에서부터 실행된다 && 모듈로 변경된 css를 js로 읽게함
'style-loader',
'css-loader',
'sass-loader'
],
}
]},
// test : 로더를 적용할 파일 유형
// use : 해당 파일에 적용할 로더의 이름
위의 설정으로 해당 프로젝트의 모든 css파일에 대해서 css-loader를 적용하겠다는 의미입니다.
webpack에서 로더의 적용은 배열 뒤 -> 앞 방향으로 적용한 순서대로 실행하므로 css와 scss loader를 먼저 적용한 후 style-loader를 맨 앞에 배치해 dom에 적용될 수 있도록 설정해야 합니다.
▶플러그인(plugin)이란?
- Loader가 파일 단위로 처리하는 반면, Plugin은 번들링 이후의 결과물을 처리
- Loader는 함수로 정의하지만, Plugin은 클래스로 정의
자주 사용하는 플러그인 종류
- BannerPlugin : 결과물에 build info나 commit version 같은 정보를 추가할 수 있는 플러그인(webpack의 기본 plugin)
예시
/* webpack.config.js */
{
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 - 결과물 */
/*!
*
* Build Date : 3/30/2022, 19:52:09 PM
* Commit version : ca82fa1
*
* Author : hue
*/
... bundle js code
- DefinePlugin : compile time에 코드에 있는 특정 변수를 다른 값이나 표현으로 바꿀 수 있다
- phase 환경 마다 상이한 정보들을 관리할 때 유용
- 생성시 빈 객채를 전달해도 기본적으로 process.env.NODE_ENV 값은 넣어준다
- process.env.NODE_ENV = 'production'
- process.env.NODE_ENV = 'development'
- (webpack.config.js의 mode 값을 바라본다)
- webpack의 기본 plugin
예시
// 컴파일 모드에 따라 자동 주입되는 설정이 다르다.
// mode=development
mode: 'development'
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), // 자동 주입
// mode=production
mode: 'production',
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), // 자동 주입
// 적용 예시
/* webpack.config.js */
{
plugins: [
new webpack.DefinePlugin({
/* 웹팩의 빌드타임에서 사용가능한 전역 변수로 등록이 된다
=> 런타임에서는 접근이 불가, 하지만 빌드 타임에 전역으로 선언되어 전역 scope를 더럽힐 수 있음
=> 조심해서 사용
*/
data: JSON.stringify('3+4'),
api_domain: JSON.stringify('https://dev.api.domain.com')
})
]
}
- HtmlTemplatePlugin
- bundle을 제공하기 위해 HTML 파일 생성을 단순화하는 third party 플러그인
- template으로 지정한 html에 번들링 된 JS, CSS파일을 자동으로 넣어준다
예시
/* webpack.config.js */
{
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
// template 내부에서 ejs문법으로 지정된 변수에 값 매핑
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(개발용)' : ''
},
// 생성되는 HTML template를 최소화 하는 옵션
minify: process.env.NODE_ENV === 'production' ? {
collapseWhitespace: true, // 공백 제거
removeComments: true, // 주석 제거
} : false
})
]
}
- webpack에서 생성된 번들을 자동으로 import하는 HTML파일을 생성, 매 빌드마다 bundle의 이름을 바꾸게된다면 HTML파일도 변경해주어야 하므로
- 이것을 통해 HTML파일 생성
- 개발자가 만든 index.html(template)을 참고하여 webpack에서 생성할 수 있도록 도와줌
- CleanWebpackPlugin
- 이전 빌드 결과물을 삭제해주는 third party 플러그인
- MiniCssExtractPlugin
- bundle된 JS코드 내부에 string으로 들어간 CSS코드를 추출해 별도의 파일로 분리해주는 third party 플러그인
- JS 내부에 삽입되는 CSS 스타일 시트의 크기가 큰 경우 불러오는 데 오래 걸릴 수 있기에 분리해주는 것이 좋다
- 배포시 사용하면 유용한 플러그인이다.
예시
/* webpack.config.js */
{
module: {
rules: [
{
test: /\.css$/,
use: [
/* prod phase에서만 MiniCssExtractPlugin.loader 적용 */
process.env.NODE_ENV === "production"
? MiniCssExtractPlugin.loader
: "style-loader",
"css-loader",
],
},
]
},
plugins: [
// prod phase에서만 css파일을 분리해서 js에 적용하도록 설정
...(process.env.NODE_ENV === 'production' ? [new MiniCssExtractPlugin({filename: '[name].css'})] : [])
]
}
tip
- resolve는 절대경로, join은 상대경로를 나타낸다.
path: path.resolve(__dirname, 'dist') path: path.join(\_\_dirname, 'dist')
'REACT' 카테고리의 다른 글
리액트 훅 (0) | 2022.05.30 |
---|---|
PostCSS (0) | 2022.04.10 |
npx란?? (0) | 2022.03.30 |
State and Lifecycle (0) | 2022.03.28 |
webpack 정리 (0) | 2022.03.17 |