๐Ÿ” Archive/Node.js

Node.js ์‹œ์ž‘ํ•˜๊ธฐ! [์œ ํŠœ๋ธŒ Node.js beginner ํŠœํ† ๋ฆฌ์–ผ ์ •๋ฆฌ]

YoungRock 2020. 3. 3. 03:30

Node.js๋ž€?

: A runtime environment for executing Javascript(js) code

- ์ฃผ๋กœ ๋ฐฑ์•ค๋“œ ์„œ๋น„์Šค ๊ตฌ์ถ•์— ์‚ฌ์šฉ๋จ ex) API(Application Programming Interface)

- ์›น์•ฑ, ๋ชจ๋ฐ”์ผ ์•ฑ์ด ๋ฐฑ์•ค๋“œ ์„œ๋น„์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜, ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, ํ‘ธ์‰ฌ ์•Œ๋žŒ์„ ๋ณด๋‚ผ๋•Œ ๋“ฑ

- Non-blocking(๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ๊ธฐ๋‹ค๋ฆฌ๊ธฐ), Asynchronous(๋น„๋™๊ธฐ) ์ด๋ฏ€๋กœ  ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ , ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ, ์‹ค์‹œ๊ฐ„ ์•ฑ์„ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค.


Node๋งŒ์˜ ์žฅ์ ?

- ํ”„๋กœํ† ํƒ€์ดํ•‘๊ณผ ๋น ๋ฅธ ๊ฐœ๋ฐœ์— ์œ ์šฉ

- ๋งค์šฐ ๋น ๋ฅด๊ณ  ํ™•์žฅ๊ฐ€๋Šฅํ•จ, ์ฆ‰, ๋” ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ, ํŒŒ์ผ๋กœ ๋” ๋น ๋ฅธ ์„œ๋น„์Šค ๊ตฌ์ถ• ๊ฐ€๋Šฅ

- ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ๋Š” ์–ด๋””๋“ ์ง€ ์žˆ์Œ (node.js๋Š” javascript ๊ธฐ๋ฐ˜)

- ๊น”๋”ํ•˜๊ณ  ์ผ๊ด€์„ฑ ์žˆ๋Š” ์ฝ”๋“œ ๊ธฐ๋ฐ˜

- ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํฌ๊ฒŒ ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ์Œ


Node ๊ตฌ์กฐ

- ๊ธฐ์กด์—๋Š” JS code๋ฅผ->JS Engine์—์„œ->Machine code ๋กœ ๋ณ€ํ™˜,
js code๋ฅผ ๋ธŒ๋ผ์šฐ์ €(ex) chrome) ์•ˆ์—์„œ ๋ฐ–์— ์‹คํ–‰์„ ๋ชปํ–ˆ์Œ

- 2009, Byan Dahl - Js code๋ฅผ ๋ธŒ๋ผ์šฐ์ € ๋ฐ–์—์„œ ์‹คํ–‰ํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด

[Google v8 engine (faster js engine)] + [embedded c++ program(some additional module)]
=> Node.exe

- Javascript code์˜ runtime environment -> ๊ทธ๋Ÿฌ๋‚˜  ๋ธŒ๋ผ์šฐ์ €์— ์žˆ๋Š” environment์˜ object์™€๋Š” ๋‹ค๋ฅธ object(๊ฐ์ฒด)๋ฅผ ๊ฐ–๊ณ  ์žˆ์Œ

์˜ˆ๋ฅผ๋“ค์–ด,

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ document.getElementById(‘’); -> document object๊ฐ€ ์•„๋‹Œ

๋…ธ๋“œ๋Š” fs.readFilew(), http.createServer()
-> fs (
ํŒŒ์ผ ์‹œ์Šคํ…œ), http (listen for request (๋„คํŠธ์›Œํฌ์—์„œ)) ๋“ฑ๊ณผ ๊ฐ™์€ object๋ฅผ ๊ฐ–๊ณ  ์žˆ์Œ

=> ํฌ๋กฌ, ๋…ธ๋“œ ๋ชจ๋‘ ๊ฐ™์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์„ ๊ณต์œ ํ•˜๋Š”๋ฐ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•œ๋‹ค.


Node is NOT a programming language!
Node is NOT  a framework!
It’s a runtime environment for executing JavaScript code

How Node Works?

<Non-bloking Asynchronous>

์Œ์‹์ ์— ๊ฐ€๋ฉด ์ ์›์ด ํ…Œ์ด๋ธ”1์„ ์ฃผ๋ฌธ๋ฐ›๊ณ  ํ…Œ์ด๋ธ”2๋ฅผ ์ฃผ๋ฌธ๋ฐ›๋Š” ๋™์•ˆ ์š”๋ฆฌ์‚ฌ๊ฐ€ ์š”๋ฆฌ๋ฅผ ํ•œ๋‹ค -> ํ…Œ์ด๋ธ”1 ์ฃผ๋ฌธ๋ฐ›๊ณ  ๊ทธ ์š”๋ฆฌ๊ฐ€ ๋‚˜์˜ฌ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†์Œ

