์ฐ์ํํ ํฌ์ฝ์ค์์ ๋ชจ๋๋ชจ์ฌ๋ผ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ์นํฉ์ ์ ์ฉํ ๋ก๋์ ๋ํด ๋ง์ ๊ณ ๋ฏผ์ด ์์์ต๋๋ค.
๋ํ์ ์ผ๋ก๋ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ts-loader
์ babel-loader
๊ฐ ์๊ณ , ์ต๊ทผ์๋ esbuild-loader
๋ผ๋ ์ข ๋ ๋น ๋ฅธ ๋ก๋๊ฐ ๋ฑ์ฅํ์ต๋๋ค. (esbuild-loader๋ vite์์ ์ฌ์ฉํ ์ ๋๋ก ํซํ ๋ก๋๋ผ๊ณ ํ๋๋ผ๊ณ ์!)
์ ๋ ํ์ ์ฒดํน๋ ํ๋ฉด์ ๋น ๋ฅธ ๋น๋ ์๋๊น์ง ์ฑ๊ธฐ๊ณ ์ถ์๊ธฐ ๋๋ฌธ์ ์ด ์ธ ๋ก๋์ ๋ํด ์ข ๋ ์์๋ณธ ๋ค ์ ํํ์ฌ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๐ ts-loader
ts-loader๋ ํ์ ์ฒด์ปค๊ฐ ๋ด์ฅ๋ ๋ก๋์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋น ํ๋ก์ ํธ์ tsconfig.json ํ์ผ์ ๋ณด๊ณ ํด๋น ์ต์ ์ ๋ฐ๋ผ ํ์ ์ฒดํน์ ์คํํฉ๋๋ค.
ts-loader์ ์คํ ์์๋ ํ์
์ฒดํน โ (ํ์
์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์์ ๊ฒฝ์ฐ) ๋น๋
์ด๊ธฐ ๋๋ฌธ์ ๋น๋ ์ฑ๊ณต๊น์ง ๋น๊ต์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฝ๋๋ค. ํ์ง๋ง ๊ฐ๋ ฅํ ํ์
์ฒดํฌ๋ก ์ธํด ์์ ํ ํ์ดํ์ด ๊ฐ๋ฅํฉ๋๋ค.
๋ง์ฝ ts-loader์ ๋น๋ ์๋๋ฅผ ํฅ์์ํค๊ณ ์ถ๋ค๋ฉด ์ปดํ์ผ๋ฌ ์ต์ ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
module.exports = {
...
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true
},
},
],
},
],
},
};
์์ ๊ฐ์ด transpileOnly
์ต์
์ true๋ก ํ๋ค๋ฉด ๋น๋ ์ ํ์
์ฒดํน์ ํ์ง ์์ต๋๋ค. ์ถ์ฒ
๊ทผ๋ฐ ํ์ ์ฒดํน์ ํ์ง ์์ผ๋ฉด ts-loader๋ฅผ ์ฌ์ฉํ ์๋ฏธ๊ฐ ์์ง ์๋? ์ ๊ทธ๋ ๊ฒ ์๊ฐํ์ต๋๋ค. ๊ทธ๋์ ํ์ ์ฒดํน์ ํ๋ฉด์ ๋น๋ ์๋๋ฅผ ๋์ผ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์๊น ๊ณ ๋ฏผํ์ต๋๋ค.
๐ fork-ts-checker-webpack-plugin
ts-loader๋ฅผ ๋ง๋ TypeStrong์์ ํ์ ์ฒดํน ๊ธฐ๋ฅ๋ง ๊ฐ์ ธ์ ๋ง๋ fork-ts-checker-webpack-plugin๋ผ๋ ์นํฉ ํ๋ฌ๊ทธ์ธ์ด ์์ต๋๋ค.
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = {
...,
plugins: [new ForkTsCheckerWebpackPlugin()],
};
์ด ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ฉด ์๋์ผ๋ก ts-loader์ transpileOnly ์ต์
์ true๋ก ์ค์ ๋์ด ๋ก๋์์๋ ํ์
์ฒดํน์ด ๋์ง ์๊ณ , ๋ณ๋์ ํ๋ก์ธ์ค์์ ์ด ํ๋ฌ๊ทธ์ธ์ ํตํด ํ์
์ฒดํน ๊ณผ์ ์ด ์ด๋ฃจ์ด์ง๋๋ค.
ํ์
์ฒดํน์ด ์ด๋ฃจ์ด์ง๋ ์์ ์ ๋ช
ํํ๊ฒ ๋ฐํ ๋ฐ๊ฐ ์์ด ํ์คํ๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ํฐ๋ฏธ๋์์ ์นํฉ์ด ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผ๋์๋ค๋ ๋ฉ์์ง ์ดํ๋ก ํ์
์ฒดํน์ด ์คํ๋๋ค๋ ๋ฌธ๊ตฌ๊ฐ ๋์จ ๊ฒ์ ๋ณด์ ์ ๋ ์ปดํ์ผ ํ ํ์
์ฒดํน ๊ณผ์ ์ด ์คํ๋๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๋์ฑ ์ข์ ๊ฒ์ fork-ts-checker-webpack-plugin์ ts-loader๊ฐ ์๋ ๋ค๋ฅธ ๋ก๋ ์กฐํฉ์๋ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ด์์ต๋๋ค. ๊ทธ๋์ ์ ๋ ts-loader๋ณด๋ค๋ ๋ค๋ฅธ ๋ก๋ + fork-ts-checker-webpack-plugin์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๊ฒ ๋ค๊ณ ํ๋จํ์ต๋๋ค.
๊ทผ๋ฐ ์ด fork-ts-checker-webpack-plugin์ ์ผ๋ฐ์ ์ธ tsc์ ํ์ ์ฒดํฌ๋ฅผ ํ๋ ๊ณผ์ ์์ ์ฐจ์ด๊ฐ ์์์ต๋๋ค.
fork-ts-checker-webpack-plugin
๋จผ์ fork-ts-checker-webpack-plugin์ ๊ฒฝ์ฐ ๋น๋ํ ๋๋ง๋ค ์๋ก ๋ณ๊ฒฝ๋ ํ์ผ์ด ์ด๋ค ํ์ผ๊ณผ ์ข ์์ฑ์ด ์๋์ง๋ฅผ ์ฐพ์๋ ๋๋ค. ์ด๋ *.d.ts ํ์ผ์ ํ์ ์ฒดํน๋ ์งํํ๊ธฐ ๋๋ฌธ์ ์ด ๊ณผ์ ์ ํ๋ก์ ํธ์ ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ์์์๊ฐ๋ ๋์ด๋๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
๋ค๋ง ํ์ ์ฒดํน์ด ์ปดํ์ผ๊ณผ ๋ณ๋์ด๊ธฐ ๋๋ฌธ์ ํ์ ์๋ฌ๊ฐ ๋๋๋ผ๋ ์ปดํ์ผ์ ์ ๋๋ก ์ด๋ฃจ์ด์ง๋ค๋ ์ , ํ์ผ์ ๋ณ๊ฒฝ์ด ์์ ๋๋ง๋ค ํ์ ์ฒดํน ๊ณผ์ ์ ์๋์ผ๋ก ์ํํด์ค๋ค๋ ์ ์ ๋ณด์ ๊ฐ๋ฐ ๋ชจ๋์์ ์ฌ์ฉํ๊ธฐ ์ ์ ํด๋ณด์์ต๋๋ค.
tsc
tsc์ ๊ฒฝ์ฐ ๋น๋ ์ .tsbuildinfo ํ์ผ์ ์์ฑํ์ฌ ๋ค์ ๋น๋๋ถํฐ ํด๋น ํ์ผ์ ์ฐธ์กฐํฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์ ๋๋ถ์ ๋ ๋ฒ์งธ ๋น๋๋ถํฐ๋ fork-ts-checker-webpack-plugin๋ณด๋ค ๋ ์ ์ ์๊ฐ์ด ์์๋๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๋ค๋ง ํ์ ์๋ฌ๊ฐ ๋๋ฉด ์ปดํ์ผ์ ํ์ง ์๊ณ ์ข ๋ฃ์์ผ๋ฒ๋ฆฐ๋ค๋ ์ , ํ์ผ์ ๋ณ๊ฒฝ์ด ์์ด๋ ํ์ ์ฒดํน ๊ณผ์ ์ ์๋์ผ๋ก ์ํํด์ฃผ์ง๋ ์๋๋ค๋ ์ ์ผ๋ก ๋ณด์ ๋ฐฐํฌ ๋ชจ๋์์ ์ฌ์ฉํ๊ธฐ ์ ์ ํด๋ณด์์ต๋๋ค.
๊ทธ ์ธ์ fork-ts-checker-webpack-plugin๊ณผ tsc๋ ์ผ๋ถ ํ์ ์ฒดํฌ์ ๋ํด์๋ ์ฐจ์ด๊ฐ ์๋ ๊ฒ ๊ฐ๊ธฐ๋ ํ๋๋ฐ, ์ฌ์ฉํ๋ฉด์ ๊ฐ๊ฐ์ ํ์ ์ฒดํน์ ๋ํด ํฌ๊ฒ ์ฐจ์ด๋ฅผ ๋๋ผ์ง๋ ๋ชปํ๊ธฐ ๋๋ฌธ์ ๋ ๊ฐ์ง๋ฅผ ๋์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ์์ ๊ฑฐ๋ผ๊ณ ํ๋จํ์ต๋๋ค.
๐ babel-loader
babel-loader๋ babel์ ์ฌ์ฉํ์ฌ ๋น๋๋ฅผ ์งํํ๋ ๋ก๋์ ๋๋ค.
module.exports = {
...
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
},
},
],
},
};
๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ๋ฒจ์ ๋น๋ ์ ํ์ ์ ์ ๊ฑฐํฉ๋๋ค. ๋ณ๋์ ํ์ ์ฒดํน ๊ณผ์ ์ด ์๋ ๊ฒ์ ๋๋ค. ๋๋ฌธ์ ํ์ ์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ๋ฒจ์ ํด๋น ์๋ฌ๋ฅผ ์ก์ง ๋ชปํฉ๋๋ค.
๊ทธ๋ ๊ธฐ์ ๋ณ๋์ ํ์ ์ฒดํน ๊ณผ์ ์ด ํ์ํ๋ค๋ฉด ์์ ๋ณด์๋ fork-ts-checker-webpack-plugin๋ tsc๋ฅผ ํ์ฉํด์ผ ํฉ๋๋ค.
์ด๋ ๊ฒ๋ง ๋ณธ๋ค๋ฉด babel-loader์ ์ฅ์ ์ ํ์ ์ ์ ๊ฑฐํ๊ธฐ ๋๋ฌธ์ ๋น๋ ์๊ฐ์ด ts-loader๋ณด๋ค ๋น ๋ฅด๋ค๋ ๊ฒ๋ฐ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฌ์ค babel-loader์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ํ์ฅ์ ์ฉ์ดํ๋ค๋ ๊ฒ์ ๋๋ค.
์์ ๋งํ๋ค์ํผ babel-loader๋ babel์ ์ฌ์ฉํฉ๋๋ค. babel์๋ ์ ์ฉํ ์ ์๋ ํ๋ฌ๊ทธ์ธ๋ค์ด ๋ง์ต๋๋ค. ์ผ์ด์ค๋ณ๋ก ๋ค๋ฅด๊ฒ ์ง๋ง ํ๋ฌ๊ทธ์ธ์ ์ ์ ์ฉํ๋ฉด ์คํ๋ ค ๋ค๋ฅธ ๋ก๋๋ณด๋ค ๋ ์ข์ ๋ฐฉ์์ผ๋ก ํ๋ก์ ํธ ์ค์ ์ ํ ์ ์์ ๊ฒ์ ๋๋ค.
ํน์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ ํ๋ฌ๊ทธ์ธ์ ์ ์ธํ๊ณ ๋ณ๋์ ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐ๋ก ์ ์ฉํ์ง ์๋๋ค๋ฉด, ๋ฐ์์ ๋ค๋ฃจ๋ esbuild-loader๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๋ ์๋์ ์์ด์ ๋ ์ข์ต๋๋ค. ๋ํ esbuild-loader๋ ์ ๊ณตํ๋ ํ๋ฌ๊ทธ์ธ์ด ๋์ด๋๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ณธ์ธ์ด ํ์ํ ํ๋ฌ๊ทธ์ธ์ ์ ๊ณตํ๊ณ ์๋ค๋ฉด esbuild-loader๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ํจ์ฌ ํจ์ฉ์ ์ผ ๊ฒ์ ๋๋ค.
๋ง์ฝ babel-loader์ ์๋๋ฅผ ๋ ๋์ด๊ณ ์ถ๋ค๋ฉด ์บ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ก๋ ์ต์
์ค cacheDirectory
๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค. (๊ธฐ๋ณธ๊ฐ์ false์
๋๋ค.) ์ฐธ๊ณ
๐ esbuild-loader
๋ง์ง๋ง์ผ๋ก esbuild-loader์ ๋๋ค. esbuild-loader๋ Go ์ธ์ด๋ก ์ ์๋ esbuild๋ฅผ ์ฌ์ฉํ์ฌ ์๋๊ฐ ๋งค์ฐ ๋น ๋ฆ ๋๋ค.
module.exports = {
...
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'esbuild-loader',
options: {
loader: 'tsx',
target: 'esnext',
},
},
},
],
},
};
esbuild๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์บ์๋ฅผ ์ง์ํฉ๋๋ค. ์ผ๋ถ ๋ฐ์ดํฐ๊ฐ ์บ์๋๊ณ , ๋ง์ง๋ง ๋น๋ ์ดํ ์๋ณธ ํ์ผ์ด ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ ๊ธฐ์ ๋ ๋ฒ์งธ ๋น๋ ์๋ถํฐ๋ ์ผ๋ฐ ๋น๋๋ณด๋ค ๋ ํจ์จ์ ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ esbuild-loader์ ๊ฒฝ์ฐ ESBuildMinifyPlugin๋ ์ง์ํ๋๋ฐ์. ๊ธฐ๋ณธ์ ์ธ terser-plugin๋ณด๋ค ์งง์ ์๊ฐ์ด ์์๋ฉ๋๋ค.
const { ESBuildMinifyPlugin } = require('esbuild-loader');
module.exports = {
...,
optimization: {
minimizer: [
new ESBuildMinifyPlugin({
target: 'esnext',
css: true, // ์ด ์ต์
์ ์ฌ์ฉํ๋ฉด css์ minify๋ ๊ฐ๋ฅํฉ๋๋ค.
}),
],
},
};
์ค์ ๋ก ์ ๊ฐ ํ ์คํธํ์ ๋ ๋ชจ๋ ์ต์ ์ ์ ์ฉ ํ esbuild-loader + fork-ts-checker-webpack-plugin๊ณผ ts-loader๋ฅผ ๋น๊ตํ์ ๋ ์ฝ 1/3 ๊ฐ๋ ๋น๋ ์๊ฐ์ด ์ค์ด๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.
๐ ๊ฒฐ๋ก
์ ๊ฐ ๋ด๋ฆฐ ๊ฒฐ๋ก ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก๋ ์๋๊ฐ ๋น ๋ฅธ
esbuild-loader
๋ฅผ ์ฌ์ฉ - ํ์ ์ฒดํน ์ ๊ฐ๋ฐ ๋ชจ๋์์๋ fork-ts-checker-webpack-plugin, ๋ฐฐํฌ ๋ชจ๋์์๋ tsc ์ฌ์ฉ
ํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค!