본문 바로가기
JavaScript│Node js

node js 기초 이론 정리

by 자유코딩 2018. 10. 5.


package.json


package.json에 대한 설명

package.json 은 npm을 위한 정보들을 저장 해 놓은 파일.


npm은 node packaged manager의 약자이다.

즉 , npm은 node.js package(module)을 관리하는 툴이다.


package.json은 이렇게 생겼다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "name""myapp",
  "version""0.0.0",
  "private"true,
  "scripts": {
    "start""node ./bin/www"
  },
  "dependencies": {
    "body-parser""^1.18.3",
    "cookie-parser""~1.4.3",
    "debug""~2.6.9",
    "express""^4.16.3",
    "http-errors""~1.6.2",
    "morgan""~1.9.0",
    "pug""2.0.0-beta11"
  }
}
cs


package.json 에서 가장 중요한 항목은 name 과 version 이다.

name 과 version이 누락되면 패키지는 설치 할 수 없다.

name 과 version을 통해서 각 패키지의 고유성을 판별한다.

즉, 패키지의 내용을 변경하려면 version 을 변경해야한다.


script : start - 시작

dependencies 는 스프링에 있는 dependencies 와 같다.

추가한 모듈의 버전을 의미한다.


exports 와 module.exports 의 차이


우선 exports 라는 단어는 import 와 반대된다.

뭔가를 내보낸다는 의미이다. node js에서의 exports는 주로 모듈을 내보낸다.


간략히 비유해서 설명하면. C언어의 사용자 정의 헤더파일 , 자바의 라이브러리(jar) 비슷한 형태라고 할 수 있다.


아래와 같이 두개의 javascript 파일이 있다고 해보자.


1. app.js


1
2
exports.test = function(a,b){return a+b};
exports.test2 = function(c,d){return c-d};
cs


2. moduleTest.js


1
2
3
4
5
const ddd = require('./app.js');
let plus = ddd.test(2,3);
let minus = ddd.test2(6,3);
console.log(plus);
console.log(minus);
cs

 

이렇게 코드를 작성하고 moduleTest.js 를 실행해보겠다.



app.js 에 있는 test와 test2를 사용한 결과가 출력된다.

 

이렇게 exports를 사용하면 다른 js 파일에 있는 함수들을 사용할 수 있다.

 

module.exports 도 모듈을 내보내는 키워드이다.

 

app.js를 아래와 같이 변경해도 코드의 동작은 똑같다.


1
2
module.exports.test = function(a,b){return a+b};
module.exports.test2 = function(c,d){return c-d};
cs


 

 

그렇다면 exports와 module.exports는 무슨 차이가 있을까

 

사실 차이가 없다.

 

우리는 module.exports로 이 기능을 사용한다.

즉 module 안에 exports가 있다는 이야기다.

 

module 안에 exports가 있기 때문에 exports.test 이렇게 작성해도 최종적으로 리턴되는 것은 module.exports.test다.


비동기 프로그래밍의 개념

1. callback

callback은 특정 함수에 매개변수로서 전달된 함수를 지칭한다.

예를 들어서 아래 코드같은 경우이다.


1
2
3
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});
cs


이 코드에서는 click함수의 인수로 function 이 들어있습니다. 이런 function 을 callback function 이라고 부릅니다.


이런 callback 함수는 작업을 비동기적으로 처리하기 위헤서 사용합니다.


2. async.js


async 는 비동기 흐름을 제어하기 위한 키워드이다.


node js의 장점 중 하나는 앞의 1번에 적은 callback 을 사용한 비동기적 처리가 잘 된다는 것이다.

하지만 callback에는 단점이 있다. "콜백 지옥"에 빠질 수가 있다.

"콜백 지옥"이란 콜백 기능을 연속해서 사용 할 경우, 콜백이 계속해서 중첩되는 상태를 말한다.

아래 코드 같은 경우를 말한다.


1
2
3
4
5
6
7
8
9
task1(a, function(err, data) {
    task2(b, function(err, data) {
        task3(c, function(err, data) {
            task4(d, function(err, data) {
                //함수 실행
            });
        });
    });
});
cs