์ ์›-> Sigle Thread ํ…Œ์ด๋ธ” -> Request ๋ผ๊ณ  ์ƒ๊ฐ

<Blocking Synchronous์˜ ๋ฌธ์ œ์ >

Thread๋Š” ํ•œ์ •๋œ ์ž์›(2๊ฐœ ์žˆ๋‹ค ์น˜์ž) ->  request 1๊ฐ€ ๋“ค์–ด์˜ด -> thread 1์ด request 1(client)์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ -> request 2๊ฐ€ ๋“ค์–ด์˜ด -> thread 2๊ฐ€ request 2๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ -> thread 3๊ฐ€ ์˜ค๋ฉด thread1, 2๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผํ•จ

=> ์—„์ฒญ ๋งŽ์€ client๋ผ๋ฉด? Thread ๋ถ€์กฑ -> ๊ธฐ๋‹ค๋ ค์•ผํ•จ or ํ•˜๋“œ์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•จ

 

๋…ธ๋“œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋””ํดํŠธ๋กœ asynchronous(๋น„๋™๊ธฐ)์ด๊ธฐ ๋•Œ๋ฌธ์—,

single thread๊ฐ€ ๋™์‹œ์— request๋ฅผ handle ๊ฐ€๋Šฅ

- request 1์ด database๋ฅผ ์š”์ฒญํ•œ๋‹ค๋ฉด database๊ฐ€ data๋ฅผ return ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š”x
- database ๊ฐ€ query๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ ๋™์•ˆ request 2๋ฅผ handle
database ๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ์ค€๋น„ํ•˜๋ฉด -> event queue  ๋ฉ”์„ธ์ง€ ๋ฐœ์ƒ
(signle thread ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ด๋ฅผ ๋ณด๊ณ ์žˆ๋‹ค๊ฐ€ -> ๊ฒฐ๊ณผ๋ฅผ request 1์—๊ฒŒ ์คŒ
  • Node is ideal for I/O-intensive app
  • ํ•˜๋“œ์›จ์–ด ์ถ”๊ฐ€ ์—†์ด ๋” ๋งŽ์€ client ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • Do not use Node for CPU-intensive apps (ex) video encoding, image manipulation service) -> ์™œ๋ƒํ•˜๋ฉด GPU๊ฐ€ ํ•˜๋Š” ๊ณ„์‚ฐ ๋งŽ๊ณ  ํŒŒ์ผ ์‹œ์Šคํ…œ์ด๋‚˜ ๋„คํŠธ์›Œํฌ๋Š” ๋ณ„๋กœ ์•ˆ๊ฑด๋“ค์ž„.
  • Only use in data-intensive and real-time apps

Node.js ์„ค์น˜

cmd ์ฐฝ์—์„œ ์„ค์น˜ ํ™•์ธ : node --version

node.js ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋œ pc 

์—†์œผ๋ฉด ์„ค์น˜ -> https://nodejs.org/en/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org


Build our first application

1) console (cmd)

> mkdir first-app ----> 'first-app'ํด๋” ์ƒ์„ฑ

> cd first-app/

> code . ----> visual studio code๋กœ ๊ฐ

2) (visual studio code์—์„œ) ์ƒˆ ํŒŒ์ผ app.js ๋งŒ๋“ฆ

function sayHello(name){
	console.log(‘Hello ’+name);
}
sayHello(‘Mosh’);

 

3) ํ„ฐ๋ฏธ๋„(cmd)์—์„œ ์‹คํ–‰

> node app.js

app.jsํŒŒ์ผ ์‹คํ–‰ -> ๊ฒฐ๊ณผ: Hello Mosh

  • Console.log(window) ์‹คํ–‰
  • ๊ฒฐ๊ณผ: window is not defined -> window๋‚˜ document object๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š์Œ

Node core


Node Module System

  • ๋…ธ๋“œ ์ฝ”์–ด์— ๊ตฌ์ถ•๋˜์–ด ์žˆ๋Š” ๋ชจ๋“ˆ : os, fs, events, http
  • ๋‚˜๋งŒ์˜ ๋ชจ๋“ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๋„ ๋ฐฐ์šธ ๊ฒƒ์ด๋‹ค.

Global Object (์ „์—ญ ๊ฐ์ฒด)

Console.log(); // console object๋Š” ์–ด๋–ค ํŒŒ์ผ์—์„œ๋“  ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ „์—ญ๋ณ€์ˆ˜

ex) setTimeout(), clearTimeout(), setInterval(), clearInterval() ๋“ฑ
-> Window object์— ์†ํ•ด ์žˆ์Œ

