Chatterbox Server

Jiyoung·2020년 12월 28일
0

Node.js란?

Node.js는 V8엔진으로 만들어진 자바스크립트 런타임(runtime)이다.

V8엔진: 자바스크립트를 기계어로 바꿔줌(compile)
런타임(runtime): 프로그래밍 언어가 구동되고 있는 환경

위의 정의로 Node.js의 정의를 풀어보면, Node.js란 자바스크립트를 기계어로 바꿔주는 엔진으로 만들어진 자바스크립트가 구동중인 환경이다.

Node.js는 이벤트 기반 및 논블로킹 I/O모델이라는 특성을 갖는다.

이벤트: 유저의 버튼 클릭이나 네트워크에 리소스를 요청 하는 것 등
블로킹(blocking): 다음 함수의 실행이 현재 함수의 종료 이후에 이루어 지는 것
논블로킹(non-blocking): 다음 함수의 실행이 현재 함수의 종료를 기다리지 않음(비동기)
I/O모델: Input을 주면 Output을 반환하는 모델

즉, 이벤트 기반 및 논블로킹 I/O모델이란 유저의 클릭이나 네트워크에 리소스를 요청 하는 이벤트가 논블로킹으로 이루어지는 Input Output 모델을 의미한다.

종합해보면 Node.js는 자바스크립트를 기계어로 바꿔서 구동하고, 이벤트 기반의 논블로킹 모델로 속도가 빠르다는 장점을 가진 자바스크립트 런타임이다.

Node Core Modules

Node.js는 별도의 설치가 필요없이 노드 상에서 쓸 수 있는 모듈이 있다. Package manager에서 설치하지 않아도 require("") 방식으로 fs(file system), http, url, path 등을 사용할 수 있다.

const fs = require('fs')
const http = require('http')

fs.readFile('./something.json',(err,data)=>{
    console.log(data);
}) //fs의 readFile 메소드를 사용

http.get('http://localhost:5000/api',(res)=>{
    console.log(res)
})

NPM(Node Package Manager)

NPM은 Node Package Manager의 준말로, 세계에서 가장 큰 오픈소스 라이브러리 생태계 중 하나이다.

<html>
    <head>
        <script src="https://code.jquery.com/jquery-2.x-git.min.js"></script>
    </head>
    <body>
        <script>
            $('button').on('click',function () {})
        </script>
    </body>
</html>

이전에는 위처럼 jQuery라는 모듈을 html에서 사용하려면 자바스크립트(js) 파일을 script태그를 통해 불러와서 활용할 수 있었다면,

const $ = require('jquery')

$('button').on('click',function() {
    console.log('button clicked!!!')
})

이제는 NPM을 활용하여 jquery라는 모듈을 받아와서 바로 코드 상에서 활용할 수 있다.

Package.json

Package.json은 NPM을 활용하기 위한 정보들이 모여있는 파일로, project 전반에 관한 정보가 들어있다.

이미지 출처: codestates urclass

dev-dependency에는 production과 직접적인 관계는 없지만 compile이나 테스트를 하기 위한 용도로 내려받은 package들이 적혀있다. dev-dependency를 설치하기 위해서는 --dev 옵션을 줘서 등록한다.

$ yarn add @babel/core --dev
(or)
$ npm install @babel/core --save-dev

dependency 안의 라이브러리는 production과 직접적인 관련이 있는 것으로, npm에서는 --save 옵션을 줘서 등록할 수 있다.

$ yarn add react 
(or)
$ npm install --save react

'npm install'은 package.json에 있는 dependency를 바탕으로 설치되는데, 설치한 dependecny가 dependency에 등록이 되어있지 않고 코드에서 실제로 사용되고 있다면 코드에서는 해당 모듈을 쓰고 있지만 npm install로는 설치 되지 않았기 때문에 해당 코드는 오류가 발생하게 된다. 따라서 협업 시 내가 사용한 모듈을 dev-dependency 혹은 dependency에 등록하지 않을 경우 팀 갈등의 주요 원인이 된다. 따라서 꼭 save 옵션으로 내가 사용한 모듈을 dependency에 등록해줘야 한다.

npm start는 scripts의 start에 정의되어 있는데 보통 서버 start 코드로 설정되어 있다.

{
  "scripts": {
    "start": "node index.js"
  },
}

node는 서버가 일회성으로 실행되고 종료되는데 반해, nodemon은 변경사항을 반영해서 즉각적으로 서버를 다시 실행시켜주는 라이브러리이다.

npm install --save nodemon
{
  "scripts": {
    "start": "nodemon index.js"
  },
}

HTTP

브라우저에서 url을 입력하고 엔터를 누를 때 어떤 일들이 일어날까?

Step 1: 도메인 이름 탐색

1) DNS서버에 접속한 후 해당 url의 IP가 무엇인지 요청
2) 요청에 대한 응답으로 IP주소 리턴

Step2: 웹 서버(HTTP) 요청

