๐ Webpack, ์ด๊ฒ๋ง์ ์๊ณ ๊ฐ์
Webpack์ ์น ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๋ฒ๋ค๋ฌ์ ๋๋ค. React ์ฑ์ ๋น๋ํด์ฃผ๋ ๋๊ตฌ๋ก ์๊ฐํ๊ณ CRA์ Webpack ์ค์ ์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ ์ด๊ฒ์ด ์ด๋ป๊ฒ ๋์ํ๋์ง, ํต์ฌ ์๋ฆฌ๋ ๋ฌด์์ธ์ง ์ดํดํด์ผ ํ์ง ์์๊น? ๋ผ๋ ์๊ฐ์์ ๊ธ์ ์ ๊ฒ๋์์ต๋๋ค. ํ์ง๋ง Webpack์์ ์ฌ์ฉํ๋ ๋ชจ๋ ํ๋ฌ๊ทธ์ธ๊ณผ ๋ฒ๋ค๋ฌ, ์ต์ ํ ์ต์ ์ ๊ณต๋ถํ๊ธฐ ๋ณด๋ค๋ Webpack์ ๋์์๋ฆฌ์ ํต์ฌ ์์๋ค์ ์ดํดํ๊ณ ์ํฉ์ ๋ง๊ฒ ํ์ํ ๊ฒ๋ค์ ํ์ตํ๋ ๊ฒ์ด ํจ์จ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋์ ์ด ๊ธ์์๋ Webpack์ ๊น์ด์๋ ๋ด์ฉ๋ณด๋ค ์๊ฒ '์ด๊ฒ๋ง์ ์์์ผ ํ์ง ์์๊น' ๋ผ๊ณ ์๊ฐ๋๋ ๋ด์ฉ์ ์ ์ด๋ดค์ต๋๋ค.
Webpack์ ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด ์ฌ์ฉ๋๋ ์ ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ ๋๋ค. ์ฌ๊ธฐ์ ๋ฒ๋ค๋ฌ๋ ์ฌ๋ฌ ํจํค์ง, ๊ด๋ จ๋ ํ์ผ๋ค์ ํ๋๋ก ๋ฌถ์ด์ฃผ๋ ๋๊ตฌ๋ผ๊ณ ์๊ฐํ ์ ์์ต๋๋ค. ๋ด๋ถ์ ์ผ๋ก๋ ํ๋ก์ ํธ์ ํ์ํ ์์ ๊ฐ์ ์์กด์ฑ ๊ทธ๋ํ๋ฅผ ์ฐธ๊ณ ํ์ฌ ํ๋ ์ด์์ ๋ฒ๋ค๋ก ๋ง๋ค์ด๋ ๋๋ค.
Webpack์์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํ์ฌ ์ฌ๋ฌ ๋ฆฌ์์ค๋ค์ ์ฐ๊ฒฐํ(Concentarte) ๊ฒฐ๊ณผ๋ฌผ์ ๋๋ค. Bundle์ ์ฌ๋ฌ ๊ฐ์ Chunk๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
๋ชจ๋ ์ฝ๋๋ฅผ ํ๋์ ๊ฑฐ๋ํ ํ์ผ(Bundle)๋ก ๋ง๋ค์ง ์๊ธฐ ์ํด์ ์ฌ๋ฌ๊ฐ์ Chunk๋ผ๋ ๋จ์๋ก ๋๋๋๋ค. ์ฝ๋๊ฐ ์ด๋ป๊ฒ ๋๋๋์ง์ ๋ํ ๋ฐฉ๋ฒ๋ ์์๋ก ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ Webpack์ ์ฌ์ฉํด์ผ ํ๋์ง ์ดํดํ๊ธฐ ์ํด์๋ ๊ทธ ์ด์ ์น์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ ๋ ๋ฒ๋ค๋ฌ๋ ์ด๋ ๋์ง ์ดํด๋ด์ผ ํฉ๋๋ค.
๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์๋๋ฐ ํ๋๋ ๋๋ฌด ๋ง์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒ์ด์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ์ ๋คํธ์ํฌ ๋ณ๋ชฉ์ ์ผ์ผ์ผฐ๊ณ ์์ฒญ ์ง์ฐ์ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋๋ฒ์งธ ๋ฐฉ๋ฒ์ ๋ชจ๋ ์ฝ๋๋ฅผ ํฌํจํ๊ณ ์๋ ํ๋์ ํฐ .js
ํ์ผ์ ์ฌ์ฉํ๋ ๊ฒ์ด์๋๋ฐ, ์ค์ฝํ, ํฌ๊ธฐ, ๊ฐ๋
์ฑ, ์ ์ง๋ณด์์ฑ์ ๋ํ ์ด์ ๋ก ๋ฌธ์ ๊ฐ ๋ง์์ต๋๋ค.
IIFE๋ ์คํฌ๋ฆฝํธ ํ์ผ์ ํ๋์ IIFE๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ํฐ ํ๋ก์ ํธ์์ ์ค์ฝํ ์ด์๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ IIFE๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ์ค์ฝํ ์ถฉ๋์ ๋ํด ๊ฑฑ์ ํ ํ์ ์์ด ์์ ํ๊ฒ ์ฝ๋๋ฅผ ๋ฒ๋ค๋งํ ์ ์์ต๋๋ค.
Webpack์ IIFE๋ฅผ ์ฌ์ฉํ๋ฉฐ ๊ทธ ๋ฐ์ ์ฌ์ฉํ๋ ๋๊ตฌ๋ก์จ๋ Make, Gulp, Grund, Brocooli or Brunch๊ฐ ์์ต๋๋ค. ์ด ๋๊ตฌ๋ค๋ ์๋ ค์ง๊ณผ ๊ฐ์ด ๋ฒ๋ค๋ฌ(๋๋ ํ ์คํฌ ๋ฌ๋)๋ก์จ ํ๋ก์ ํธ ํ์ผ๋ค์ ๋ชจ๋ ๋ฒ๋ค๋งํด์ค๋๋ค. ํ์ง๋ง ๋ค๋ฅธ ๋๊ตฌ๋ค๊ณผ ๋ค๋ฅด๊ฒ Webpack์ dependency graph๋ฅผ ์์ฑํ์ฌ ๋น๋์์ผ์ฃผ๋ ๋๊ตฌ๋ก์จ ํฌ๊ณ ๋ณต์กํ ๋ฆฌ์์ค๊ฐ ์๋ ํ๋ก์ ํธ์์๋ Webpack์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. (Grunt, Gulp๋ ์ค๋ก์ง ๋ฆฌ์์ค์ ๋ํ ํด๋ก ์ฌ์ฉ๋๋ฉฐ dependency graph ๊ฐ๋ ์ด ์์) ๋ํ ๋น์ทํ Browsify์ ๋น๊ตํ๋ค๋ฉด ์๋๋ฉด์์ ์ข ๋ ์ฐ์ํฉ๋๋ค.
Webpack์ ์ฌ์ฉํ์ง ์๊ณ ๋ฒ๋ค๋ง์ ํ๋ค๊ณ ๊ฐ์ ํด๋ณธ๋ค๋ฉด, ํ๋์ ํ์ผ์ ๋ณ๊ฒฝํ๋ค๋ ๊ฒ์ (๋ฒ๋ค์ ์๋ก ๋ง๋ค์ด์ผํ๋ฏ๋ก)์ ์ฒด๋ฅผ ๋ค์ ๋น๋ํ๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฒ๋ค๋ง์ ์ฝ๊ฒํ๋ ค๋ฉด ํ์ผ๋ค ๊ฐ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฌ์ฉํด์ผํฉ๋๋ค. ํ์ง๋ง ์ด๋ฅผ ์ต์ ํํ์ฌ ๋น๋ํ๋ ๊ฒ์ ์ด๋ ต์ต๋๋ค. ๋ํ ์ฝ๋๋ฅผ ์์ฑํ ๋ค์ ๊ทธ ์ฝ๋๊ฐ ์คํฌ๋ฆฝํธ์์ ์ค์ ๋ก ์ฌ์ฉ๋๋์ง ์๋์ง ์ด๋ป๊ฒ ์ ์ ์์๊น์?
์๋ฅผ ๋ค์ด lodash์์ ๋จ์ผํจ์ ๋ง ์ฌ์ฉํ๋๋ผ๋ lodash ์ ์ฒด ์ฝ๋๋ฅผ ์ถ๊ฐํ ๋ค์ ํจ๊ป ๋ฒ๋ค๋งํด์ผํฉ๋๋ค. ์ด๋ฌํ ์ฝ๋์ ์ข ์์ฑ์ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น์? ์ฝ๋์ ๋ก๋ฉ์ง์ฐ์ ์ปค์ง๋ ๊ฒ์ ๋ง์์ผํ๋ฉฐ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๊ฐ๋ฐ์์ ๋ง์ ์์์ ์ด ํ์ํฉ๋๋ค.
์ด๋ฌํ ์ํฉ์ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ผ๋ก Webpack์ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ง์ ํ๊ธฐ ์ด๋ ค์ด ๋ฒ๋ค๋ง์ ์ฑ๋ฅ๊ณผ ์ต์ ํ๋ฅผ ๋น๊ต์ ์ฝ๊ฒ ๊ฐ์ ํ ์ ์์ต๋๋ค. ๋ํ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋์ธ ์ฝ๋ ์คํ๋ฆฌํ ์ ์ด์ฉํ์ฌ ํ์ํ ๋ชจ๋๋ง ๋ก๋ํ์ฌ ์์ฒญ ์ง์ฐ์ ์ค์ผ ์ ์์ต๋๋ค.
์๋๋ Webpack์ core๋ผ๊ณ ํ ์ ์๋ ์์๋ค์ ๋๋ค. ์ด ์์๋ค์ ์ฝ๋์ ํจ๊ป ์ดํด๋ณด๊ฒ ์ต๋๋ค.
CRA๋ React๋ก ๊ฐ๋ฐํ ๋ ๊ฐ์ฅ ์ ์ฉํ ๋ณด์ผ๋ฌํ๋ ์ดํธ์ ๋๋ค. ์ด CRA ์ค์ ์๋ React๋ฅผ ๊ตฌ์ฑํ๋๋ฐ ํ์ํ Webpack ์ค์ ๋ค์ด ๊ธฐ๋ณธ์ผ๋ก ์์ฑ๋์ด ์์ต๋๋ค. ์ด ์ค์ ๋ค์ ๋ณด๋ฉฐ React์์ Webpack์ ์ด๋ป๊ฒ ์ค์ ํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก CRA๋ฅผ ํตํด React ํ๊ฒฝ ๊ตฌ์ฑ์ํ๋ฉด Webpack ๊ด๋ จ ์ค์ ๋ค์ด ์จ๊ฒจ์ ธ์๋๋ฐ ์ด๋ฅผ ๊บผ๋ด์ด ๊ฐ๋ฐ์๊ฐ ์ง์ ์์ ํ ์ ์๋๋ก ํด์ผํฉ๋๋ค.
npx create-react-app myapp
eject
๋ฅผ ํตํด Webpack ์ค์ ์ ์ธ๋ถ๋ก ๊บผ๋ด๊ธฐnpm run eject
# ๋๋ yarn
yarn eject
์ด๋ ๊ฒ eject
์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์ค์ ์ ๊บผ๋ผ ์ ์์ผ๋ฉฐ config
์ script
๋๋ ํฐ๋ฆฌ๊ฐ ์์ฑ๋๋๋ฐ config/webpack.config.js
์์ Webpack ํ๊ฒฝ์ค์ ์ ๋ณผ ์ ์์ต๋๋ค.
์ด ์์๋ค์ CRA์์์ webpack.config.js
์ฝ๋์์ ๋ชจ๋ ์ค์ ์ ์ดํด๋ณด์ง ์๊ณ ํต์ฌ์ ์ธ ๋ถ๋ถ๋ง ํ๋์ฉ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
entry๋ building์ ์์์ ์ด๋ผ๊ณ ๋ณผ ์ ์์ผ๋ฉฐ, output์ buidling ๋ ํ์ผ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๋ค.
entry: [
// dev ๋ชจ๋๋ฉด Hot reload(ํ์ผ์ ๋ณ๊ฒฝ์ฌํญ ์๋ ๋ฐ์) ์ค์ ์ ์ถ๊ฐ
isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),
// src/index.js
paths.appIndexJs
].filter(Boolean), // true๊ฐ์ธ ๊ฒฐ๊ณผ๋ง ๋ฐํ
output: {
// build path, filename ์ง์
path: isEnvProduction ? paths.appBuild : undefined,
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js' // ํด์ ๊ฐ์ ๋ฃ์์ผ๋ก์จ ๋ก์ปฌ์์ ์บ์ฑ์ ์ ๋ํ ์ ์์ต๋๋ค.
: isEnvDevelopment && 'static/js/bundle.js',
// more...
},
loader๋ ๋ฒ๋ค๋งํ ํ์ผ์ ๋ํ ๊ท์น์ ์ ํ๊ณ ์คํํ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค. ์๋์ ์ฝ๋๋ ๋ชจ๋์ด ๋ ์ ์๋ ํ์ผ๋ค์ babel-loader
๋ฅผ ํตํด ์ฝ์ด๋ค์ด๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
loaders: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve("babel-loader")
// ...
}
];
๋ฆฌ์์ค ํ์ผ๋ค ๋ํ loader๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
loaders: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve("babel-loader")
// ...
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve("url-loader")
}
];
ํ๋ฌ๊ทธ์ธ์ ๋ฒ๋ค ์ต์ ํ, ํ๊ฒฝ ๋ณ์ ์ฃผ์
๊ณผ ๊ฐ์ ์์
๋ค์ ์ํํ ์ ์์ผ๋ฉฐ ์ด์ธ์๋ ๋ค์ํ ๊ธฐ๋ฅ๋ค์ด ์กด์ฌํฉ๋๋๋ค. ์๋ ์ฝ๋์์๋ HtmlWebPackPluglin
์ ์ฌ์ฉํ์ฌ filename
์ ๊ฐ์ผ๋ก ์ง์ ๋ ํ์ผ์์ <script>
ํ๊ทธ๋ฅผ ์ฃผ์
ํฉ๋๋ค.
plugins: [
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml // ./src/index.html
},
isEnvProduction
? {
minify: {
removeComments: true
//...
}
}
: undefined
)
)
// more ...
];
webpack์ ๊ตฌ๋์ํฌ mode๋ฅผ ์ง์ ํด์ค ์ ์์ต๋๋ค. development
, production
, none
์ธ๊ฐ์ง๊ฐ ์๋๋ฐ ๊ฐ๊ฐ์ ์ค์ ์ ๋ฐ๋ผ webpack์ ๋ด์ฅ๋ ์ต์ ํ๋ฅผ ์ด๋ค ๋ฐฉ์์ผ๋ก ํ ์ง ์ง์ ํ ์ ์์ต๋๋ค. webpack์ mode ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ด๋ค ์ต์ ํ๊ฐ ์ค์ ๋๋์ง ์์ธํ๊ฒ ์ ์ ์์ต๋๋ค. ์ด๋ฅผ ๋ฐํ์ผ๋ก ์์๋ก optimization
์์ฑ์ ์ต์ ํ ์ต์
์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
๋ฒ๋ค์ ๊ตฌ์ฑ์ฌํญ์ ํ๋ฒ์ ๋ณผ ์ ์๋ ๋๊ตฌ์ ๋๋ค. ์ด๋ฅผ ํ์ฉํ์ฌ ์ด๋ค ๊ตฌ์ฑ์ด bundle์ ํฌ๊ธฐ๋ฅผ ์ผ๋ง๋ ์ฐจ์งํ๋์ง ํ์ธํ ์ ์๊ณ ์ด๋ฅผ ํตํด์ Webpack ์ค์ ์ ์์ ํ๊ฑฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ต์ฒด๋ ๊ณ ๋ คํด๋ณผ ์ ์์ต๋๋ค.
React๋ก ๊ฐ๋ฐํ๋ฉฐ ๋น๋์ ๋ํด์๋ ํฌ๊ฒ ๊ด์ฌ์ ๊ฐ์ง์ง ์์์๋๋ฐ ๊ด์ฌ์ ๊ฐ์ง๊ณ ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ๋ค์ผ์๋ก ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์๋ค๋ ๊ฒ์ ์์์ต๋๋ค. ๋ํ SPA๋ฅผ ๊ฐ๋ฐํ ๋ ๋น๋ ๋๊ตฌ๋ฅผ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋๋๋ฐ ์ด๋ฅผ ์ ์ดํดํ์ง ๋ชปํ ์ฑ ๊ฐ๋ฐํ๋ ๊ฑด ๋ง์น ์นด๋ฉ๋ผ์ ์กฐ๋ฆฌ๊ฐ์ ๋ ์ฆ๋ฅผ ์ ์ดํดํ๊ณ ์๋ ์ฌ์ง๊ฐ๊ฐ ์ผ๋ฐ์ธ๋ณด๋ค ์ฌ์ง์ ์ ์ฐ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง ์๋๊น ์๊ฐ์ด ๋ค์์ต๋๋ค. ๋น๋ ๋๊ตฌ๋ ํจ๊ป ์ดํดํ๋ค๋ฉด ์ข์ ์ฑ๋ฅ์ ๋ผ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.