๋…ธ๋“œ -> global์ด๋ผํ•˜๋Š” ๊ฐ์ฒด์— ์†ํ•ด ์žˆ์Œ

  • Var message = ''; ----> ์ „์—ญ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ํ•ด๋‹นํŒŒ์ผ ๋ฐ–์—์„œ๋Š” ์ ‘๊ทผ ๋ชปํ•จ.

Modules

  • ์•ˆ์ •์ ์ด๊ณ  ์‹ ๋ขฐ๊ฐ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋ ค๋ฉด ์ „์—ญ๋ณ€์ˆ˜๋‚˜ ์ „์—ญํ•จ์ˆ˜์˜ ์ง€์ •์„ ํ”ผํ•ด์•ผ ํ•œ๋‹ค.
  • ๋Œ€์‹  Module ์‚ฌ์šฉ

Creating a Module

// logger.js

var url = 'http://mylogger.io/log'; // imagine send a html request to this url(end point)

function log(message) {
    // Send an HTTP request
    console.log(message);
}

module.exports.log = log;   //global ๋ณ€์ˆ˜๋กœ ์ง€์ •ํ•˜๊ณ  ์‹ถ์–ด์„œ

 

  • main module(app.js)์—์„œ logger.js์˜ ํ•จ์ˆ˜ log๋ฅผ ์ ‘๊ทผํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?
  • module.exports.log = log; ๋กœ log๋ฅผ global ๋ณ€์ˆ˜ log๋กœ ์ง€์ •

Loading a Module

  • require(): (๋ธŒ๋ผ์šฐ์ €์—๋Š” ์—†๋Š” ํ•จ์ˆ˜) loadํ•˜๊ณ  ์‹ถ์€ ๋ชจ๋“ˆ์„ ์ธ์ž๋กœ ๋„˜๊ธด๋‹ค.
  • app.js
// app.js
var logger = require('./logger');
console.log(logger); 

์‹คํ–‰๊ฒฐ๊ณผ


๋ชจ๋“ˆ์ด ๋™์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

[์ฝ”๋“œ]

  • app.js
// app.js
const logger = require('./logger');
logger.log('message');

logger์€ ์žฌ์ •์˜๋ฅผ ๋ง‰๊ธฐ์œ„ํ•ด ์ƒ์ˆ˜๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค.

  • logger.js
// logger.js

var url = 'http://mylogger.io/log';

function log(message) {
    // Send an HTTP request
    console.log(message);
}

module.exports.log = log;

 

[์‹คํ–‰๊ฒฐ๊ณผ] app.js์—์„œ logger.js์˜ logํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ


Module Wrapper Function

  • Node๋Š” ์ฝ”๋“œ๋ฅผ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.
(function(exports, require, module, __filename, __dirname){
    // code…
})

 ์ด๋Ÿฐ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐ์‹ผ ํ›„ ์‹คํ–‰

// Logger.js์— ์ถ”๊ฐ€
console.log(__filename);
console.log(__dirname);

์œผ๋กœ ํ™•์ธ


<ํฌ๊ฒŒ ์•Œ์•„์•ผ ํ•  module>

File System, HTTP(์›น์„œ๋ฒ„), OS, Path(์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ธฐ๋Šฅ), Process, Query Strings, Stream ๋“ฑ

(์ฐธ๊ณ : https://nodejs.org/dist/latest-v12.x/docs/api/)

Path module

  • path ๋ชจ๋“ˆ
const path = require('path');

var pathObj = path.parse(__filename);

console.log(pathObj);

์‹คํ–‰๊ฒฐ๊ณผ


OS module

const os = require('os');

var totalMemory = os.totalmem();
var freeMemory = os.freemem();

console.log(`Total Memory: ${totalMemory}`);
console.log(`Free Memory: ${freeMemory}`); 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์•Œ์ˆ˜ ์—†๋Š” ์ •๋ณด๋“ค์„ ์•Œ ์ˆ˜ ์žˆ์Œ

์‹คํ–‰๊ฒฐ๊ณผ


File System module

const fs = require('fs');

 

1) synchronous์ธ readdirSync() ํ•จ์ˆ˜

const files = fs.readdirSync('./');
console.log(files);

์‹คํ–‰๊ฒฐ๊ณผ

ํ•˜์ง€๋งŒ, ๋…ธ๋“œ์—์„œ๋Š” "asynchronous ํ•จ์ˆ˜ ์‚ฌ์šฉ"์„ ์ ๊ทน ๊ถŒ์žฅํ•œ๋‹ค!

2) asynchronous์ธ readdir() ํ•จ์ˆ˜

// asynchronous function
const files = fs.readdir('./', function(err, files){
    if(err) console.log('Error', err);
    else console.log('Result', files);
});

- ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” call back ํ•จ์ˆ˜ 
- node๋Š” asynchronous operation์ด ๋๋‚˜๋ฉด ๋‘๋ฒˆ์งธ ์ธ์ž์˜ ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฅธ๋‹ค.

๊ฒฐ๊ณผ


Events module

  • Event: A signal that something has happened
const EventEmitter = require('events');
// class์ž„
const emitter = new EventEmitter();

// Register a listener
emitter.on('messageLogged', function(){
    console.log('Listener called');
})

// Raise an event
emitter.emit('messageLogged', { id: 1, url: 'http://'});
// emit: Making a noise, produce - signalling
  • emit์ด ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ sychoronously ํ•˜๊ฒŒ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์— emit์ด ์—†์œผ๋ฉด ์ถœ๋ ฅ ์•ˆ๋จ

์‹คํ–‰๊ฒฐ๊ณผ

  • ์ด ๊ธฐ์ˆ ๋กœ ๋ฐฉ๊ธˆ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ์ฝœ๋ฐฑ์„ ์“ฐ๊ธฐ๋„ ํ•จ (์ด๊ฑธ ์„ ํ˜ธ)
// Register a listener
emitter.on('messageLogged', (arg) => {  // e, eventArg์ด๋ผํ•ด๋„๋จ
    console.log('Listener called', arg);
})

Extending EventEmitter

  • ์„œ๋กœ ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ emitter์“ฐ๋ ค๊ณ  ๊ฐ ํŒŒ์ผ๋งˆ๋‹ค
  • const emitter = new EventEmitter();
  • ์„ ์„ ์–ธํ•˜๋ฉด ์ด๋ฆ„์€ ๊ฐ™์ง€๋งŒ ์„œ๋กœ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋œ๋‹ค.

=> ๋Œ€์‹  class๋ฅผ ๋งŒ๋“ ๋‹ค

[app.js]

// app.js
const EventEmitter = require('events');

const Logger = require('./logger');
const logger = new Logger();

// Register a listener
logger.on('messageLogged', (arg) => {
    console.log('Listener called', arg);
})

logger.log('message');

 

[logger.js]

// logger.js
const EventEmitter = require('events');

var url = 'http://mylogger.io/log';

class Logger extends EventEmitter{
    //base class
    log(message) {
        // Send an HTTP request
        console.log(message);

        // Raise an event
        this.emit('messageLogged', { id: 1, url: 'http://'});
    }
}

module.exports = Logger; // export Logger class

 

EventEmitter๋ฅผ ํ™•์žฅํ•˜์—ฌ EventEmitter๊ฐ€ Loggerํด๋ž˜์Šค์˜ ์ผ๋ถ€๊ฐ€ ๋จ
-> this๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ EventEmitter์˜ method ์‚ฌ์šฉ๊ฐ€๋Šฅ


HTTP module

: ์•ฑ์—์„œ ๋„คํŠธ์›Œํฌ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“ˆ

// app.js
const http = require('http');

const server = http.createServer(); //create web server

// this server is event emitter
/* http.Serverํด๋ž˜์Šค๋Š” net.Server๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค์ธ๋ฐ
net.Server ๊ฐ€ event emitter์ด๋‹ค  (๊ณต์‹๋ฌธ์„œ์—์„œ ํ™•์ธ)
*/
server.on('connection', (socket) => {
    console.log('New connection...');
})

server.listen(3000);

console.log('Listening on port 3000...');

์‹คํ–‰๊ฒฐ๊ณผ
๋ธŒ๋ผ์šฐ์ €(ํฌ๋กฌ)์—์„œ localhost:3000์„ ์‹คํ–‰ํ–ˆ์„ ๋•Œ


  • ์ฝ”๋“œ

[app.js]

const http = require('http');

const server = http.createServer(function(req, res){
    if(req.url === '/'){
        res.write('Hello World');
        res.end();
    }
    
    if(req.url === '/api/courses'){
        res.write(JSON.stringify([1,2,3]));  // convert this array->JSON syntex
        res.end();
    }

    // ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ผ์šฐํ„ฐ๋ฅผ ๊ฐ€์ง„ ๊ฒƒ์€ ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ฆ
    // express ์‚ฌ์šฉ -> clean structure
    
}); //create web server

server.listen(3000);

console.log('Listening on port 3000...');

 

  • ์‹คํ–‰๊ฒฐ๊ณผ


[์ •๋ฆฌ from]

Node.js Tutorial for Beginners (์ฑ„๋„: Programming with Mosh)

https://youtu.be/TlB_eWDSMt4

'๐Ÿ” Archive > Node.js' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Express.js ํŠœํ† ๋ฆฌ์–ผ (GET, POST, PUT, DELETE)  (0) 2020.03.04