로더는 특정 유형의 모듈을 변환되는데에 사용되지만 (이미지 파일이나 txt파일들을 변환),
플러그인은 번들을 최적화 하거나 에셋을 관리하고 환경 변수 주입 등 광범위한 작업에 사용된다.
로더에서는 설정해놓은 확장자 파일 전부에 로더 함수가 실행이 되지만,
플러그인 같은 경우엔 번들 자체에 한번 적용되는 것이다 .
class MyWebpackPlugin {
apply(compiler) {
compiler.hooks.done.tap("My Plugin", (stats) => {
console.log("MyPlugin : done");
});
}
}
module.exports = MyWebpackPlugin;
const path = require("path");
const MyWebpackPlugin = require("./my-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[hash][ext][query]",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(jpeg|jpg|gif|svg)$/,
type: "asset/resource",
},
{
test: /\.png/,
type: "asset/inline",
},
],
plugins: [new MyWebpackPlugin()], // 플러그인 불러오기
};
빌드해보면 콘솔창이 딱 한번만 나타나는 것을 확인 할 수 있다 .
const path = require("path");
const webpack = require("webpack");
const childProcess = require("child_process");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[hash][ext][query]",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(jpeg|jpg|gif|svg)$/,
type: "asset/resource",
},
{
test: /\.png/,
type: "asset/inline",
},
],
},
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")}
`,
}),
],
};
webpack 내에 내장되어있는 플러그인이다.
설정후 빌드를 하면 빌드된 main.js 1번 라인에 저렇게 플러그인에서 설정된 문구가 나온다.
어플리케이션을 개발할때, 개발환경과 배포환경을 다르게 해서 개발을 진행하는데,
DefinePlugin 을 사용해서 각각 환경에 맞는 전역 상수를 지정해줄 수있다.
const path = require("path");
const webpack = require("webpack");
const childProcess = require("child_process");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[hash][ext][query]",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(jpeg|jpg|gif|svg)$/,
type: "asset/resource",
},
{
test: /\.png/,
type: "asset/inline",
},
],
},
plugins: [
new webpack.DefinePlugin({}) //빈 객체를 전달해도 기본적으로 mode로 설정한 값을 넣어줌,
//process.env.NODE_ENV로 접근가능
],
};
HtmlWebpackPlugin을 사용하면 빌드시에 모든 script를 포함하는 html로 번들링을 해준다
const path = require("path");
const webpack = require("webpack");
const childProcess = require("child_process");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[hash][ext][query]",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(jpeg|jpg|gif|svg)$/,
type: "asset/resource",
},
{
test: /\.png/,
type: "asset/inline",
},
],
},
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")}
`,
}),
new webpack.DefinePlugin({}),
new HtmlWebpackPlugin({
template: "./src/index.html", // src폴더 안에 있는 index.html 을 번들링 해주겠다
}),
],
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
</head>
<body></body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
<script defer src="main.js"></script></head>
<body></body>
</html>
dist 폴더에 index.html 파일이 생기고, 그 안에 자동으로 빌드된 main.js파일이 주입되었다.