[๊ฐ๋ฐํ๊ฒฝ]
npm: 10.5.0
Node.js: 18.20.2
00. ๊ฐ์
Create React App(CRA)๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก์ ํธ ์ด๊ธฐ ์ค์ ์ด ๋งค์ฐ ๊ฐ๋จํ๊ณ ๋น ๋ฅด๊ฒ ํ ์ ์๋ค. ํ์ง๋ง ๊ธฐ๋ณธ์ ์ธ ์ค์ ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํน์ ์์ ์ด๋ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ ์ปค์คํฐ๋ง์ด์ง ํ๊ธฐ ์ด๋ ต๋ค. ๋ํ, ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํฌํจํ์ฌ ๋ฒ๋ค์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ฒ๋ค ํฌ๊ธฐ๊ฐ ์ปค์ง๋ค๋ ์ ์ด ์ ๊ฒฝ์ฐ์๊ณ , ๋ฌด์๋ณด๋ค ์ง์ ์นํฉ์ ์ค์ ํด์ ๊ฐ๋ฐํ๊ฒฝ์ ๊ตฌ์ฑํด ๋ณด๊ณ ์ถ์๋ค.
01. ์นํฉ(Webpack)์ด๋?
์นํฉ์ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์ ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ด๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒ๋ฆฌํ ๋ ํ๋ก์ ํธ์ ํ์ํ ๋ชจ๋ ๋ชจ๋์ ๋งคํํ๊ณ ํ๋ ์ด์์ ๋ฒ๋ค์ ์์ฑํ๋ค. ์ด๋ ๊ฐ๋ฐ๊ณผ์ ์ ๋จ์ํํ๊ณ , ์ฝ๋๋ฅผ ์ต์ ํํ์ฌ ์น ์ฌ์ดํธ์ ์ฑ๋ฅ์ ํฅ์์ํจ๋ค.
02. package.json ์์ฑ
npm init ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ package.json ํ์ผ์ ์์ฑํ๋ค.
$ npm init
์ด ํ์ผ์ ํ๋ก์ ํธ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๋ ์ญํ ์ ํ๋ค.

