๐Ÿ’ป ์คŒ ํด๋ก  ์ฑŒ๋ฆฐ์ง€ DAY+01

yhwaยท2023๋…„ 2์›” 20์ผ
0
post-thumbnail

๐Ÿ“ ์คŒ ํด๋ก ์ฝ”๋”ฉ: From #1.0 to #1.9

Express๋ฅผ ์‚ฌ์šฉํ•œ ์ผ๋ฐ˜์ ์ธ NodeJS์„ค์ •์ž…๋‹ˆ๋‹ค.
WebRTC์™€ Websockets๋ฅผ ํ™œ์šฉํ•œ Zoom ํด๋ก ์ฝ”๋”ฉ
Pug๋กœ view engine์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
Express์— template์ด ์–ด๋””์žˆ๋Š”์ง€ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค.
public url์„ ์ƒ์„ฑํ•ด์„œ ์œ ์ €์—๊ฒŒ ํŒŒ์ผ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
home.pug๋ฅผ ๋ Œ๋”ํ•ด์ฃผ๋Š” route handler๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.(server.js)

Node.js version

v16.18.0 (v14.17.3 ์ด์ƒ ํ•„์š”)

โ›ณ๏ธ NodeJS ๊ฐœ๋ฐœํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ

- package.json
- Babel
- Nodemon
  1. zoom ํด๋”๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋งŒ๋“  ํด๋” ๋‚ด์—์„œ ์ปค๋งจ๋“œ์ฐฝ npm init -y ์ž…๋ ฅํ•ด์„œ, package.json์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. package.json์—์„œ script์™€ main์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  4. Github์„ ๊ณ ๋ คํ•ด์„œ README.md๋„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Nodemon ์‚ฌ์šฉํ•˜๊ธฐ

- Nodemon์ด๋ž€, ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์„์‹œ, 
์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ด์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.
- ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•˜๋Š” ๋Œ€์‹ , babel-node๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
- Babel์ด๋ž€, ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์ผ๋ฐ˜ NodeJS๋กœ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.
- ๊ทธ ์ž‘์—…์„ src/server.js์—์„œ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค.
- server.jsํŒŒ์ผ์—์„œ๋Š” express๋ฅผ importํ•ด์„œ 
express ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.
- view engine์„ Pug๋กœ ์„ค์ •, views ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
- ๋˜ํ•œ, publicํŒŒ์ผ๋“ค์— ๋Œ€ํ•ด์„œ๋„ ๋˜‘๊ฐ™์€ ์ž‘์—…์„ ํ•ด์ฃผ๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.
- publicํด๋” ๋‚ด ํŒŒ์ผ๋“ค์€ Front์—์„œ ๊ตฌ๋™๋˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
- app.js๊ฐ€ ํ”„๋ก ํŠธ, server.js๊ฐ€ ๋ฐฑ์—”๋“œ์ž…๋‹ˆ๋‹ค.
- ์œ ์ €๋Š” /public์œผ๋กœ ์ด๋™ํ• ์‹œ, publicํด๋” ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- viewsํด๋”์— ์žˆ๋Š” home.pug๋ฅผ ๋ Œ๋”ํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค.
- babel-node๋ฅผ ์‹คํ–‰์‹œํ‚ค๋ฉด, babel-node๋Š” ๋ฐ”๋กœ
- babel.config.json์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
- ๊ทธ๊ณณ์—์„œ ์ฝ”๋“œ์— ์ ์šฉ์‹œํ‚ฌ preset๋ฅผ ์‹คํ–‰์‹œํ‚ต๋‹ˆ๋‹ค.
  1. npm i nodemon -D ๋กœ node_modules๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. babel๋„ ์„ค์น˜ํ•ด์•ผํ•˜๋ฏ€๋กœ, touch babel.config.js๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. nodemon.json ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  4. src ํด๋”๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค, ๊ทธ ์•ˆ์— server.js๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.
  5. git init. ์„ ํ†ตํ•ด, git๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  6. npm i @babel/core @babel/cli @babel/node -D ๋กœ ๋ฐ”๋ฒจ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
  7. touch .gitignore gitignore๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  8. .gitignore ํŒŒ์ผ ๋‚ด๋ถ€์—๋Š” /node_modules๋ฅผ ์ž…๋ ฅํ•ด์„œ git์ด ๋ชจ๋“ˆ์„ ๋ฌด์‹œํ•˜์—ฌ git ์—…๋กœ๋“œ์—์„œ ์ œ์™ธํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  9. nodemon.json ์—๋Š” exec ๋ช…๋ น์–ด๋ฅผ ํ•˜๋‚˜ ๋„ฃ์Šต๋‹ˆ๋‹ค. exec๋Š” server.js๋ฅผ ์‹คํ–‰์‹œํ‚ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
    ๐Ÿ‘‰ nodemon์€ exec๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด์„œ ์ด ๋ช…๋ น๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
{
    "exec": "babel-node src/server.js"
}
  1. babel.config.json์—์„œ๋Š” preset์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  2. npm i @babel/preset-env -D์œผ๋กœ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
  3. babel.config.json์—๋Š” ์šฐ๋ฆฌ์‚ฌ ์‚ฌ์šฉํ•  preset์ด ์ž…๋ ฅ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.
  4. package.json์—๋Š” scripts๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
    "dev"๋Š” nodemon์„ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