이 코드는 단순한 경우이고 , 실제로 node js 로 코딩 할때는 4중첩 이상도 흔히 볼 수 있다.


그럼 async 키워드를 사용해보겠다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
async function asyncMain () {
    let data = await asyncFunction1('hello');
    console.log(data);
    data = await asyncFunction2('world');
    console.log(data);
}
 
function asyncFunction1 (inputString) {
    console.log('async function');
    return inputString;
}
 
function asyncFunction2 (inputString) {
    console.log('async function2');
    return inputString;
}
 
asyncMain();
cs


코드를 보면 asyncMain 함수의 앞에 async 키워드가 적혀있다. 

async 키워드를 사용하면 함수의 실행 흐름을 순차적으로 제어 할 수 있다.


일단 그냥 봐도 function 4개 중첩한 것 보다는 훨씬 가독성도 좋다.


실행 흐름은 이렇다.


ex ) 함수 1 실행 - > 함수 1 종료 -> 함수 2 실행 -> 함수 2 종료 -> 함수 3 실행 -> 함수 3 종료



3. Promise


async가 콜백 지옥을 벗어나기 위한 모듈이라면


Promise 는 콜백 지옥을 벗어나기 위한 패턴이다.


promise 패턴을 사용하면 비동기 작업들을 순차적으로 진행 할 수 있다.


비동기 작업을 병렬로 진행 할 수도 있다.


예제를 통해서 promise 를 살펴보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const condition = true;
const promise = new Promise((resolve, reject) => {
    if (condition) {
        resolve('성공');
    }
    else {
        reject('실패');
    }
});
 
promise
.then((message) => {
    console.log(message);
    console.log('여기가 실행됨');
})
.catch((error) => {
    console.error(error);
});
cs



실행하면


------------------------------------

성공

여기가 실행됨


------------------------------------


이렇게 출력된다.




코드를 첫번째 줄부터 살펴보겠다.


line 1 에서 condition 의 값은 true이다.


그래서 new Promise 안에 있는 코드는 무조건 if 문이 실행된다.


line 2부터 line 9 까지는 resolve 와 reject를 매개변수로 갖는 콜백함수이다.


condition 의 값이 true 이기 때문에 line2에서 line 10 사이에서 if 문이 실행된다.


if 문 안에는 resolve 가 있다.


이 resolve 는 line 12의 then 부분을 실행하게 된다.


만약에 line 7의 reject 를 만났다면 line 16의 catch 가 실행 되었을 것이다.


그래서 line 4가 실행되면 line 12의 message 부분에 '성공' 이 전달된다.


그러면 console에 '성공'을 출력한다.


then 부분은 여러 개 쓸 수도 있다.


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
const condition = true;
const promise = new Promise((resolve, reject) => {
    if (condition) {
        resolve('성공');
    }
    else {
        reject('실패');
    }
});
 
promise
.then((message) => {
    
    console.log(message+'1');
    
    return new Promise((resolve, reject) => {
        resolve(message);
    });
})
.then((message2) => {
    
    console.log(message2+'2');
    
    return new Promise((resolve, reject) => {
        resolve(message2);
    });
})
.catch((error) => {
    console.error(error);
});
cs



실행은 이렇다.


-----------------------------------------

성공 1

성공 2


-----------------------------------------


then 부분이 연달아 실행된다.


이렇게 코드를 작성하면 앞에 있는 then의 return 값을 다음 then 의 매개변수로 넘긴다.


즉,  실행과정이 이렇다. 


1. line 4가 실행된다.


2. line 4는 line 12를 실행한다. - 여기서 '성공 1' 이 출력된다.


3. line 12 의 return 에는 새로운 Promise 객체와 resolve 가 들어있다. 


4. resolve의 괄호 안에 message 를 적어서 건넨다.


5. 이 resolve 는 line 20의 then 을 호출한다. - 여기서 '성공 2' 가 출력된다.



node js 에서의 http 트랜잭션


