์ค๋์ Vanilia JS ๋ฅผ ํ์ฉํ SPA ํ๋ก์ ํธ์์ Babel + TypeScript + Webpack ์ ์ค์ ํ๋ ๋ฒ์ ๋ํด์ ์์๋ณด๋ ค๊ณ ํฉ๋๋ค.
Babel์ด๋?
Babel
Current Sponsors We're a small group of volunteers that spend their free time maintaining this project, funded by the community. If Babel has benefited you in your work, becoming a contributor or sponsoring might just be a great way to give back!
babeljs.io
๊ณต์๋ฌธ์์๋ ๋ค์๊ณผ ๊ฐ์ ์๊ฐ๊ฐ ๋์์์ต๋๋ค.
Babel is a JavaScript compiler
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments. Here are the main things Babel can do for you:
- Transform syntax
- Polyfill features that are missing in your target environment (through a third-party polyfill such as core-js)
- Source code transformations (codemods)
- And more! (check out these videos for inspiration)
// Babel Input: ES2015 arrow function
[1, 2, 3].map(n => n + 1);
// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
return n + 1;
});
์ต์ JavaScript/TypeScript ์ฝ๋๋ฅผ ๊ตฌํ ๋ธ๋ผ์ฐ์ ๋ Node.js ํ๊ฒฝ์์๋ ๋์ ๊ฐ๋ฅํ๊ฒ ๋ณํํ๋ ๋๊ตฌ(ํธ๋์คํ์ผ๋ฌ)์ด๋ค.
๋ค์๊ณผ ๊ฐ์ด ๋ฌธ๋ฒ ๋ณํ๊ณผ ๊ด๋ จํ ์ญํ ์ ๋งก์ต๋๋ค.
- ์ต์ ECMAScript ๋ฌธ๋ฒ(ES2020+)์ ํ์ ํธํ ์ฝ๋๋ก ๋ณ๊ฒฝ
- ๋๋ฝ๋ ํด๋ฆฌํ ๊ธฐ๋ฅ
- ํ์ ์ด๋ ธํ ์ด์ ์ ๊ฑฐ ( Babel์ ํ์ ๊ฒ์ฌ๋ฅผ ํ์ง ์๋๋ค )
- React JSX → JS ์ฝ๋ ๋ณํ
- ๊ทธ ์ธ์ ๋ง์ ๊ฒ๋ค -> https://babeljs.io/videos ์ฐธ๊ณ
Webpack
JS, TS, CSS, ์ด๋ฏธ์ง, ํฐํธ ๋ฑ ๋ชจ๋ ๋ฆฌ์์ค๋ฅผ ํ๋์ ํ์ผ๋ก ๋ฌถ์ด์ฃผ๋ ๋ชจ๋ ๋ฒ๋ค๋ฌ(Module Bundler)์ ๋๋ค.
ํ๋ ํ๋ก ํธ์๋ ์ฑ์ ์์ญ~์๋ฐฑ ๊ฐ์ JS/TS ํ์ผ, CSS, ์ด๋ฏธ์ง, ํฐํธ ๋ฑ์ผ๋ก ๊ตฌ์ฑ๋๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ๋ชจ๋ ํ์ผ์ ๋ก๋ํ๋ฉด ๋คํธ์ํฌ ์์ฒญ์ด ๋๋ฌด ๋ง์์ง๊ณ , ๊ด๋ฆฌ๊ฐ ๋ณต์กํด์ง๋๋ค.
๋ฐ๋ผ์ Webpack์ ์์ค ์ฝ๋๋ฅผ ๋ถ์ํด์ ์์กด์ฑ ๊ทธ๋ํ(Dependency Graph) ๋ฅผ ๋ง๋ค๊ณ , ๋ถํ์ํ ์ฝ๋ ์ ๊ฑฐ(Tree-shaking)์ ํจ๊ป ์ต์ข ๋ฒ๋ค ํ์ผ(bundle.js)๋ก ๋ฌถ์ด ์ฃผ์ด ํจ์จ์ ์ธ ๋ก๋ฉ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๋ชจ๋ ๋ฒ๋ค๋ง (Module Bundling) : ์ฌ๋ฌ ๊ฐ ํ์ผ์ ํ๋์ ๋ฒ๋ค๋ก ๋ฌถ์
- ๋ก๋ ์ ์ฉ : Babel, TypeScript ๊ฐ์ Loader๋ฅผ ํตํด ES6 -> ES5 ๋ณํ ์ ์ฉ, TS -> JS ๋ณํ ์ ์ฉ
- ์์ ๊ด๋ฆฌ (CSS, ์ด๋ฏธ์ง, ํฐํธ ๋ฑ) : ํจ์จ์ ์ธ CSS ์ ์ด๋ฏธ์ง/ํฐํธ ๊ด๋ฆฌ
- css-loader, style-loader → CSS ๊ด๋ฆฌ
- asset/resource, file-loader → ์ด๋ฏธ์ง/ํฐํธ ๊ด๋ฆฌ
- ์ต์ ํ(Tree Shaking, Code Splitting) : ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ค์ด๋ ๋ค์ํ ์ต์ ํ ๊ธฐ๋ฅ์ ์ ๊ณต
- ๊ฐ๋ฐ ์๋ฒ(HMR) : webpack-dev-server ๋ฅผ ํ์ฉํ์ฌ HMR(Hot Module Replacement) ์ ์ฉ
HMR(Hot Module Replacement)
https://webpack.kr/guides/hot-module-replacement/
Hot Module Replacement | ์นํฉ
์นํฉ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ ๋๋ค. ์ฃผ์ ๋ชฉ์ ์ ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉํ ์ ์๋๋ก JavaScript ํ์ผ์ ๋ฒ๋ค๋ก ๋ฌถ๋ ๊ฒ์ด์ง๋ง, ๋ฆฌ์์ค๋ ์ ์ ์ ๋ณํํ๊ณ ๋ฒ๋ค๋ง ๋๋ ํจํค์งํ ์๋ ์์ต๋๋ค.
webpack.kr
Hot Module Replacement(๋๋ HMR)๋ webpack์์ ์ ๊ณตํ๋ ๊ฐ์ฅ ์ ์ฉํ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค.
Hot Module Replacement (HMR) ์ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ค์ ๋ชจ๋์ ๊ต์ฒดํ๋ ๊ธฐ๋ฅ์ ๋๋ค.
์ฝ๋๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ ์ฒด ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ์ง ์๊ณ , ๋ฐ๋ ๋ชจ๋๋ง ๊ต์ฒดํด์ UI์ ๋ฐ์ํฉ๋๋ค.
// ๊ฐ๋ฐ ์๋ฒ ์ค์ (webpack-dev-server)
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 3000,
open: true,
hot: true, // HMR(Hot Module Replacement) ํ์ฑํ
historyApiFallback: true,
},
HMR with Stylesheets
CSS ์์กด์ฑ์ด ์ ๋ฐ์ดํธ๋ ๋ <style>ํ๊ทธ๋ฅผ ํจ์นํ๊ธฐ ์ํด ๋ฐฑ๊ทธ๋ผ์ด๋์์ module.hot.accept๋ฅผ ์ฌ์ฉ
=> ์๋ก๊ณ ์นจ ์์ด๋ ์คํ์ผ์ด ๋ฐ์
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
},
devtool: 'inline-source-map',
devServer: {
static: './dist',
hot: true,
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Hot Module Replacement',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
๐ฆ Webpack ์ด๊ธฐ ์ค์ ๊ฐ์ด๋
1. ํ๋ก์ ํธ ์ด๊ธฐํ
mkdir my-webpack-app
cd my-webpack-app
npm init -y
- npm init -y → package.json ์๋ ์์ฑ
2. Webpack ์ค์น
npm install --save-dev webpack webpack-cli
- webpack → ๋ฒ๋ค๋ฌ
- webpack-cli → CLI ๋ช ๋ น์ด ์คํ ๋๊ตฌ
3. ๊ธฐ๋ณธ ํ๋ก์ ํธ ๊ตฌ์กฐ
my-webpack-app/
โโโ src/
โ โโโ index.js # ์ํธ๋ฆฌ ํฌ์ธํธ
โโโ dist/
โ โโโ index.html # ์ต์ข
๋น๋๋ ํ์ผ์ ๋ก๋
โโโ package.json
- src/ : ๊ฐ๋ฐ์ฉ ์์ค ์ฝ๋
- dist/ : ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ค์ด๊ฐ ํด๋
4. Webpack ๊ธฐ๋ณธ ์ค์ ํ์ผ
ํ๋ก์ ํธ ๋ฃจํธ์ webpack.config.js ์์ฑ:
const path = require("path");
module.exports = {
entry: "./src/index.js", // ์์์
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js", // ๋ฒ๋ค ํ์ผ ์ด๋ฆ
},
mode: "development", // "development" | "production"
};
5. index.html ์์ฑ
dist/index.html์ ๋ฒ๋ค๋ง๋ JS ํ์ผ์ ๋ก๋ํ๋๋ก ์ค์ ํฉ๋๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Webpack App</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
6. ๋น๋ ์คํ
package.json์ script ์ถ๊ฐ:
"scripts": {
"build": "webpack"
}
์คํ:
npm run build
- dist/bundle.js ํ์ผ ์์ฑ๋จ
- index.html์์ ๋ก๋ ๊ฐ๋ฅ
7. ๊ฐ๋ฐ ์๋ฒ (์ ํ)
ํธ๋ฆฌํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ํด webpack-dev-server๋ฅผ ์ถ๊ฐํฉ๋๋ค.
npm install --save-dev webpack-dev-server
webpack.config.js ์์ :
devServer: {
static: "./dist", // ์ ์ ํ์ผ ์ ๊ณต ๊ฒฝ๋ก
open: true, // ์๋์ผ๋ก ๋ธ๋ผ์ฐ์ ์ด๊ธฐ
hot: true, // HMR (Hot Module Replacement)
}
package.json ์คํฌ๋ฆฝํธ ์ถ๊ฐ:
"scripts": {
"start": "webpack serve --open"
}
8. ์ถ๊ฐ ๊ธฐ๋ฅ (์ ํ)
- Babel (์ต์ JS ๋ณํ):
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"] } } } ] } - npm install --save-dev babel-loader @babel/core @babel/preset-env
- CSS ๋ก๋:
module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] } ] } - npm install --save-dev style-loader css-loader
์ฌ๊ธฐ๊น์ง ํ๋ฉด Webpack ๊ธฐ๋ณธ ํ๊ฒฝ ์ธํ
์๋ฃ์
๋๋ค.
๐ฆ Babel + TS configuarion ๊ตฌ์ฑ
์ด์ ๊ธฐ๋ณธ Webpack ์ธํ ์ ์ด์ด Babel + TS configuarion ์ค์ ์ ํด์ผํฉ๋๋ค.
Babel๊ณผ TypeScript๋ฅผ Webpack ํ๊ฒฝ์ ํตํฉํ๋ ค๋ฉด ๋ ๊ฐ์ง ์ ๊ทผ์ด ์์ต๋๋ค.
- ts-loader (TypeScript ์ปดํ์ผ๋ฌ๋ฅผ ์ง์ ์ฌ์ฉ)
- babel-loader + @babel/preset-typescript (Babel๋ก TS → JS ๋ณํ)
์ต๊ทผ ํ๋ก ํธ์๋์์๋ Babel ๊ธฐ๋ฐ ์ค์ ์ ๋ง์ด ์๋๋ค. (๋น ๋ฅด๊ณ Babel ํ๋ฌ๊ทธ์ธ ์ํ๊ณ ํ์ฉ ๊ฐ๋ฅ)
์๋๋ Babel + TypeScript + Webpack ์ค์ ๊ฐ์ด๋์
๋๋ค.
1. ์์กด์ฑ ์ค์น
npm install --save-dev \
typescript \
@babel/core \
@babel/preset-env \
@babel/preset-typescript \
babel-loader \
webpack webpack-cli webpack-dev-server
- typescript → ํ์ ๊ฒ์ฌ
- @babel/preset-env → ์ต์ JS๋ฅผ ๋ธ๋ผ์ฐ์ ํธํ ์ฝ๋๋ก ๋ณํ
- @babel/preset-typescript → TS ๊ตฌ๋ฌธ์ JS๋ก ๋ณํ
- babel-loader → Babel์ Webpack์์ ์ฌ์ฉ
2. ํ๋ก์ ํธ ๊ตฌ์กฐ
my-app/
โโโ src/
โ โโโ index.ts
โโโ dist/
โ โโโ index.html
โโโ tsconfig.json
โโโ babel.config.js
โโโ webpack.config.js
โโโ package.json
3. Babel ์ค์ (babel.config.js)
module.exports = {
presets: [
["@babel/preset-env", { targets: "defaults" }],
"@babel/preset-typescript"
]
};
4. TypeScript ์ค์ (tsconfig.json)
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true // Babel์ด ๋ณํํ๋ฏ๋ก TS๋ ํ์ผ ์ถ๋ ฅ ์ ํจ
},
"include": ["src"]
}
โ ๏ธ noEmit: true๋ก ์ค์ ํด์ผ TypeScript๊ฐ JS ํ์ผ์ ๋ฐ๋ก ๋ด๋ณด๋ด์ง ์๊ณ ํ์ ์ฒดํฌ๋ง ์ํํฉ๋๋ค.
5. Webpack ์ค์ (webpack.config.js)
const path = require("path");
module.exports = {
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
resolve: {
extensions: [".ts", ".js"], // import ์ ํ์ฅ์ ์๋ต ๊ฐ๋ฅ
},
module: {
rules: [
{
test: /\.tsx?$/, // .ts, .tsx ํ์ผ
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
devServer: {
static: "./dist",
open: true,
hot: true,
},
mode: "development"
};
6. ์คํ ์คํฌ๋ฆฝํธ (package.json)
"scripts": {
"build": "webpack",
"start": "webpack serve --open",
"type-check": "tsc --noEmit"
}
7. ์ํ ์ฝ๋ (src/index.ts)
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("์์ฐ"));
โ ๋์ ์๋ฆฌ
- tsc --noEmit → ํ์ ๊ฒ์ฌ ์ ์ฉ
- babel-loader → .ts ํ์ผ์ ์ฝ์ด์ JS๋ก ๋ณํ
- @babel/preset-env → ๋ธ๋ผ์ฐ์ ํธํ ์ฝ๋๋ก ๋ณํ
- ์ต์ข ๋ฒ๋ค์ dist/bundle.js๋ก ์์ฑ
์ฌ๊ธฐ์ ์ ํ์ง๊ฐ ์๋๋ฐ์.
- ํ์ ๊ฒ์ฌ ์๋๋ฅผ ๋์ด๊ณ ์ถ๋ค → fork-ts-checker-webpack-plugin ์ถ๊ฐ
- React + TS + Babel ํ๊ฒฝ์ ๋ง๋ค๊ณ ์ถ๋ค → @babel/preset-react ์ถ๊ฐ
'๐ ํ๋ก ํธ์๋(FE)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์น ์ ๋๋ฉ์ด์ ์ ๋๋ก ํ์ฉํ๊ธฐ: Transition, Keyframes, rAF, WAAPI ๋น๊ต์ ํ์ฉ๋ฒ (0) | 2025.09.24 |
|---|---|
| Webpack Tree Shaking ๋์ ์๋ฆฌ (0) | 2025.09.17 |
| MVC ๊ตฌ์กฐ - ์ต์ ๋ฒ ํจํด ( Observer Pattern ) (0) | 2025.09.08 |
| [Javascript] ์ด๋ฒคํธ ์ ํ & ์ด๋ฒคํธ ์์ (1) | 2025.09.08 |
| [CoderPad] ๋ฆฌ์กํธ ๊ฐ์ ์คํฌ๋กค (Virtualized List) (5) | 2025.06.22 |