Post

๐Ÿฅœ [Node.js] Node.js ๋ฅผ ์‚ฌ์šฉํ•œ Server ๊ตฌํ˜„

Server ๊ตฌํ˜„ ์‹œ์˜ ๊ธฐ๋ณธ ์„ค์ •๊ณผ ์„œ๋ฒ„ ๊ตฌํ˜„๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ํฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

CJS

CJS ๋ž€?

Common JS ์˜ ์•ฝ์ž๋กœ ์ˆœ์ˆ˜ JavaScript ๋งŒ์„ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ๊ตฌํ˜„์„ ๋œปํ•จ

  1. ํŒŒ์ผ ๋‹จ์œ„๋กœ ์บก์Šํ™”
  2. require ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ module(package) ๋ฅผ ๋ถˆ๋Ÿฌ์˜ด
  3. module.exports ๋‚˜ exports ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์˜ ํ•จ์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•จ
1
2
3
4
5
6
7
8
9
10
11
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.write("Hello Node.js! CJS!");
  res.end();
});

server.listen(3000, () => {
  console.log("Server is listening on port 3000 ...");
});

ESM

ECMAScript Module ์˜ ์•ฝ์ž๋กœ JavaScript ์˜ ๊ณต์‹ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ

  1. import ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋Šฅ์„ ๋ถˆ๋Ÿฌ์˜ด
  2. export ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์˜ ํ•จ์ˆ˜, ํด๋ž˜์Šค, ๋ณ€์ˆ˜ ๋“ฑ์„ ์™ธ๋ถ€์— ๊ณต๊ฐœ
  3. ESM ์€ ๋ชจ๋“ˆ ๋กœ๋”ฉ์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ
  4. ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๊ณ , ๋ชจ๋“ˆ ๊ฐ„์˜ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ์šฉ์ด
1
2
3
4
5
6
7
8
9
{
    "name": "my-app",
    "version": "1.0.0",
    "description": "test node.js folder",
    "main": "index.js",
    "type": "module"
    
    // ์ค‘๋žต...
}

์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด type ์„ module ๋กœ ๊ฑธ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createServer } from "http";
// ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค. import ๋ฌธ๊ณผ ๋™์ผ

const server = createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.write("Hello Node.js! ESM!");
  // ํ•ญ์ƒ response ๋ฅผ ์‚ฌ์šฉํ•ด ์‘๋‹ตํ•  ๋•Œ๋Š”
  res.end();
  // ์‘๋‹ต์„ ๋๋‚ด์ฃผ์–ด์•ผ ํ•œ๋‹ค!
});

server.listen(3000, () => {
  console.log("Server is listening port 3000 ...");
});



Nodemon

Node.js ์„œ๋ฒ„๋ฅผ ํ‚ฌ ๋•Œ, ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ์ฆ‰๊ฐ ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”๋‹ค.

์ฆ‰๊ฐ ๋ฐ˜์˜๋˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

1
npm install nodemon -D



Express ๋ž€?

Express๋Š” Node.js์˜ ํ•ต์‹ฌ ๋ชจ๋“ˆ์ธ HTTP๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ๋ผ์šฐํŒ…, ์š”์ฒญ ์ฒ˜๋ฆฌ, ์˜ค๋ฅ˜ ๊ด€๋ฆฌ ๋“ฑ

๊ธฐ๋Šฅ์„ ๊ฐ„๊ฒฐํ•˜๊ณ  ํšจ์œจ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ฆ‰, Express ๋Š” ์—ฌ๋Ÿฌ middleware์˜ ์—ฐ๊ฒฐ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import express from 'express';

const app = express();
const port = 3000;

// ๋ฃจํŠธ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ GET ์š”์ฒญ ์ฒ˜๋ฆฌ
app.get('/', (req, res) => {
  res.send('Hello World!');
});

// ์„œ๋ฒ„ ์‹œ์ž‘
app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});


FS

File System์„ ์˜๋ฏธํ•˜๋ฉฐ, ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•˜์—ฌ

ํŒŒ์ผ์„ ์ƒ์„ฑ, ์ฝ๊ธฐ, ์“ฐ๊ธฐ, ์‚ญ์ œ ๋ฐ ์ˆ˜์ • ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ์ œ๊ณต



