Javascript/Node.js

[ Node.js ] - node.js๋ž€? ( + ๊ธฐ๋ณธ ์ฝ”๋“œ )

algml0703 2022. 6. 10. 18:08
๋ฐ˜์‘ํ˜•

Node.js

๐Ÿ‘‰ Chrome V8 Javascript ์—”์ง„์œผ๋กœ ๋นŒ๋“œ๋œ Javascript ๋Ÿฐํƒ€์ž„์ด๋‹ค.

node.js๋Š” ์„œ๋ฒ„ ์‹คํ–‰์šฉ์œผ๋กœ ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

  • ๋Ÿฐํƒ€์ž„ : ํŠน์ • ์–ธ์–ด๋กœ ๋งŒ๋“  ํ”„๋กœ๊ทธ๋žจ๋“ค์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ
  • ์„œ๋ฒ„ : ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ ์ •๋ณด๋‚˜ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ปดํ“จํ„ฐ ๋˜๋Š” ํ”„๋กœ๊ทธ๋žจ
  • ํด๋ผ์ด์–ธํŠธ : ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ฃผ์ฒด๋กœ, ์ฃผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์˜๋ฏธํ•œ๋‹ค.( ๋ชจ๋ฐ”์ผ ์•ฑ์ด๋‚˜, ๋‹ค๋ฅธ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ดฌ๋Š” ์„œ๋ฒ„๋„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. )

ํŠน์„ฑ

โœ” ์ด๋ฒคํŠธ๊ธฐ๋ฐ˜

์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์‚ฌ์ „์— ์งœ์—ฌ์ง„ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฆ‰ ํŠน์ • ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ํ•ด๋‹น ์ด๋ฒคํŠธ์— ์„ค์ •ํ•ด๋‘” ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜๋“ค์€ ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœ ์Šคํƒ์— ๋“ค์–ด๊ฐ€๊ณ  ํ•จ์ˆ˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๋ฉด ํ˜ธ์ถœ ์Šคํƒ์—์„œ ๋งˆ์ง€๋ง‰์— ๋“ค์–ด๊ฐ„ ํ˜ธ์ถœ๋ถ€ํ„ฐ ์ง€์›Œ์ง€๊ฒŒ ๋œ๋‹ค. ์ฆ‰ ํ›„์ž…์„ ์ถœ(LIFO: Last In First Out)์ด๋‹ค.

โœ” ๋…ผ๋ธ”๋กœํ‚น I/O

์ด์ „ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (๋ธ”๋กœํ‚น์€ ์ด์ „ ์ž‘์—…์ด ๋ชจ๋‘ ์™„๋ฃŒ๋œ ํ›„์— ๋‹ค๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.) ๋…ธ๋“œ๋Š” I/O์ž‘์—…์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ๋„˜๊ฒจ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•œ๋‹ค.

* I/O๋ž€?
์ฃผ๋กœ libuv๊ฐ€ ์ง€์›ํ•˜๋Š” ์‹œ์Šคํ…œ ๋””์Šคํฌ๋‚˜ ๋„คํŠธ์›Œํฌ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
์ฆ‰ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ํŒŒ์ผ์“ฐ๊ธฐ, ํด๋” ๋งŒ๋“ค๊ธฐ ๋“ฑ ํŒŒ์ผ์‹œ์Šคํ…œ ์ ‘๊ทผ์ด๋‚˜ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•œ ์š”์ฒญ ๋“ฑ์ด ์ด์— ํ•ด๋‹น๋œ๋‹ค.
* libuv : ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋น„๋™๊ธฐ I/O๋ฅผ ์ง€์›ํ•˜๋Š” ๋‹ค์ค‘ ํ”Œ๋žซํผ C ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ฒƒ์€ ์ž‘์—… ์‹คํ–‰์˜ ์„ฑ๋Šฅ์„ ๋†’์—ฌ์ค€๋‹ค.

ex) ๋…ผ๋ธ”๋กœํ‚น ์˜ˆ์‹œ

node.js์˜ ๊ฒฝ์šฐ '์‹œ์ž‘'์„ ์ถœ๋ ฅํ•œ ์ดํ›„์— '์ž‘์—… ์™„๋ฃŒ' ๊ฐ€ ์ถœ๋ ฅํ•˜๋Š” ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋”๋ผ๋„ ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•œ๋‹ค.