๋ํ, ํ๋ก์ ํธ ํด๋ ๋ด์ dist, public, src ํด๋๋ฅผ ์์ฑํ์ฌ ๊ฐ๋ฐ์ ํ์ํ ๊ตฌ์กฐ๋ฅผ ๋ง๋ จํ๋ค.
$ mkdir dist public src
public ํด๋ ์๋์ index.html ๋ง๋ค์ด์ค๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React</title>
</head>
<body>
<div id="root"></div>
<script src="main.bundle.js"></script>
</body>
</html>
03. React ์ค์น
npm install react react-dom ๋ช ๋ น์ด๋ฅผ ํตํด React์ ReactDOM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๋ค.
$ npm install react react-dom
- React:
- ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- React๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ์ ๊ฐ๋ฐ์ ์ง์ํ๋ฉฐ, ์ ์ธ์ ์ธ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ UI ๊ตฌ์ฑํ ์ ์๋ค.
- React๋ ๊ฐ์ DOM(Virtual DOM)์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ , ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ด๋ฆฌํ๋ค.
- ReactDOM:
- React ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ธ๋ผ์ฐ์ ์์ ๋ ๋๋งํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ DOM์ ์ฌ์ฉํ์ฌ UI๋ฅผ ์์ฑํ๋ฉฐ, ์ด๋ฅผ ์ค์ DOM์ ์ ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ์ ํ์ํ๋ค.
- ReactDOM์ React Native์ ๊ฐ์ ๋ค๋ฅธ ํ๋ซํผ์์๋ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ํด๋น ํ๋ซํผ์ ์ ํฉํ ๋ ๋๋ง ์์ง์ ์ ๊ณตํ๋ค.
04. babel ์ค์น ๋ฐ ์ค์
Babel์ ์ต์ JavaScript ์ฝ๋๋ฅผ ์ด์ ๋ฒ์ ์ผ๋ก ๋ณํํ๋ JavaScript ์ปดํ์ผ๋ฌ์ด๋ค. ์ด๋ฅผ ํตํด React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋, ์ต์ JavaScript ๋ฌธ๋ฒ๊ณผ JSX ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค. ์๋ ๋ช ๋ น์ด๋ก ์ค์นํ๋ค.
$ npm install @babel/core @babel/preset-env @babel/preset-react babel-loader
- @babel/core:
- Babel์ ํต์ฌ ์์ง์ด๋ค. ์ด ์์ง์ JavaScript ์ฝ๋๋ฅผ ํ์ฑํ๊ณ ๋ณํํ๋ ์ญํ ์ ํ๋ค.
- Babel์ ์ต์ JavaScript ๋ฌธ๋ฒ์ ์ด์ ๋ฒ์ ์ผ๋ก ๋ณํํ๊ฑฐ๋, JSX์ ๊ฐ์ ํ์ฅ ๋ฌธ๋ฒ์ JavaScript๋ก ๋ณํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- @babel/preset-env:
- Babel์ ํ๋ฆฌ์ (preset) ์ค ํ๋์ด๋ค.
- ์ด ํ๋ฆฌ์ ์ ํ์ฌ ํ๊ฒฝ์์ ์ง์๋๋ ์ต์ JavaScript ๋ฌธ๋ฒ๋ง์ ์ฌ์ฉํ์ฌ ์ฝ๋๋ฅผ ๋ณํํ๋ค. ์ฆ, ๋ธ๋ผ์ฐ์ ์ ์ง์ ๋ฒ์์ ๋ฐ๋ผ ํ์ํ ๋ณํ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ค.
- @babel/preset-react:
- React ์ ํ๋ฆฌ์ผ์ด์ ์์ JSX ๋ฌธ๋ฒ์ JavaScript๋ก ๋ณํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- JSX๋ React์์ ์ฌ์ฉ๋๋ ๋ฌธ๋ฒ์ผ๋ก, JavaScript์ ํ์ฅ ๋ฌธ๋ฒ์ด๋ค. ์ด๋ฅผ ์ผ๋ฐ์ ์ธ JavaScript๋ก ๋ณํํ์ฌ ๋ธ๋ผ์ฐ์ ์์ ์คํํ ์ ์๋๋ก ํ๋ค.
- babel-loader:
- ์นํฉ(Webpack)์์ Babel์ ์ฌ์ฉํ์ฌ JavaScript ํ์ผ์ ๋ก๋ํ๊ณ ๋ณํํ๋ ๋ก๋์ด๋ค.
- ์นํฉ์ ๋ก๋ ์ค ํ๋๋ก, JavaScript ํ์ผ์ ๋ฒ๋ค๋งํ๋ ๋์ Babel์ ์ฌ์ฉํ์ฌ ES6+ ๋ฌธ๋ฒ์ด๋ JSX๋ฅผ ์ด์ ๋ฒ์ ์ JavaScript๋ก ๋ณํํ๋ค.
babel.config.js ํ์ผ์ ์์ฑํ์ฌ Babel์ ์ค์ ์ ์ ์ํ๋ค.
// babel.config.js
module.exports = {
presets: [
"@babel/preset-env",
[
"@babel/preset-react",
{
runtime: "automatic",
},
],
],
};
05. webpack ์ค์น ๋ฐ ์ค์
์นํฉ์ ์ค์นํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋ฒ๋ค๋งํ๋ ์ค์ ์ ์งํํ๋ค.
$ npm install webpack webpack-cli webpack-dev-server
- webpack:
- ์นํฉ(Webpack)์ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ก, ์ฌ๋ฌ ๋ชจ๋๊ณผ ๋ฆฌ์์ค๋ค์ ํ๋๋ก ๋ฌถ์ด ์ต์ ํ๋ ๋ฒ๋ค์ ์์ฑํ๋ค.
- JavaScript, CSS, ์ด๋ฏธ์ง ๋ฑ ๋ค์ํ ๋ฆฌ์์ค๋ฅผ ๋ชจ๋๋ก ์ทจ๊ธํ์ฌ ๊ด๋ฆฌํ๊ณ , ์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์๋ค.
- webpack-cli:
- ์นํฉ์ ๋ช ๋ น์ค์์ ์ฌ์ฉํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ช ๋ น์ค ์ธํฐํ์ด์ค(Command Line Interface)์ด๋ค.
- ์ด๋ฅผ ํตํด ํฐ๋ฏธ๋์์ ์นํฉ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ์คํํ ์ ์๋ค.
- webpack-dev-server:
- ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ ๊ณตํ์ฌ ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ๊ณ ๋น๋๋ ๊ฒฐ๊ณผ๋ฌผ์ ๋ธ๋ผ์ฐ์ ์ ์ ๊ณตํ๋ค.
- ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ๋ ๋์ ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ ์ ์์ผ๋ฉฐ, ๋น ๋ฅธ ๋ฐ๋ณต ๋ฐ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์๋ค.
webpack.config.js ์นํฉ ์ค์ ํ์ผ์ ์์ฑํ์ฌ ๋ฒ๋ค๋ง ๋์์ ๊ตฌ์ฑํ๋ค. ๋ก๋(loader)์ ํ๋ฌ๊ทธ์ธ(plugin)์ ์ค์ ํ์ฌ ์นํฉ์ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๋ค.
// webpack.config.js
const path = require("path");
module.exports = {
mode: "development",
entry: {
main: "./src/main.js", // ๋ฒ๋ค๋ง ์์ ํ์ผ ์ค์
},
/* ๋ฒ๋ค๋ง๋ ๊ฒฐ๊ณผ๋ฌผ์ ํ์ผ๋ช
๊ณผ ๊ฒฝ๋ก ์ค์ */
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].bundle.js",
clean: true, // ๋น๋ ์ output ํด๋์ ์ญ์ ํ ๋ค์ ํ์ผ๋ค์ ๋ฃ์ด์ฃผ๋ ๊ธฐ๋ฅ
},
resolve: {
extensions: [".js", ".jsx"],
},
devtool: "source-map",
devServer: {
static: path.resolve(__dirname, "public"),
hot: true, // ์ ์ฅํ ๋๋ง๋ค ์์ ์ฌํญ ๋ฐ์
open: true, // ๋ธ๋ผ์ฐ์ ์๋ ์คํ
port: 3000 // process.env.PORT,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
};
- mode:
- ํ์ฌ ๊ฐ๋ฐ ๋ชจ๋๋ฅผ ์ค์ ํ๋ค. "development"๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ๊ฐ๋ฐ์ฉ ์ค์ ์ด ์ ์ฉ๋๋ค. ๋น๋๋ ํ์ผ์ด ์์ถ๋์ง ์๊ณ , ์ถ๊ฐ์ ์ธ ๋๋ฒ๊น ๊ธฐ๋ฅ์ด ํ์ฑํ๋๋ค.
- entry:
- ๋ฒ๋ค๋ง์ ์์์ (entry point)์ ์ค์ ํ๋ค. "./src/main.js" ํ์ผ์ ์์์ผ๋ก ๋ชจ๋ ์์กด ๋ชจ๋์ ์ฐพ์ ๋ฒ๋ค๋งํ๋ค.
- output:
- ๋ฒ๋ค๋ง๋ ๊ฒฐ๊ณผ๋ฌผ์ ํ์ผ๋ช ๊ณผ ๊ฒฝ๋ก๋ฅผ ์ค์ ํ๋ค.
- path ์์ฑ์ ๋ฒ๋ค๋ ํ์ผ์ ์ถ๋ ฅ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ค.
- filename ์์ฑ์ ์ถ๋ ฅ๋๋ ๋ฒ๋ค ํ์ผ์ ์ด๋ฆ์ ์ง์ ํ๋ค. [name]์ entry์์ ์ค์ ํ ํค ์ด๋ฆ(main)์ผ๋ก ๋์ฒด๋๋ค.
- clean ์์ฑ์ ๋น๋ ์ output ํด๋์ ๋ด์ฉ์ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ ์ค์ ํ๋ค.
- resolve:
- ๋ชจ๋์ ํด์ํ๋ ๋ฐฉ๋ฒ์ ์ค์ ํ๋ค.
- extensions ์์ฑ์ ๋ชจ๋ ํ์ผ์ ํ์ฅ์๋ฅผ ๋ํ๋ธ๋ค. ์ฌ๊ธฐ์๋ .js์ .jsx ํ์ผ์ ํด์ํ๋ค.
- devtool:
- ์์ค ๋งต(Source Map)์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ค์ ํ๋ค. "source-map"์ผ๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ์์ค ๋งต ํ์ผ์ด ๋ณ๋๋ก ์์ฑ๋๋ค.
- devServer:
- ๊ฐ๋ฐ ์๋ฒ ์ค์ ์ ์ ์ํ๋ค.
- static ์์ฑ์ ์ ์ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ค.
- hot ์์ฑ์ HMR(Hot Module Replacement) ๊ธฐ๋ฅ์ ํ์ฑํํ๋ค. ์ ์ฅํ ๋๋ง๋ค ์์ ์ฌํญ์ด ๋ฐ์๋๋ค.
- open ์์ฑ์ ์๋ฒ๋ฅผ ์คํํ ๋ ์๋์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฐ๋ค.
- port ์์ฑ์ ๊ฐ๋ฐ ์๋ฒ์ ํฌํธ ๋ฒํธ๋ฅผ ์ค์ ํ๋ค.
- module/rules:
- ๋ชจ๋์ ํด์ํ ๋ ์ ์ฉํ ๊ท์น์ ์ค์ ํ๋ค.
- ์ฌ๊ธฐ์๋ .js์ .jsx ํ์ฅ์๋ฅผ ๊ฐ์ง ํ์ผ์ ๋ํด Babel ๋ก๋๋ฅผ ์ ์ฉํ์ฌ ES6+ ๋ฌธ๋ฒ๊ณผ JSX ๋ฌธ๋ฒ์ ๋ณํํ๋ค.
React ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด๋ณด์. src ํด๋ ์๋์ main.js์ App.jsx ์์ฑํ๋ค.
// /src/main.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
// /src/App.jsx
const App = () => <>Hello React</>;
export default App;
package.json ํ์ผ์์ script ๋ถ๋ถ์ start๋ฅผ ์์ฑํ๋ค.
{
"name": "react_toy_project",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --config webpack.config.js"
},
"author": "Jiwon Hyeon",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.24.5",
"@babel/preset-env": "^7.24.5",
"@babel/preset-react": "^7.24.1",
"babel-loader": "^9.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
}
}
์ด ํ์ผ์ ํ๋ก์ ํธ์ ๋ฉํ๋ฐ์ดํฐ์ ์์กด์ฑ ํจํค์ง ์ ๋ณด๋ฅผ ์ ์ํ๋ค. ํด๋น ํ์ผ์ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ์ ์ค์ ์ ๊ด๋ฆฌํ๊ณ , ํ์ํ ํจํค์ง๋ค์ ๊ด๋ฆฌํ๋ฉฐ, npm ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์๋ค.
- name: ํ๋ก์ ํธ์ ์ด๋ฆ. npm ๋ ์ง์คํธ๋ฆฌ์์ ํ๋ก์ ํธ๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- version: ํ๋ก์ ํธ์ ํ์ฌ ๋ฒ์ . ๋ฒ์ ์ Semantic Versioning(SemVer) ๊ท์น์ ๋ฐ๋ผ ์ง์ ๋๋ค.
- description: ํ๋ก์ ํธ์ ๋ํ ๊ฐ๋จํ ์ค๋ช ์ ๋ธ๋ค. ์ด ์์ฑ์ ์ ํ์ ์ด๋ฉฐ, ํ๋ก์ ํธ์ ๋ชฉ์ ์ด๋ ํน์ง์ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ ์ ์๋ค.
- scripts: ํ๋ก์ ํธ์์ ์ฌ์ฉํ ์ ์๋ npm ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ํ๋ค. "test"์ "start" ์คํฌ๋ฆฝํธ๊ฐ ์ ์๋์ด ์๋ค.
- "test": ํ ์คํธ๋ฅผ ์คํํ๋ ๋ช ๋ น์ด๋ฅผ ์ ์. ํ ์คํธ๊ฐ ์ง์ ๋์ง ์์์ผ๋ฏ๋ก ์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๋ค.
- "start": ํ๋ก์ ํธ๋ฅผ ์คํํ๋ ๋ช ๋ น์ด๋ฅผ ์ ์. webpack serve ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์คํํ ์ ์๋ค.
- author: ํ๋ก์ ํธ์ ์ ์์ ๋๋ ๊ฐ๋ฐ์๋ฅผ ๋ํ๋ธ๋ค.
- license: ํ๋ก์ ํธ์ ๋ผ์ด์ ์ค๋ฅผ ๋ํ๋ธ๋ค
- dependencies: ํ๋ก์ ํธ๊ฐ ์์กดํ๋ ํจํค์ง๋ค์ ๋ํ๋ด๋ฉฐ, ๊ฐ ํจํค์ง์ ์ด๋ฆ๊ณผ ๋ฒ์ ์ด ํฌํจ๋์ด ์๋ค.
06. ์คํ
npm start ๋ช ๋ น์ด๋ก ์๋ฒ๋ฅผ ์คํ์ํจ๋ค.
$ npm start