1) 웹 서버의 라우팅(routing: 조건에 따른 분기)에 따라 요청 처리
2) 서버가 요청에 대한 응답을 자원(resource, HTML/JS파일 등) 형태로 전달
3) 서버가 보내주는 자원을 브라우저에서 처리
** 없을 경우 '404 Not Found' 페이지 실행. 404는 HTTP의 status code를 의미함.

HTTP는 서버와 클라이언트가 HTML 등의 문서를 주고받는 데 사용하는 프로토콜로, 주로 TCP/UDP 80번 포트를 사용한다. HTTP는 요청과 응답, 그리고 Body로 이루어져 있다.

HTTP 요청(Request)

GET / HTTP/1.1 //요청 메소드 + URI + HTTP version
Host: developer.mozilla.org
Accept-Language: fr

HTTP요청은 URI를 통해 할 수 있으며, 주소창을 통해 하는 요청은 모두 GET 요청이다. HTTP 요청 메소드에는 GET, POST, PUT, DELETE 등이 있다.

GET: 특정 리소스를 가져오도록 요청
POST: 데이터를 서버로 제출하는 요청(form 제출, submit 버튼 눌렀을 때), 서버 상태의 변화를 일으킴
PUT: POST와 비슷하지만 연속적인 요청에도 같은 효과를 가져옴. 기존 데이터를 교체하는 용도로 사용할 수 있음
DELETE: 리소스의 삭제를 요청

HTTP 응답(Response)

HTTP/1.1 200 OK //정상적인 응답일 경우 200 리턴
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html

<!DOCTYPE html... (here comes the 29769 bytes of the requested web page)//실질적인 내용이 담김(HTTP서버로부터 받은 콘텐츠)

CORS(Cross Origin Resource Sharing)

예전에는 서버에 클라이언트라는 파일을 가지고 있고 사용자가 서버에 요청을 하면 서버에서 내려받은 클라이언트로 통신이 이루어졌다. 따라서 서버에서 내려받은 클라이언트는 서버에 위해가 가는 행위를 하지 않을 것이라는 확신이 있었다. 그러나 최근에 웹 어플리케이션이 고도화되면서 YouTube, GitHub 등 다른 서버에 있는 리소스를 활용할 필요가 생겼다.
이미지 출처: codestates urclass

same origin이 아닌 다른 origin에서 리소스(서버자원)를 요청하여 사용해야되는데, 이를 cross origin 요청이라고 한다. 보안상의 이유로 브라우저에서 크로스 도메인 요청은 기본적으로 제한하고 있지만 웹 어플리케이션 고도화를 위해 개발자들이 개선 요청을 하였고, 이에 서버가 허용한 범위 내에서 cross origin 요청이 허용되고 있다.

const defaultCorsHeaders = {
  "access-control-allow-origin": "*", //모든 도메인(*)에서 우리 서버로 cross origin 요청 가능
  "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS", //메소드는 GET, POST, PUT, DELETE, OPTIONS만 허용
  "access-control-allow-headers": "content-type, accept", //헤더에는 content-type과 accept만 쓸 수 있음
  "access-control-max-age": 10 // Seconds. Preflight Request는 10초까지 허용됨
};

CORS에서 OPTIONS메소드를 통해 Preflight Request(사전 요청)를 보내 서버가 해당 parameters를 포함한 요청을 보내도 되는지에 대한 응답을 줄 수 있게 한다.

CommonJS

CommonJS는 JavaScript를 브라우저에서뿐만 아니라, 서버사이드 애플리케이션이나 데스크톱 애플리케이션에서도 사용하려고 조직한 자발적 워킹 그룹이다. CommonJS의 'Common'은 JavaScript를 브라우저에서만 사용하는 언어가 아닌 일반적인 범용 언어로 사용할 수 있도록 하겠다는 의지를 나타내고 있는 것이라고 이해할 수 있다.

  1. 스코프(Scope): 모든 모듈은 자신만의 독립적인 실행 영역이 있어야 한다.
  2. 정의(Definition): 모듈 정의는 전역 객체인 exports 객체를 이용한다.
  3. 사용(Usage): 모듈 사용은 require 함수를 이용한다.

module.exports vs. exports

// --  hello.js
exports.anything = function() {
  console.log('I am anything.');
};
// -- hello-runner.js
const hello = require('./hello');
// let's see what's there in hello variable
console.log(hello); // {anything: Function}
hello.anything(); // I am anything.

exports는 module.exports 사용을 도와주는 helper로, exports는 module.exports를 참조할 뿐이다. module.exports에 뭔가가 이미 붙어있다면 exports는 무시된다. 두 가지를 섞어쓰지 않아야 된다.

// --  hello.js
module.exports.anything = function() {
  console.log('I am anything.');
};
// -- hello-runner.js
const hello = require('./hello');
// let's see what's there in hello variable
console.log(hello); // {anything: Function}
hello.anything(); // I am anything.
profile
경계를 넘는 삶

0개의 댓글