function longRunningTask() {
	// ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…
	console.log('์ž‘์—… ์™„๋ฃŒ');
};

console.log('์‹œ์ž‘');

setTimeout(longRunningTask,1);

console.log('๋‹ค์Œ์ž‘์—…');
// ์œ„์˜ ์ฝ”๋“œ ์‹คํ–‰์‹œ
// ์‹œ์ž‘ -> ๋‹ค์Œ์ž‘์—… -> ์ž‘์—…์™„๋ฃŒ

node.js ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ชจ๋“  I/O ๋ฉ”์„œ๋“œ๋Š” ๋…ผ๋ธ”๋กœํ‚น์ธ ๋น„๋™๊ธฐ ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜๊ณ  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค.

ํ•˜์ง€๋งŒ ์ž‘์—…์„ ํ•˜๋‹ค๋ณด๋ฉด ์ด์ „์˜ ์ž‘์—…์ด ๋ชจ๋‘ ์™„๋ฃŒ๋œ ํ›„์— ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๊ฐ€ ๊ทธ ์˜ˆ์‹œ์ด๋‹ค.

const fs = requir('fs');
fs.readFile('/file.md',(err,data) => {
    if(err) throw err;
    console.log(data);I/O
});
fs.unlinkSync('/file.md');
// ์œ„ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์€ I/O๊ฐ€ ๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์•ž์—์„œ fs ํŒŒ์ผ์ด
// ๋‹ค ์ฝํ˜€์ง€๊ธฐ๋„ ์ „์— unlinkSync()๊ฐ€ ์‹คํ–‰๋˜์–ด ํŒŒ์ผ์ด ์ œ๊ฑฐ๋  ์œ„ํ—˜์ด ์žˆ๋‹ค.
// ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •๋˜์–ด์•ผ ํ•จ.

const fs = require('fs');
fs.readFile('/file.md',(readFileErr,data) => {
    if(readFileErr) throw readFileErr;
    console.log(data);
    fs.unlink('/file.md',(funlinkErr) => {
    	if(unlinkErr) throw unlinkErr;
    })
})

๋˜๋Š” promise๋‚˜ async await ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋„๋ก ๋™๊ธฐ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ” ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ

node.js๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ด๋‹ค.

๐ŸŒž ์ดํ•ด๋ฅผ ๋•๋Š” ์•„์ฃผ ์ข‹์€ ์˜ˆ์‹œ
์ ์›์ด ํ•œ ์†๋‹˜์˜ ์ฃผ๋ฌธ์„ ๋ฐ›๊ณ  ์ฃผ๋ฐฉ์— ์ฃผ๋ฌธ๋‚ด์—ญ์„ ๋„˜๊ธด ๋’ค ๋‹ค์Œ ์†๋‹˜์˜ ์ฃผ๋ฌธ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ ์›์€ ์š”๋ฆฌ๊ฐ€ ๋๋‚˜๊ธฐ ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ์ฃผ๋ฌธ๋‚ด์—ญ๋งŒ ์ฃผ๋ฐฉ์— ๊ณ„์† ์ „๋‹ฌํ•˜๊ณ , ์ฃผ๋ฐฉ์—์„œ ์š”๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์™„๋ฃŒ๋œ ์ˆœ์„œ๋Œ€๋กœ ์†๋‹˜์—๊ฒŒ ์„œ๋น™ํ•ฉ๋‹ˆ๋‹ค. ์š”๋ฆฌ์˜ ํŠน์„ฑ(๋ธ”๋กœํ‚น์ธ์ง€ ๋…ผ๋ธ”๋กœํ‚น์ธ์ง€)์— ๋”ฐ๋ผ ์™„๋ฃŒ๋˜๋Š” ์ˆœ์„œ๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์–ด, ์ฃผ๋ฌธ์˜ ๋“ค์–ด์˜จ ์ˆœ์„œ์™€ ์„œ๋น™ํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์š”๋ฆฌ๋ฅผ ํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค๋ฉด( CPU๊ฐ€ ๋งŽ์ด ์†Œ๋ชจ๋˜๋Š” ์ž‘์—… ) ์ฃผ๋ฌธ์ด ๋งŽ์ด ๋“ค์–ด์˜ค๋ฉด  ๋ฒ„๊ฑฐ์šธ ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰ ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ == ์ ์› ํ•œ ๋ช…