node js 로 만든 웹 애플리케이션은 아래 과정을 거친다.


1. 서버 생성


1
2
3
4
5
const http = require('http');
 
http.createServer((request, response) => {
 
});
cs


서버 생성은 createServer 명령을 통해서 한다.


2. 메소드 url 헤더


http 트랜잭션은 url과 처리할 메소드를 확인 한 후 작업을 처리합니다.


헤더는 요청의 앞에 붙는 "머리말" 정도로 생각하면 됩니다.


주고 받는 데이터가 json 인지 html 인지를 헤더에 정의하기도 합니다.


3. 요청 바디


요청 바디에는 주고받는 데이터 값이 들어있습니다.

post 나 put 방식으로 데이터를 전송할 때 데이터의 값입니다.


http 트랜잭션을 이용할 때는 json , xml 등의 형태로 값을 보낼 수 있습니다.



4.  에러 확인 처리



http 상태 코드


상태 코드 200 - 정상 요청


상태 코드 300 - 리다이렉션 ( 요청한 리소스에 새로운 uri 가 지정되어 있는 경우. 다른 페이지로 리다이렉트 한다.)


상태 코드 400 - 클라이언트의 요청 에러 ( ex) 잘못된 값을 전달한 경우 )


상태 코드 500 - 서버의 처리 과정에서 에러 발생



응답 헤더 설정하기


response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');


헤더에서는 setHeader 를 사용해서 응답 값의 타입을 지정할 수 있다.


명시적인 헤더 데이터 전송


1
2
3
4
response.writeHead(200, {
  'Content-Type''application/json',
  'X-Powered-By''bacon'
});
cs


응답 코드를 지정 할 수도 있다.(ex) 200, 300 ,400)


응답 바디 전송


write 를 사용해서 응답 바디를 전송 할 수도 있다.


response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();


이 코드는 html 이다. json 도 write해서 jsonString을 응답으로 보낼 수 있다.


json 을 보낼때는 헤더에 데이터 타입을 application/json 으로 설정하면 된다.

express 의 미들웨어

여기 네트워크를 통해서 연결된 여러 개의 컴퓨터가 있다.

각 컴퓨터에는 많은 프로세스가 있다.

많은 프로세스들에게 어떤 서비스를 사용 할 수 있도록 연결해주는 소프트웨어도 있다.


이렇게 연결해주는 소프트웨어를 보통 "미들웨어"라고 부른다.


node js 에서는 express 라는 라우팅 , 미들웨어 웹 프레임워크가 있다.


라우팅 기능을 통해서 클라이언트가 보낸 요청을 구분하고 처리 할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
app.get('/user/:id'function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});
 
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id'function (req, res, next) {
  res.end(req.params.id);
});app.get('/user/:id'function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});
 
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id'function (req, res, next) {
  res.end(req.params.id);
});
cs




ejs로 html 템플릿 작성하기


express 에서는 템플릿 엔진을 제공한다.


템플릿 엔진을 사용하면 훨씬 적은 코드로 html 페이지를 만들 수 있다.


아래 코드 예제를 보자.


express generator 를 사용 했을 때 , index.ejs 예제 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
  <head>
    <title><%title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%title %></h1>
    <p>Welcome to <%title %></p>
    <ul>
      <% for(var i = 1; i < 10; i++){ %>
        <li>
          <%gugu %> * <%=i%> = <%gugu * i %>
        </li>
      <% } %>
    </ul>
  </body>
</html>
cs


express generator 를 사용 했을 때, index.js 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const express = require('express');
const router = express.Router();
 
/* GET home page. */
router.get('/'function(req, res, next) {
 
    const num = req.param('num');
    let resultString = '';
    if (isNaN(num)) {
        res.statusCode = 400;
    } else {
        for(let i = 1 ; i < 10 ; i++) {
            resultString = resultString + num + "*" + i + "=" + (num * i) + " ";
        }
        res.status(200);
        res.render('index', { title : 'Express', gugu : num});
    }
    res.end();
 
});
 
module.exports = router;
 
cs


댓글