์ด๋ฅผ ํตํด ๊ฐ๋ฐ ์๋ฒ๊ฐ ์์๋๊ณ , ํ๋ก์ ํธ๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ํ์ธํ ์ ์๋ค.

์ ์ฒด ์ฝ๋
github Repository - 2024.05.10. ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ - webpack ์ค์
2024.05.10. ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ - webpack ์ค์ ยท Hyeonjiwon/React_Toy_Project@51d9aa0
Hyeonjiwon committed May 10, 2024
github.com
[๊ฐ๋ฐํ๊ฒฝ]
npm: 10.5.0
Node.js: 18.20.2
00. ๊ฐ์
Create React App(CRA)๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก์ ํธ ์ด๊ธฐ ์ค์ ์ด ๋งค์ฐ ๊ฐ๋จํ๊ณ ๋น ๋ฅด๊ฒ ํ ์ ์๋ค. ํ์ง๋ง ๊ธฐ๋ณธ์ ์ธ ์ค์ ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํน์ ์์ ์ด๋ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ ์ปค์คํฐ๋ง์ด์ง ํ๊ธฐ ์ด๋ ต๋ค. ๋ํ, ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํฌํจํ์ฌ ๋ฒ๋ค์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ฒ๋ค ํฌ๊ธฐ๊ฐ ์ปค์ง๋ค๋ ์ ์ด ์ ๊ฒฝ์ฐ์๊ณ , ๋ฌด์๋ณด๋ค ์ง์ ์นํฉ์ ์ค์ ํด์ ๊ฐ๋ฐํ๊ฒฝ์ ๊ตฌ์ฑํด ๋ณด๊ณ ์ถ์๋ค.
01. ์นํฉ(Webpack)์ด๋?
์นํฉ์ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์ ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ์ด๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒ๋ฆฌํ ๋ ํ๋ก์ ํธ์ ํ์ํ ๋ชจ๋ ๋ชจ๋์ ๋งคํํ๊ณ ํ๋ ์ด์์ ๋ฒ๋ค์ ์์ฑํ๋ค. ์ด๋ ๊ฐ๋ฐ๊ณผ์ ์ ๋จ์ํํ๊ณ , ์ฝ๋๋ฅผ ์ต์ ํํ์ฌ ์น ์ฌ์ดํธ์ ์ฑ๋ฅ์ ํฅ์์ํจ๋ค.
02. package.json ์์ฑ
npm init ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ package.json ํ์ผ์ ์์ฑํ๋ค.
$ npm init
์ด ํ์ผ์ ํ๋ก์ ํธ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๋ ์ญํ ์ ํ๋ค.