โœ… NPM (=Node Package Manager)

โœ” Package.json

์„ค์น˜๋œ ํŒจํ‚ค์ง€์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ํŒŒ์ผ์ด๋‹ค.

> npm init
> npm install [ ํŒจํ‚ค์ง€๋ช… ]
> npm uninstall [ ํŒจํ‚ค์ง€๋ช… ]

โœ” express

javascript๋กœ ์ž‘์„ฑ๋˜๊ณ  Node.js ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์—์„œ ๊ตฌ๋™๋˜๋Š” ์›น ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

- app.all( [ ๊ฒฝ๋กœ ] , [ ์ฝœ๋ฐฑํ•จ์ˆ˜ ] )
// ๋ชจ๋“  ์š”์ฒญ ๋ฉ”์„œ๋“œ ( get, post, delete, put ...)์— ๋Œ€ํ•˜์—ฌ ํ•ด๋‹น ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ฌ ๋•Œ ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์ค€ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
app.all('/user', ()=>{console.log( '๋กœ๊ทธ์ธ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.' )});
// ์–ด๋–ค ๋ฉ”์„œ๋“œ๋กœ ์š”์ฒญํ•˜๋ƒ์— ์ƒ๊ด€์—†์ด /user๋กœ ์š”์ฒญํ•œ ๊ฒฝ์šฐ '๋กœ๊ทธ์ธ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.'๋ฅผ ์ถœ๋ ฅํ•ด์ค€๋‹ค.

- app.use( [๋ฏธ๋“ค์›จ์–ด] ) or - app.use([๊ฒฝ๋กœ], [๋ผ์šฐํŠธ])
app.use(cookieParser()) 
// ํ•ด๋‹น ์„œ๋ฒ„์—์„œ cookieParser๋ฅผ ์‚ฌ์šฉ.
const api = require('./api'); // api๋Š” ๋ผ์šฐํŠธ ํŒŒ์ผ
app.use('/api', api);
// '/api' ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด api ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์š”์ฒญ๋ฉ”์„œ๋“œ

  • get
  • post
  • put
  • delete
  • ...

์‘๋‹ต๋ฉ”์„œ๋“œ

  • res.json().    // ์‘๋‹ต์„ json ํ˜•์‹์œผ๋กœ ๋ฐ˜ํ™˜
  • res.download()  // ํŒŒ์ผ์ด ๋‹ค์šด๋กœ๋“œ๋˜๋„๋ก ํ”„๋กฌํ”„ํŠธ
  • res.end() // ์‘๋‹ต ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ
  • res.redirect() // ๊ฒฝ๋กœ ์žฌ์ง€์ •
  • res.render() // ์ธ์ž๊ฐ’์œผ๋กœ ์ค€ ํ…œํ”Œ๋ฆฟ์„ ๋ณด์—ฌ์ค€๋‹ค.
  • res.send()  // ์ธ์ž๊ฐ’ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ
  • res.sendFile()  // ์ธ์ž๊ฐ’์œผ๋กœ ์ค€ ํŒŒ์ผ์„ ํ™”๋ฉด์— ์ถœ๋ ฅ
  • res.sendStatus()  // ํ•ด๋‹น ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ด”ํ™˜
app.use( [๋ฏธ๋“ค์›จ์–ด] ) or app.use([๊ฒฝ๋กœ], [๋ผ์šฐํŠธ])
app.use(cookieParser()) 
// ํ•ด๋‹น ์„œ๋ฒ„์—์„œ cookieParser๋ฅผ ์‚ฌ์šฉ.
const api = require('./api'); // api๋Š” ๋ผ์šฐํŠธ ํŒŒ์ผ
app.use('/api', api);
// '/api' ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด api ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


๊ธฐ๋ณธ ์ฝ”๋“œ