Template Engine

ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค Rendering ํ•  html ํŒŒ์ผ์„ ๊ณ„์†ํ•ด์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค.

๋”ฐ๋ผ์„œ Template ํ™” ํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ Code ์žฌ์‚ฌ์šฉ์„ฑ๋„ ๋†’์•„์ง€๋ฉฐ ๊ฐ€๋…์„ฑ๋„ ์ข‹์•„์ง„๋‹ค.

์ด๋Ÿฌํ•œ ๋™์ž‘์„ ๋„์™€์ฃผ๋Š” ๊ฒƒ์ด Template Engine ์ด๋‹ค.

Mustache , Pug , Nunjucks ๊ฐ€ ๋Œ€ํ‘œ์ ์ด๋ฉฐ ์—ฐ์Šต์—์„œ๋Š” Nunjucks ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.



Server ๋™์ž‘ ๊ธฐ์ดˆ ์˜ˆ์‹œ

image-01 (file directory)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import express from "express";
import nunjucks from "nunjucks";
import bodyParser from "body-parser";
import fs from "fs";
import path from "path";

const app = express();
const __dirname = path.resolve();

// file path
// my-app/data/writing.json ์œผ๋กœ ๊ฒฝ๋กœ ์ง€์ •
const filePath = path.join(__dirname, "data", "writing.json");

// body parser set
app.use(bodyParser.urlencoded({ extended: false })); // express ๊ธฐ๋ณธ ๋ชจ๋“ˆ ์‚ฌ์šฉ
app.use(bodyParser.json());

// view engine set
app.set("view engine", "html"); // main.html -> main(.html)

// nunjucks
nunjucks.configure("views", { // views folder ๋‚ด์— ์žˆ๋Š” ๋ณ€๊ฒฝ ๊ฐ’์„ watch
  watch: true, // html ํŒŒ์ผ์ด ์ˆ˜์ •๋  ๊ฒฝ์šฐ, ๋‹ค์‹œ ๋ฐ˜์˜ ํ›„ ๋ Œ๋”๋ง
  express: app,
});

// middleware
// main page GET
app.get("/", (req, res) => {
  const fileData = fs.readFileSync(filePath);
  const writings = JSON.parse(fileData);
  console.log(writings);

  res.render("main", { list: writings });
  // main.html ์˜ list ์— props ์ „๋‹ฌ
  // list ๋Š” ์ด์ œ nunjucks ์— ์˜ํ•ด ๊ฐ’์„ ํ™œ์šฉ ๊ฐ€๋Šฅ
});

app.get("/write", (req, res) => {
  res.render("write");
});

app.post("/write", async (req, res) => {
  const title = req.body.title;
  const contents = req.body.contents;
  const date = req.body.date;

  // data ์ €์žฅ
  // data/wriring.json ์— ๊ฐ’ ์ €์žฅ

  const fileData = fs.readFileSync(filePath);
  console.log(fileData); // ํŒŒ์ผ ์ฝ๊ธฐ

  const writings = JSON.parse(fileData);
  console.log(writings); // ํŒŒ์ผ ๋ณ€ํ™˜

  // request ๋ฐ์ดํ„ฐ ์ €์žฅ
  writings.push({
    title: title,
    contents: contents,
    date: date,
  });

  // data/writing.json ์— ์ €์žฅํ•˜๊ธฐ
  fs.writeFileSync(filePath, JSON.stringify(writings));

  res.render("detail", {
    detail: { title: title, contents: contents, date: date },
  });
});

app.get("/detail", async (req, res) => {
  res.render("detail");
});
app.listen(3000, () => {
  console.log(`
  โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—        โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
  โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•        โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•
  โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—          โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•     โ–ˆโ–ˆ   โ–ˆโ–ˆโ•‘โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘
  โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘
  โ•šโ•โ•  โ•šโ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ• โ•šโ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•
                                                        
  `);
});

image-02 image-03 image-04

1
2
3
4
[
  { "title": "HELLO", "contents": "123", "date": "" },
  { "title": "๊ธ€ ์ž‘์„ฑ", "contents": "์ž‘์„ฑ์ค‘...", "date": "2024-02-28" }
]

(์ •์ƒ์ ์œผ๋กœ json ์— data ๊ฐ€ ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ)

This post is licensed under CC BY 4.0 by the author.