๋ํ, ํ๋ก์ ํธ ํด๋ ๋ด์ dist, public, src ํด๋๋ฅผ ์์ฑํ์ฌ ๊ฐ๋ฐ์ ํ์ํ ๊ตฌ์กฐ๋ฅผ ๋ง๋ จํ๋ค.
$ mkdir dist public src
public ํด๋ ์๋์ index.html ๋ง๋ค์ด์ค๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React</title>
</head>
<body>
<div id="root"></div>
<script src="main.bundle.js"></script>
</body>
</html>
03. React ์ค์น
npm install react react-dom ๋ช ๋ น์ด๋ฅผ ํตํด React์ ReactDOM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๋ค.
$ npm install react react-dom
- React:
- ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- React๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ์ ๊ฐ๋ฐ์ ์ง์ํ๋ฉฐ, ์ ์ธ์ ์ธ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ UI ๊ตฌ์ฑํ ์ ์๋ค.
- React๋ ๊ฐ์ DOM(Virtual DOM)์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ , ์ปดํฌ๋ํธ ๊ฐ์ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ด๋ฆฌํ๋ค.
- ReactDOM:
- React ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ธ๋ผ์ฐ์ ์์ ๋ ๋๋งํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ DOM์ ์ฌ์ฉํ์ฌ UI๋ฅผ ์์ฑํ๋ฉฐ, ์ด๋ฅผ ์ค์ DOM์ ์ ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ์ ํ์ํ๋ค.
- ReactDOM์ React Native์ ๊ฐ์ ๋ค๋ฅธ ํ๋ซํผ์์๋ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ํด๋น ํ๋ซํผ์ ์ ํฉํ ๋ ๋๋ง ์์ง์ ์ ๊ณตํ๋ค.
04. babel ์ค์น ๋ฐ ์ค์
Babel์ ์ต์ JavaScript ์ฝ๋๋ฅผ ์ด์ ๋ฒ์ ์ผ๋ก ๋ณํํ๋ JavaScript ์ปดํ์ผ๋ฌ์ด๋ค. ์ด๋ฅผ ํตํด React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋, ์ต์ JavaScript ๋ฌธ๋ฒ๊ณผ JSX ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค. ์๋ ๋ช ๋ น์ด๋ก ์ค์นํ๋ค.
$ npm install @babel/core @babel/preset-env @babel/preset-react babel-loader
- @babel/core:
- Babel์ ํต์ฌ ์์ง์ด๋ค. ์ด ์์ง์ JavaScript ์ฝ๋๋ฅผ ํ์ฑํ๊ณ ๋ณํํ๋ ์ญํ ์ ํ๋ค.
- Babel์ ์ต์ JavaScript ๋ฌธ๋ฒ์ ์ด์ ๋ฒ์ ์ผ๋ก ๋ณํํ๊ฑฐ๋, JSX์ ๊ฐ์ ํ์ฅ ๋ฌธ๋ฒ์ JavaScript๋ก ๋ณํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- @babel/preset-env:
- Babel์ ํ๋ฆฌ์ (preset) ์ค ํ๋์ด๋ค.
- ์ด ํ๋ฆฌ์ ์ ํ์ฌ ํ๊ฒฝ์์ ์ง์๋๋ ์ต์ JavaScript ๋ฌธ๋ฒ๋ง์ ์ฌ์ฉํ์ฌ ์ฝ๋๋ฅผ ๋ณํํ๋ค. ์ฆ, ๋ธ๋ผ์ฐ์ ์ ์ง์ ๋ฒ์์ ๋ฐ๋ผ ํ์ํ ๋ณํ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ค.
- @babel/preset-react:
- React ์ ํ๋ฆฌ์ผ์ด์ ์์ JSX ๋ฌธ๋ฒ์ JavaScript๋ก ๋ณํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- JSX๋ React์์ ์ฌ์ฉ๋๋ ๋ฌธ๋ฒ์ผ๋ก, JavaScript์ ํ์ฅ ๋ฌธ๋ฒ์ด๋ค. ์ด๋ฅผ ์ผ๋ฐ์ ์ธ JavaScript๋ก ๋ณํํ์ฌ ๋ธ๋ผ์ฐ์ ์์ ์คํํ ์ ์๋๋ก ํ๋ค.
- babel-loader:
- ์นํฉ(Webpack)์์ Babel์ ์ฌ์ฉํ์ฌ JavaScript ํ์ผ์ ๋ก๋ํ๊ณ ๋ณํํ๋ ๋ก๋์ด๋ค.
- ์นํฉ์ ๋ก๋ ์ค ํ๋๋ก, JavaScript ํ์ผ์ ๋ฒ๋ค๋งํ๋ ๋์ Babel์ ์ฌ์ฉํ์ฌ ES6+ ๋ฌธ๋ฒ์ด๋ JSX๋ฅผ ์ด์ ๋ฒ์ ์ JavaScript๋ก ๋ณํํ๋ค.
babel.config.js ํ์ผ์ ์์ฑํ์ฌ Babel์ ์ค์ ์ ์ ์ํ๋ค.
// babel.config.js
module.exports = {
presets: [
"@babel/preset-env",
[
"@babel/preset-react",
{
runtime: "automatic",
},
],
],
};
05. webpack ์ค์น ๋ฐ ์ค์
์นํฉ์ ์ค์นํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋ฒ๋ค๋งํ๋ ์ค์ ์ ์งํํ๋ค.
$ npm install webpack webpack-cli webpack-dev-server
- webpack:
- ์นํฉ(Webpack)์ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ก, ์ฌ๋ฌ ๋ชจ๋๊ณผ ๋ฆฌ์์ค๋ค์ ํ๋๋ก ๋ฌถ์ด ์ต์ ํ๋ ๋ฒ๋ค์ ์์ฑํ๋ค.
- JavaScript, CSS, ์ด๋ฏธ์ง ๋ฑ ๋ค์ํ ๋ฆฌ์์ค๋ฅผ ๋ชจ๋๋ก ์ทจ๊ธํ์ฌ ๊ด๋ฆฌํ๊ณ , ์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์๋ค.
- webpack-cli:
- ์นํฉ์ ๋ช ๋ น์ค์์ ์ฌ์ฉํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ช ๋ น์ค ์ธํฐํ์ด์ค(Command Line Interface)์ด๋ค.
- ์ด๋ฅผ ํตํด ํฐ๋ฏธ๋์์ ์นํฉ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ์คํํ ์ ์๋ค.
- webpack-dev-server:
- ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ ๊ณตํ์ฌ ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ๊ณ ๋น๋๋ ๊ฒฐ๊ณผ๋ฌผ์ ๋ธ๋ผ์ฐ์ ์ ์ ๊ณตํ๋ค.
- ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ๋ ๋์ ์ค์๊ฐ์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ ์ ์์ผ๋ฉฐ, ๋น ๋ฅธ ๋ฐ๋ณต ๋ฐ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์๋ค.
webpack.config.js ์นํฉ ์ค์ ํ์ผ์ ์์ฑํ์ฌ ๋ฒ๋ค๋ง ๋์์ ๊ตฌ์ฑํ๋ค. ๋ก๋(loader)์ ํ๋ฌ๊ทธ์ธ(plugin)์ ์ค์ ํ์ฌ ์นํฉ์ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๋ค.
// webpack.config.js
const path = require("path");
module.exports = {
mode: "development",
entry: {
main: "./src/main.js", // ๋ฒ๋ค๋ง ์์ ํ์ผ ์ค์
},
/* ๋ฒ๋ค๋ง๋ ๊ฒฐ๊ณผ๋ฌผ์ ํ์ผ๋ช
๊ณผ ๊ฒฝ๋ก ์ค์ */
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].bundle.js",
clean: true, // ๋น๋ ์ output ํด๋์ ์ญ์ ํ ๋ค์ ํ์ผ๋ค์ ๋ฃ์ด์ฃผ๋ ๊ธฐ๋ฅ
},
resolve: {
extensions: [".js", ".jsx"],
},
devtool: "source-map",
devServer: {
static: path.resolve(__dirname, "public"),
hot: true, // ์ ์ฅํ ๋๋ง๋ค ์์ ์ฌํญ ๋ฐ์
open: true, // ๋ธ๋ผ์ฐ์ ์๋ ์คํ
port: 3000 // process.env.PORT,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
};
- mode:
- ํ์ฌ ๊ฐ๋ฐ ๋ชจ๋๋ฅผ ์ค์ ํ๋ค. "development"๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ๊ฐ๋ฐ์ฉ ์ค์ ์ด ์ ์ฉ๋๋ค. ๋น๋๋ ํ์ผ์ด ์์ถ๋์ง ์๊ณ , ์ถ๊ฐ์ ์ธ ๋๋ฒ๊น ๊ธฐ๋ฅ์ด ํ์ฑํ๋๋ค.
- entry:
- ๋ฒ๋ค๋ง์ ์์์ (entry point)์ ์ค์ ํ๋ค. "./src/main.js" ํ์ผ์ ์์์ผ๋ก ๋ชจ๋ ์์กด ๋ชจ๋์ ์ฐพ์ ๋ฒ๋ค๋งํ๋ค.
- output:
- ๋ฒ๋ค๋ง๋ ๊ฒฐ๊ณผ๋ฌผ์ ํ์ผ๋ช ๊ณผ ๊ฒฝ๋ก๋ฅผ ์ค์ ํ๋ค.
- path ์์ฑ์ ๋ฒ๋ค๋ ํ์ผ์ ์ถ๋ ฅ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ค.
- filename ์์ฑ์ ์ถ๋ ฅ๋๋ ๋ฒ๋ค ํ์ผ์ ์ด๋ฆ์ ์ง์ ํ๋ค. [name]์ entry์์ ์ค์ ํ ํค ์ด๋ฆ(main)์ผ๋ก ๋์ฒด๋๋ค.
- clean ์์ฑ์ ๋น๋ ์ output ํด๋์ ๋ด์ฉ์ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ ์ค์ ํ๋ค.
- resolve:
- ๋ชจ๋์ ํด์ํ๋ ๋ฐฉ๋ฒ์ ์ค์ ํ๋ค.
- extensions ์์ฑ์ ๋ชจ๋ ํ์ผ์ ํ์ฅ์๋ฅผ ๋ํ๋ธ๋ค. ์ฌ๊ธฐ์๋ .js์ .jsx ํ์ผ์ ํด์ํ๋ค.
- devtool:
- ์์ค ๋งต(Source Map)์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ค์ ํ๋ค. "source-map"์ผ๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ์์ค ๋งต ํ์ผ์ด ๋ณ๋๋ก ์์ฑ๋๋ค.
- devServer:
- ๊ฐ๋ฐ ์๋ฒ ์ค์ ์ ์ ์ํ๋ค.
- static ์์ฑ์ ์ ์ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ค.
- hot ์์ฑ์ HMR(Hot Module Replacement) ๊ธฐ๋ฅ์ ํ์ฑํํ๋ค. ์ ์ฅํ ๋๋ง๋ค ์์ ์ฌํญ์ด ๋ฐ์๋๋ค.
- open ์์ฑ์ ์๋ฒ๋ฅผ ์คํํ ๋ ์๋์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฐ๋ค.
- port ์์ฑ์ ๊ฐ๋ฐ ์๋ฒ์ ํฌํธ ๋ฒํธ๋ฅผ ์ค์ ํ๋ค.
- module/rules:
- ๋ชจ๋์ ํด์ํ ๋ ์ ์ฉํ ๊ท์น์ ์ค์ ํ๋ค.
- ์ฌ๊ธฐ์๋ .js์ .jsx ํ์ฅ์๋ฅผ ๊ฐ์ง ํ์ผ์ ๋ํด Babel ๋ก๋๋ฅผ ์ ์ฉํ์ฌ ES6+ ๋ฌธ๋ฒ๊ณผ JSX ๋ฌธ๋ฒ์ ๋ณํํ๋ค.
React ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด๋ณด์. src ํด๋ ์๋์ main.js์ App.jsx ์์ฑํ๋ค.
// /src/main.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
// /src/App.jsx
const App = () => <>Hello React</>;
export default App;
package.json ํ์ผ์์ script ๋ถ๋ถ์ start๋ฅผ ์์ฑํ๋ค.
{
"name": "react_toy_project",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack serve --config webpack.config.js"
},
"author": "Jiwon Hyeon",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.24.5",
"@babel/preset-env": "^7.24.5",
"@babel/preset-react": "^7.24.1",
"babel-loader": "^9.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
}
}
์ด ํ์ผ์ ํ๋ก์ ํธ์ ๋ฉํ๋ฐ์ดํฐ์ ์์กด์ฑ ํจํค์ง ์ ๋ณด๋ฅผ ์ ์ํ๋ค. ํด๋น ํ์ผ์ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ์ ์ค์ ์ ๊ด๋ฆฌํ๊ณ , ํ์ํ ํจํค์ง๋ค์ ๊ด๋ฆฌํ๋ฉฐ, npm ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์๋ค.
- name: ํ๋ก์ ํธ์ ์ด๋ฆ. npm ๋ ์ง์คํธ๋ฆฌ์์ ํ๋ก์ ํธ๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- version: ํ๋ก์ ํธ์ ํ์ฌ ๋ฒ์ . ๋ฒ์ ์ Semantic Versioning(SemVer) ๊ท์น์ ๋ฐ๋ผ ์ง์ ๋๋ค.
- description: ํ๋ก์ ํธ์ ๋ํ ๊ฐ๋จํ ์ค๋ช ์ ๋ธ๋ค. ์ด ์์ฑ์ ์ ํ์ ์ด๋ฉฐ, ํ๋ก์ ํธ์ ๋ชฉ์ ์ด๋ ํน์ง์ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ ์ ์๋ค.
- scripts: ํ๋ก์ ํธ์์ ์ฌ์ฉํ ์ ์๋ npm ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ํ๋ค. "test"์ "start" ์คํฌ๋ฆฝํธ๊ฐ ์ ์๋์ด ์๋ค.
- "test": ํ ์คํธ๋ฅผ ์คํํ๋ ๋ช ๋ น์ด๋ฅผ ์ ์. ํ ์คํธ๊ฐ ์ง์ ๋์ง ์์์ผ๋ฏ๋ก ์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๋ค.
- "start": ํ๋ก์ ํธ๋ฅผ ์คํํ๋ ๋ช ๋ น์ด๋ฅผ ์ ์. webpack serve ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์คํํ ์ ์๋ค.
- author: ํ๋ก์ ํธ์ ์ ์์ ๋๋ ๊ฐ๋ฐ์๋ฅผ ๋ํ๋ธ๋ค.
- license: ํ๋ก์ ํธ์ ๋ผ์ด์ ์ค๋ฅผ ๋ํ๋ธ๋ค
- dependencies: ํ๋ก์ ํธ๊ฐ ์์กดํ๋ ํจํค์ง๋ค์ ๋ํ๋ด๋ฉฐ, ๊ฐ ํจํค์ง์ ์ด๋ฆ๊ณผ ๋ฒ์ ์ด ํฌํจ๋์ด ์๋ค.
06. ์คํ
npm start ๋ช ๋ น์ด๋ก ์๋ฒ๋ฅผ ์คํ์ํจ๋ค.
$ npm start

์ด๋ฅผ ํตํด ๊ฐ๋ฐ ์๋ฒ๊ฐ ์์๋๊ณ , ํ๋ก์ ํธ๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ํ์ธํ ์ ์๋ค.

์ ์ฒด ์ฝ๋
github Repository - 2024.05.10. ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ - webpack ์ค์
2024.05.10. ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ - webpack ์ค์ ยท Hyeonjiwon/React_Toy_Project@51d9aa0
Hyeonjiwon committed May 10, 2024
github.com