const express = require('express')
const app = express()
require('dotenv').config('env')
// dotenv์‚ฌ์šฉ์„ ์œ„ํ•œ ์„ธํŒ…
// env ํŒŒ์ผ ์•ˆ์— PORT=3010 ์ด์™€ ๊ฐ™์ด ํ‚ค=๊ฐ’ ํ˜•์‹์œผ๋กœ ์ €์žฅํ›„
// ์‹ค์ œ ์‚ฌ์šฉ์‹œ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด process.env.PORT ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ 
// ||๋Š” ๋งŒ์•ฝ์— ํ•ด๋‹น ํ‚ค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 3010์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.
const port = process.env.PORT||3010
const morgan = require('morgan')
// morgan ๋ฏธ๋“ค์›จ์–ด๋Š” logging ์ฆ‰ ์ƒํƒœ์— ๋Œ€ํ•œ ๊ธฐ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฏธ๋“ค์›จ์–ด
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser')
// ์ฟ ํ‚ค ํŒŒ์‹ฑ์„ ๋•๋Š” ๋ฏธ๋“ค์›จ์–ด

app.use(express.urlencoded({extended:false}))

app.use(morgan(':method:url'))
// method์™€ url์— ๋Œ€ํ•œ ์ •๋ณด๋งŒ ๋ณด์—ฌ์คŒ
//app.use(morgan('tiny'));
// morgan()์˜ ์•ˆ์— ์˜ค๋Š” ์ธ์ž์— ๋”ฐ๋ผ ๋ณด์—ฌ์ฃผ๋Š” ๋‚ด์šฉ์ด ๋‹ค๋ฅด๋‹ค.
// http://expressjs.com/en/resources/middleware/morgan.html ๊ด€๋ จ 
app.use(cookieParser())
// cookie-parser์‚ฌ์šฉ
// req๋ฅผ ํ†ตํ•ด cookies ๊ฐ์ฒด์— ์ ‘๊ทผ ๊ฐ€๋Šฅ

app.get('/',(req,res)=>{    
    if(req.cookies.remember){ 
        // cookie-parser๋ฅผ ํ†ตํ•ด request๊ฐ์ฒด์˜ ์ฟ ํ‚ค์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
        // ์ฆ‰ ํ•ด๋‹น /์— ๋“ค์–ด์™”์„ ๋•Œ ์ฟ ํ‚ค์— remember์ด ์žˆ๋‹ค๋ฉด ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ์‹คํ–‰
        //console.log('if')
        res.send('Remembered :).Click to <a href="/forget">forget</a>')        
    }else{
        // remember์ด ์—†๋‹ค๋ฉด
        // ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ์‹คํ–‰
        //console.log('else')
        res.send('<form method="post"><p>check to<label>'
        +'<input type="checkbox" name="remember"/> remberer me</label>'
        +'<input type="submit" value="์ œ์ถœ"/>0</p></form>')
    }    
})

app.get('./forget',function(req,res){
    res.clearCookie('remberer');
    res.redirect('back');
})

app.post('/',(req,res)=>{
    let min = 60000
    if(req.body.remember) res.cookie('remember',1,{maxAge:min})
    res.redirect('back')
})

app.listen(port,()=>{
    console.log(`server start port${port}`)
    
})

์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์—ฐ๊ฒฐํ•˜๊ธฐ

> npm install mysql
// mysql๋กœ ์—ฐ๊ฒฐ์‹œ ์—๋Ÿฌ๋‚˜๋Š” ๊ฒฝ์šฐ mysql2๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
const mysql = require('mysql');
const connection = mysql.createConnection({
	host: 'localhost',
    user: 'root',
    password: 'root'
});
// ์œ„์˜ ์„ค์ •์€ ์‹ค์ œ ์‚ฌ์šฉ์ž์˜ ์ปดํ“จํ„ฐ์— ์„ค์ •๋œ ๊ฒƒ์„ ์‚ฌ์šฉํ•œ๋‹ค.

connection.connect();

// ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค.
// board ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •
connection.query(`SELECT * FROM board`, (err, rows, fields) => {
	if(err) throw err;
    console.log(rows);
});

connection.end();
๋ฐ˜์‘ํ˜•