"scripts":{
	"dev": "nodemon"
}

nodemon์ด ํ˜ธ์ถœ๋˜๋ฉด nodemon์ด nodemon.json์„ ์‚ดํŽด๋ณด๊ณ , ๊ฑฐ๊ธฐ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
14. express๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. npm i express ์‹คํ–‰
15. pug๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. npm i pug ์‹คํ–‰
16. server.js์— express๋ฅผ importํ•ฉ๋‹ˆ๋‹ค.
17. server.js์—์„œ app์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

package.json

{
  "name": "zoom",
  "version": "1.0.0",
  "description": "Zoom Clone using WebRTC and Websockets",
  "keywords": [],
  "author": "",
  "license": "MIT",
  "scripts": {
    "dev": "nodemon"
  },
  "devDependencies": {
    "@babel/cli": "^7.20.7",
    "@babel/core": "^7.20.12",
    "@babel/node": "^7.20.7",
    "@babel/preset-env": "^7.20.2",
    "nodemon": "^2.0.20"
  },
  "dependencies": {
    "express": "^4.18.2",
    "pug": "^3.0.2"
  }
}

โ›ณ๏ธ ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

server.js์— Express App ๋งŒ๋“ค๊ธฐ

- app์€ console.log("hello")๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ํฌํŠธ 3000์„ listenํ•ฉ๋‹ˆ๋‹ค.
- ์ฝ˜์†”์ฐฝ์—์„œ npm run dev๋ฅผ ์‹คํ–‰์‹œ์ผœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
import express from "express";

const app = express();

console.log("hello, server");

app.listen(3000);

... ์ž‘์—…์„ ์œ„ํ•œ ํ”„๋กœ์ ํŠธ ์„ค์ •์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.
npm run dev ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
localhost:3000 ์œผ๋กœ ๊ฐ€๋ฉด ํŽ˜์ด์ง€์—์„œ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์—†์ง€๋งŒ, ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ํ™”๋ฉด์€ ๋œจ์ง€ ์•Š์•„์•ผํ•ฉ๋‹ˆ๋‹ค.

Cannot GET /

...์„œ๋ฒ„๋Š” ๊ตฌ๋™๋˜๊ณ  ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.


โ›ณ๏ธ ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ

- static files ๋˜๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด๋‚ด๊ฒŒ๋  ํŒŒ์ผ๋“ค์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
- webpack์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
- JS๋ฅผ ์œ ์ €์—๊ฒŒ ๋ณด๋‚ด๊ณ  ๊ทธ๊ฒƒ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
- src > public > js > app.js๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
- pugํ™”๋ฉด๋‹จ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”ํ•˜๊ธฐ์œ„ํ•ด pug์„ค์ •์„ ํ•ฉ๋‹ˆ๋‹ค.
- Express์˜ ํ• ์ผ์€ views๋ฅผ ์„ค์ •ํ•˜๊ณ  renderํ•ด์ฃผ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
- ๋‚˜๋จธ์ง€๋Š” websocket์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.
mport express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");

app.get("/", (req, res) => res.render("home"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
app.listen(3000, handleListen);

... npm run dev ํ•ด๋ณด๋ฉด home.pug ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

Pug ๐Ÿถ ์„ค์ •

- srcํด๋” ์•ˆ์— viewsํด๋”, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์•ˆ์— Home.pugํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));

app.get("/", (req, res) => res.render("home"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
app.listen(3000, handleListen);

http://localhost:3000/public/js/app.js์œผ๋กœ ๊ฐ€๋ณด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์—†๋Š” ํ™”๋ฉด์ด ๋œน๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, public/js/app.js ์—์„œ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ฉด ๋ฐ˜์˜์ด ๋ฉ๋‹ˆ๋‹ค.

app.js (FE)

- views๋‚˜ ์„œ๋ฒ„๋ฅผ ์ˆ˜์ •ํ• ๋•Œ๋งŒ nodemon์ด ์žฌ์‹œ์ž‘๋˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
- FE ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ˆ˜์ •ํ• ๋•Œ๋Š” nodemon์ด ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
{
    "ignore": [
        "src/public/*"
    ],
    "exec": "npx babel-node src/server.js"
}

์„œ๋ฒ„๋ฅผ ์ข…๋ฃŒ์‹œํ‚ค๊ณ , ๋‹ค์‹œ ์‹คํ–‰์‹œ์ผœ app.js์—์„œ hello๋ฅผ ์ €์žฅํ•ด๋ด…๋‹ˆ๋‹ค.
๐Ÿ‘‰ ๋”์ด์ƒ nodemon์ด ์žฌ์‹คํ–‰๋˜์ง€์•Š์Šต๋‹ˆ๋‹ค.

server.js > ์œ ์ €๊ฐ€ ์–ด๋–ค url๋กœ ์ด๋™ํ•˜๋“ ์ง€, home์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
๋‹ค๋ฅธ url์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , home๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

app.get("/*", (req, res) => res.redirect("/"));

MVP CSS

- ์ถ”๊ฐ€์ ์ธ css์ž‘์„ฑ ์—†์ด ์Šคํƒ€์ผ๋ง์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ์ œ๊ณต๋˜๋Š” cdn์„ header์— ์—ฐ๊ฒฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
profile
๐Ÿ“Œ FE ๊ณต๋ถ€ ์ •๋ฆฌ ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€