Webpack - 로더(Loader) & 플러그인(Plugin)
로더 (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가 반영한다
- 링크
webpack guide : https://webpack.js.org/loaders/css-loader/
npm package : https://www.npmjs.com/package/css-loader
github : https://github.com/webpack-contrib/css-loader
[ style-loader ]
css-loader를 통해 웹팩 의존성 트리에 존재하게 되는 css 코드를 브라우저에 적용해주는 로더
- 내부적으로
<style> 태그를 통해 CSS를 DOM에 추가하는 원리
- 즉,
css-loader와 주로 함께 사용
- 링크
webpack guide : https://webpack.js.org/loaders/style-loader/
npm package : https://www.npmjs.com/package/style-loader
github : https://github.com/webpack-contrib/style-loader
[ 적용 예시 ]
/* webpack.config.js */
{
module: {
rules: [
/* css-loader + style-loader
css-loader => style-loader 순서로 실행 */
{
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 ]
/* webpack.config.js */
{
module: {
rules: [
/* file-loader */
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
// 파일을 사용할 때 로더에 의해 경로가 바뀔수 있어서 사용측의 기본 사용 path 지정
publicPath: './dist/',
// [원본파일].[확장자]?[해시값] -> 브라우저 로컬 캐시 무력화를 위해 캐시값 지정
name: '[name].[ext]?[hash]'
}
},
/* url-loader */
{
test: /\.(png|jpg|gif|svg)/,
loader: 'url-loader',
options: {
publicPath: './dist/',
name: '[name].[ext]?[hash]',
// 20kb 보다 작은 파일만 url-loader 적용
limit: 20000, // 20kb
}
}
]
}
}
[ 적용 예시 - webpack 5 ]
webpack5 Asset Modules : https://webpack.js.org/guides/asset-modules/
/* webpack.config.js */
{
output: {
filename: "[name].js",
path: path.resolve("./dist"),
assetModuleFilename: "images/[name][ext]", // asset/resource 와 /asset 에서만 적용
},
module: {
rules: [
/* png 파일을 assetModuleFilename 지정한 경로와 형식으로 결과물 생성 */
{
test: /\.(png)/,
type: "asset/resource", // default 생성 파일 이름 : [hash][ext][query]
},
/* jpg 파일을 generator > filename 을 통해 custom한 경로와 형식으로 결과물 생성 */
{
test: /\.(jpg)/,
type: "asset/resource",
generator: {
filename: "static/[name][ext]", // 생성 파일 이름 custom
},
},
/* svg 파일을 data url scheme로 js 코드 내에 인라인으로 삽입 */
{
test: /\.(svg)/,
type: "asset/inline",
},
]
}
}
/*
├── images
│ └── times-circle.png
├── index.html
├── main.js
└── static
└── default-image.jpg
*/
플러그인 (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 ]
[ 설명 ]
- 결과물에
build info나 commit version 같은 정보를 추가할 수 있는 플러그인
webpack의 기본 plugin
webpack guide : https://webpack.js.org/plugins/banner-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/20/2022, 11: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 값을 바라본다)
// 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의 기본 plugin
webpack guide : https://webpack.js.org/plugins/define-plugin/
[ 적용 예시 ]
/* 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({
// JS 파일을 넣을 html template 지정
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
})
]
}
[ CleanWebpackPlugin ]
[ 설명 ]
이전 빌드 결과물을 삭제해주는 third party 플러그인
- 링크
[ 적용 예시 ]
/* webpack.config.js */
{
plugins: [
new CleanWebpackPlugin()
]
}
[ MiniCssExtractPlugin ]
[ 설명 ]
bundle된 JS코드 내부에 string으로 들어간 CSS코드를 추출해 별도의 파일로 분리해주는 third party 플러그인
- JS 내부에 삽입되는
CSS 스타일 시트의 크기가 큰 경우 불러오는 데 오래 걸릴 수 있기에 분리해주는 것이 좋다
- 주의 :
style-loader 대신 별도로 제공하는 MiniCssExtractPlugin.loader 를 사용해야 한다
webpack guide : https://webpack.js.org/plugins/mini-css-extract-plugin
[ 적용 예시 ]
/* 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'})] : [])
]
}
Author And Source
이 문제에 관하여(Webpack - 로더(Loader) & 플러그인(Plugin)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@neity16/Webpack-로더Loader-플러그인Plugin
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
[ 로더(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-loaderstyle-loaderfile-loader/url-loader- 둘 다
webpack5에서 Asset 파일을 처리하기 위해 내장된 모듈인Asset Modules에 기능이 통합됨 file-loader=>type : asset/resourceurl-loader=>type : asset/inline
- 둘 다
babel-loader
[ css-loader ]
JS파일 내부에서css 파일을 불러오는 역할을 하는 로더- 내부적으로 번들링된 js 파일에
string 값으로css 데이터들이 존재하게 된다 style-loader와 함께 사용해서실제 dom으로 추가해서css가 반영한다- 링크
webpack guide: https://webpack.js.org/loaders/css-loader/npm package: https://www.npmjs.com/package/css-loadergithub: https://github.com/webpack-contrib/css-loader
[ style-loader ]
css-loader를 통해웹팩 의존성 트리에 존재하게 되는css 코드를브라우저에 적용해주는 로더- 내부적으로
<style>태그를 통해CSS를DOM에 추가하는 원리 - 즉,
css-loader와 주로 함께 사용 - 링크
webpack guide: https://webpack.js.org/loaders/style-loader/npm package: https://www.npmjs.com/package/style-loadergithub: https://github.com/webpack-contrib/style-loader
[ 적용 예시 ]
/* webpack.config.js */
{
module: {
rules: [
/* css-loader + style-loader
css-loader => style-loader 순서로 실행 */
{
test: /\.css$/,
use : [
'style-loader',
'css-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 ]
/* webpack.config.js */
{
module: {
rules: [
/* file-loader */
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
// 파일을 사용할 때 로더에 의해 경로가 바뀔수 있어서 사용측의 기본 사용 path 지정
publicPath: './dist/',
// [원본파일].[확장자]?[해시값] -> 브라우저 로컬 캐시 무력화를 위해 캐시값 지정
name: '[name].[ext]?[hash]'
}
},
/* url-loader */
{
test: /\.(png|jpg|gif|svg)/,
loader: 'url-loader',
options: {
publicPath: './dist/',
name: '[name].[ext]?[hash]',
// 20kb 보다 작은 파일만 url-loader 적용
limit: 20000, // 20kb
}
}
]
}
}
[ 적용 예시 - webpack 5 ]
webpack5 Asset Modules: https://webpack.js.org/guides/asset-modules/
/* webpack.config.js */
{
output: {
filename: "[name].js",
path: path.resolve("./dist"),
assetModuleFilename: "images/[name][ext]", // asset/resource 와 /asset 에서만 적용
},
module: {
rules: [
/* png 파일을 assetModuleFilename 지정한 경로와 형식으로 결과물 생성 */
{
test: /\.(png)/,
type: "asset/resource", // default 생성 파일 이름 : [hash][ext][query]
},
/* jpg 파일을 generator > filename 을 통해 custom한 경로와 형식으로 결과물 생성 */
{
test: /\.(jpg)/,
type: "asset/resource",
generator: {
filename: "static/[name][ext]", // 생성 파일 이름 custom
},
},
/* svg 파일을 data url scheme로 js 코드 내에 인라인으로 삽입 */
{
test: /\.(svg)/,
type: "asset/inline",
},
]
}
}
/*
├── images
│ └── times-circle.png
├── index.html
├── main.js
└── static
└── default-image.jpg
*/
[ 설명 ]
[ 플러그인(Plugin) 이란 ? ]
Loader가파일 단위로 처리하는 반면,Plugin은번들링된 결과물을 처리Loader는함수로 정의하지만,Plugin은클래스로 정의Plugin은bundle optimization/asset management/injection of environment등으로 활용 가능webpack concepts: https://webpack.js.org/concepts/#plugins
- 자주 사용하는 플러그인
BannerPluginDefinePluginHtmlTemplatePluginCleanWebpackPluginMiniCssExtractPlugin
[ BannerPlugin ]
[ 설명 ]
- 결과물에
build info나commit version같은 정보를 추가할 수 있는 플러그인webpack의 기본 pluginwebpack guide: https://webpack.js.org/plugins/banner-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/20/2022, 11: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값을 바라본다)// 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의 기본 pluginwebpack guide: https://webpack.js.org/plugins/define-plugin/
[ 적용 예시 ]
/* 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({ // JS 파일을 넣을 html template 지정 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 }) ] }
[ CleanWebpackPlugin ]
[ 설명 ]
이전 빌드 결과물을삭제해주는third party 플러그인- 링크
[ 적용 예시 ]
/* webpack.config.js */ { plugins: [ new CleanWebpackPlugin() ] }
[ MiniCssExtractPlugin ]
[ 설명 ]
bundle된JS코드내부에string으로 들어간 CSS코드를추출해별도의 파일로 분리해주는third party 플러그인- JS 내부에 삽입되는
CSS 스타일 시트의 크기가 큰 경우 불러오는 데 오래 걸릴 수 있기에분리해주는 것이 좋다- 주의 :
style-loader대신 별도로 제공하는MiniCssExtractPlugin.loader를 사용해야 한다webpack guide: https://webpack.js.org/plugins/mini-css-extract-plugin
[ 적용 예시 ]
/* 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'})] : []) ] }
Author And Source
이 문제에 관하여(Webpack - 로더(Loader) & 플러그인(Plugin)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@neity16/Webpack-로더Loader-플러그인Plugin저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)