๐งWebpack : ์์ฃผ ์ฌ์ฉ๋๋ Plugin
์ด๋ฒ ํฌ์คํ ์์๋ ์์ฃผ ์ฌ์ฉ๋๋ ํ๋ฌ๊ทธ์ธ์ ๊ดํด ์ดํด ๋ณผ ๊ฒ์ด๋ค. ์์ฃผ ์ฌ์ฉ๋๋ ๋ํ์ ํ๋ฌ๊ทธ์ธ 5๊ฐ์ง๋ฅผ ์ดํด ๋ณผ ๊ฒ์ด๋ค.
BannerPlugin
์ด์ ํฌ์คํ ์์ ์ฐ๋ฆฌ๊ฐ BannerPlugin์ ๋ชจ์ฌํ๋ค. ์ด ํ๋ฌ๊ทธ์ธ์ webpack์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต์ ํด์ฃผ๋ ํ๋ฌ๊ทธ์ธ์ด๋ค. BannerPlugin์ ๊ฒฐ๊ณผ๋ฌผ์ ๋น๋ ์ ๋ณด๋ ์ปค๋ฐ ๋ฒ์ ๊ฐ์ ๊ฒ์ ์ถ๊ฐ ํ ์ ์๋ค. ์ด๋ฅผ webpack.config์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
//webpack.config.js
const path = require('path');
const MyWebpackPlugin = require('./my-webpack-plugin');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
main: './src/app.js'
},
/* -- ์ค๊ฐ ์๋ต -- */
plugins: [
new CleanWebpackPlugin(), // ๋น๋ ์ ์ dist ํด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
new webpack.BannerPlugin({
banner: '์ด๊ฒ์ Banner ์
๋๋ค.'
})
],
}
์ด๋ฒ์๋ ์์ฑ๋ ์๊ฐ๊ณผ ๊น ์ปค๋ฐ log ๋ฒํธ ๊ทธ๋ฆฌ๊ณ ์์ฑ์ ์ ๋ณด๋ฅผ ๋ฃ์ด ๋ณด์.
::cmd
git rev-parse --short HEAD
::a7cec5b
git config user.name
::4Bee
๊น ์ปค๋ฐ log ๋ฒํธ๋ git log์ ๊ฐ์ด ํ์ธ์ ํ ์๋ ์์ง๋ง ๋๋ฌด๊ธธ๊ธฐ ๋๋ฌธ์ ์๋์๊ฐ์ ๋ช ๋ น์ด๋ฅผ ์คํํด์ ๋จ์ถ๋ log๋ฒํธ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ์ด๋ ๊ฒ git์ ํตํด์ ํ๋ํ๋ ๋งค๋ฒ ์ ๋ณด๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ ๋ ฅํด์ ๋ฃ์ด ์ค ์ ์๋ค. ๊ทธ๋์ ์ด๋ฅผ ์๋ํ ํ๋ ๋ฐฉ๋ฒ์ด ์๋๋ฐ ๊ทธ๊ฒ์ node-modules์์ ์ ๊ณตํด์ฃผ๋ childProcess๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์๋ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์.
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
/* -- ์ค๊ฐ ์๋ต -- */
plugins: [
new CleanWebpackPlugin(), // ๋น๋ ์ ์ dist ํด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
new webpack.BannerPlugin({
banner: `
Build Date: ${new Date().toLocaleDateString()}
Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
Author: ${childProcess.execSync('git config user.name')}
`
})
],
}
์ด๋ ๊ฒ childProcess๋ฅผ ์ฌ์ฉํด์ git ๋ช ๋ น์ด๋ฅผ build๊ฐ ๋๋ ๊ณผ์ ์ execSync๋ก ์คํ์ํค๊ฒ ๋ง๋ค๋ฉด ๋๋ค. ์ด์ build๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ์ด ๋ฐฐ๋์ ์ถ๊ฐ๊ฐ๋๋ ๊ฒ์ ์ ์ ์๋ค.
/*dist/main.js*/
/*!
*
* Build Date: 2024. 8. 23.
* Commit Version: a7cec5b
*
* Author: 4Bee
*
*
*/
๋ง์น ์ฐ๋ฆฌ๊ฐ ๋ธ๋ผ์ฐ์ ์ console์ ํตํ log๋ฅผ ํ์ธํ๋ ์ฉ๋์ ์ ์ฌํ๋ค. ์ ํ์์ ํ๋ฉด ๋งค์ฐ ์ ์ฉํ ๊ฒ ๊ฐ๋ค.
DefinePlugin
ํ๋ก ํธ์์ ํ๋ก์ ํธ๋ฅผ ๊ด๋ฆฌ ํ ๋ ๊ฐ๋ฐํ๊ฒฝ๊ณผ ๋ฐฐํฌํ๊ฒฝ์ผ๋ก ๋๋์ด์ ์ด์์ ํ๋ค. ๊ทธ๋์ ์๋ฒ API ์๋ฒ ์ฃผ์๋ ๋ณ๊ฒฝ์ด ๋ ์ ๋ณด๋ค์ด ์์ ์ ์๋ค. ์ด๋ฐ ๊ฒ๋ค์ `ํ๊ฒฝ ์์กด ์ ๋ณด`๋ผ๊ณ ํ๋ค. ๋ฐ๋ผ ๋ฐฐํฌ๋ฅผ ํ ๋ ๋ง๋ค ์ฝ๋๋ฅผ ๊ณ์ํด์ ๋ณ๊ฒฝํ๋ ๋ฒ๊ฑฐ๋ก์์ ์ค์ด๊ณ ์ DefinePlugin์ ์ฌ์ฉํด์ ์ฝ๊ฒ ํด๊ฒฐ ํ ์ ์๋ค.(dotenv์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ง๋ง ํด๋น ํ๋ฌ๊ทธ์ธ์ผ๋ก ๋์ฒดํ ์ ์์ง ์์๊น ํ๋ค.) ํด๋น ํ๋ฌ๊ทธ์ธ ์ญ์ webpack์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํด์ฃผ๋ ํ๋ฌ๊ทธ์ธ์ด๋ค. ์ด๋ฅผ ํ์ฉํ๊ธฐ ์ํด์๋ process.env.NODE_ENV๊ฐ ์๋ค. ์ฌ๊ธฐ๋ก ์ ๊ทผํด์ webpack.config์ `mode`๊ฐ์ ์ป์ด์์ ํ์ฉํ๋ฉด ๋๋ค. process.env.NODE_ENV๋ฅผ app.js์์ console๋ก ํ์ธ์ด ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ ` development`๋ผ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ๊ทธ๋ผ ์ด์ ์ง์ ํ๊ฒฝ๋ณ์๋ฅผ ๋ง๋ค์ด๋ณด์.
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
/* -- ์ค๊ฐ ์๋ต -- */
plugins: [
new CleanWebpackPlugin(), // ๋น๋ ์ ์ dist ํด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
new webpack.BannerPlugin({
banner: `
Build Date: ${new Date().toLocaleDateString()}
Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
Author: ${childProcess.execSync('git config user.name')}
`
}),
new webpack.DefinePlugin({
TWO: '1+1'
})
],
}
์ด์ app.js์ TWO๋ผ๋ ํ๊ฒฝ๋ณ์์ ์ ๊ทผ์ ํ๋ ค๋ฉด ์๋์ ๊ฐ์ด ์์ฑํ๋ฉด ๋๋ค.
//app.js
console.log(process.env.NODE_ENV);
console.log(TWO); //2
ํ์ง๋ง ๊ฒฐ๊ณผ๋ ๊ฐ์ผ๋ก console์ด ์ฐํ๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ฌธ์๋ก ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์์ ํ๋ฉด ๋๋ค.
//TWO: '1+1'
TWO: JSON.stringify('1+1') //1+1
// ๊ฐ์ฒด ๋ฐฉ์
'api.domain': JSON.stringify('http://dev.api.domain.com')
HtmlTemplatePlugin
HtmlTemplatePlugin์ ์ด์ ํ๋ฌ๊ทธ์ธ๊ณผ ๋ฌ๋ฆฌ ์จ๋ ํํฐ ํจํค์ง์ด๊ธฐ์ ๋ฐ๋ก ์ค์น๋ฅผ ํด์ค์ผ ํ๋ค. HtmlTemplatePlugin์ HTML ํ์ผ์ ํ์ฒ๋ฆฌํ๋ ํ๋ฌ๊ทธ์ธ์ด๋ฉฐ ๋น๋ ํ์์ ๊ฐ์ ๋ฃ๊ฑฐ๋ ์ฝ๋๋ฅผ ์์ถํ๋ ์ญํ ์ ํ๋ค. HtmlTemplatePlugin์ html์ ์์ ํ๋ ํ๋ฌ๊ทธ์ธ์ด๊ธฐ ๋๋ฌธ์ ์ ์์ ์ผ๋ก ๋์ํ๊ฒ ํ๋ ค๋ฉด src ๋๋ ํ ๋ฆฌ์ html์ด ์์ ๊ฒฝ์ฐ, webpack์ผ๋ก ์์ ์ ํด์ผํ๋ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๋ฉด ๋๋ค ๋ณผ ์ ์๋ค. ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* -- ์ค๊ฐ ์๋ต -- */
plugins: [
new CleanWebpackPlugin(), // ๋น๋ ์ ์ dist ํด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
new webpack.BannerPlugin({
banner: `
Build Date: ${new Date().toLocaleDateString()}
Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
Author: ${childProcess.execSync('git config user.name')}
`
}),
new webpack.DefinePlugin({
TWO: JSON.stringify('1+1'),
'api.domain': JSON.stringify('http://dev.api.domain.com')
}),
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
}
์ดํ build๋ฅผ ํ๊ฒ ๋๋ฉด dist ๋๋ ํ ๋ฆฌ์ index.html ํ์ผ์ด ๋ค์ด ์๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค. ๋ง์ฝ live-server๋ก ์ ๊ทผ์ ํ๋ ค๋ฉด ์ฃผ์๊ฐ `PortNumber/~/dist/index.html`๋ก ํด์ค์ผ ํ๋ค.
์ด๋ฒ์๋ ์ด์ด์ html์์ ์ฌ์ฉํ ์ ์๋ ejs ๋ฌธ๋ฒ์ ์ ๊น ๋ค๋ค ๋ณผ ๊ฒ์ด๋ค. ํด๋น ๋ฌธ๋ฒ์ HtmlTemplatePlugin์์ ์ฌ์ฉํ๋ template์ html์ ์ง์ ๋ฃ์ด ๋ณด๋ ๊ฒ์ด๋ค. ํด๋น ๋ฌธ๋ฒ์ envs๋ผ๋ template๋ฅผ ๋ฃ์ ์ ์๋ ๋ฌธ๋ฒ์ด๋ค. ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
<!-- src/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document<%= env %></title>
</head>
<body>
<script type="module" src="./dist/main.js"></script>
</body>
</html>
์ด์ ์ฌ๊ธฐ env์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ ค๋ฉด ์๋์ ๊ฐ์ด webpack.configํ์ผ์ ์์ ํ๋ฉด ๋๋ค.
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* -- ์ค๊ฐ ์๋ต -- */
new HtmlWebpackPlugin({
template: './src/index.html',
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(๊ฐ๋ฐ์ฉ)' : ''
}
})
],
}
์ด์ build๋ฅผ ํ๋ฉด๋๋ค. ๋จ, NODE_ENV์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๋ฉด ์ฐ๋ฆฌ๊ฐ ์๋ํ ๊ฒฐ๊ณผ๋ฌผ์ด ๋์ฌ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ ์ผ๋ฐ์ ์ธ build๊ฐ ์๋ ์๋์ ๊ฐ์ด build๋ช ๋ น์ผ๋ก ์คํ ํด์ผํ๋ค.
:: ๊ฐ๋ฐ์ฉ์ด ์๋ ์ ํ์ฉ์ผ ๊ฒฝ์ฐ development ๋์ production์ ๋ฃ์ผ๋ฉด ejs์ env ๋ฌธ๋ฒ์ ๋ฌด์ํ๊ณ ๋น๋๊ฐ ๋๋ค.
:: npm(Window)
set NODE_ENV=development&& npm run build
:: npm(MacOS)
NODE_ENV=development yarn run build
:: yarn(Window)
set NODE_ENV=development&& yarn run build
::yarn(MacOS)
NODE_ENV=development&& yarn build
์ด์ธ์๋ ๋น๋๋๋ html์ ์ฌ๋ฌ ์กฐ๊ฑด์ ์ค์๊ฐ ์๋๋ฐ ์ฐ๋ฆฌ๋ ๋น์ค ์ ๊ฑฐ์ ์ฃผ์ ์ ๊ฑฐ๋ฅผ ํด๋ณผ ๊ฒ์ด๋ค. ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ถ๊ฐํ์
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* -- ์ค๊ฐ ์๋ต -- */
new HtmlWebpackPlugin({
template: './src/index.html',
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(๊ฐ๋ฐ์ฉ)' : ''
},
minify: {
collapseWhitespace: true,
removeComments: true,
}
})
],
}
์ดํ build๋ฅผ ํ์ธํ๋ฉด ์๋ ์ฝ๋์ฒ๋ผ htmlํ์ผ์ ํ์ค๋ก ์ฝ๋๊ฐ ์์ฑ๋๊ฑธ ํ์ธํ ์ ์๋ค.
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Document(๊ฐ๋ฐ์ฉ)</title><script defer="defer" src="main.js"></script></head><body><script type="module" src="./dist/main.js"></script></body></html>
์ด๋ ๊ฒ ํ์ค๋ก buildํ๋ ๊ฒฝ์ฐ๋ ์ผ๋ฐ์ ์ผ๋ก development ๋ฐฉ์์ด ์๋๋ผ producion์ผ ๊ฒฝ์ฐ์๋ง ์ ์ฉํ๋ค. ๋ฐ๋ผ ์๋์ ๊ฐ์ด ์กฐ๊ฑด์ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
//webpack.config.js
/* -- ์ค๊ฐ ์๋ต -- */
const webpack = require('webpack');
const childProcess = require('child_process'); //from node_modules
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* -- ์ค๊ฐ ์๋ต -- */
new HtmlWebpackPlugin({
template: './src/index.html',
templateParameters: {
env: process.env.NODE_ENV === 'development' ? '(๊ฐ๋ฐ์ฉ)' : ''
},
minify: production.env.NODE_ENV === 'production' ? {
collapseWhitespace: true,
removeComments: true,
} : false
})
],
}
์ ์ฅํ์ง ์๊ณ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋๋ ๋ฐ๋์ `clean-webpack-plugin`๊ณผ `mini-css-extract-plugin`์ ์์ฑํ๋ ์ฝ๋๋ค์ด ๋ชจ๋ ์ฌ๋ผ์ก๋ค. ๋ค์ ์์ฃผ ์ฌ์ฉ๋๋ ํ๋ฌ๊ทธ์ธ 2๊ฐ๋ ๊ทธ๋ฆฌ ์ด๋ ต์ง ์์๋ค. NODE_ENV๋ฅผ ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ๋ค์ด์๋ค. ์คํ๋ ค ์ฃผ์ ๊น๊ฒ ๋ณด์์ผ ํ๋ ๋ถ๋ถ์ mini-css-extract-plugin์ด์๋ค. ์ถํ์ ๋ค์ ์ ๊ฒํ๋ฉด์ ๋ง๋ฌด๋ฆฌ ์ง์ ๊ฒ์ด๋ค. ์๋ Github์์ ์ ์ฒด์ฝ๋๋ฅผ ํ์ธํด ๋ฌ๋ผ.
/* -- ์ค๊ฐ ์๋ต -- */
new CleanWebpackPlugin(), // ๋น๋ ์ ์ dist ํด๋๋ฅผ ์ ๋ฆฌํฉ๋๋ค.
...(process.env.NODE_ENV === 'production'
? [new MiniCssExtractPlugin({ filename: '[name].css' })]
: [])
Frontend-Development-Environment/webpack.config.js at main · Programming-Contents-List/Frontend-Development-Environment
ํ๋ก ํธ์๋ ๊ฐ๋ฐ ํ๊ฒฝ ์ธํ ์์ . Contribute to Programming-Contents-List/Frontend-Development-Environment development by creating an account on GitHub.
github.com