본문 바로가기

WINK-(Web & App)/Express.js (Node.js) 스터디

[2024 Node.js 스터디] 김태일 #4주차

반응형

03. 노드 기능 알아보기

 

03.1 REPL 사용하기

 

- REPL이란?

Read : 입력한 코드를 읽고

Eval : 해석하고

Print : 결과물 반환

Loop : 종료할 때까지 반복

 

- REPL 사용

1) 콘솔을 열고 node를 입력

2) 프롬프트가 > 모양으로 바뀜

3) 코드 입력

4) ctrl+c 두번 혹은 .exit를 통해 종료

 

 REPL은 짧은 코드를 테스트해보는 용도

    긴 코드는 자바스크립트 파일을 통째로 실행하는것이 더 유용

 

 

03.2 JS파일 실행하기

 

1) 콘솔에서 node [자바스크립트 파일 경로]로 실행

$ node helloWorld  -->   helloWorld.js 파일 실행

REPL에서 입력하는 것이 아니므로 주의

  (콘솔에서 REPL로 들어가는 명령어가 node이고, 노드를 통해 파일을 실행하는 명령어는 node [자바스크립트 파일 경로]입니다.)

 

 

03.3 모듈로 만들기

 

모듈이란?

- 특정한 기능을 하는 함수나 변수들의 집합

- 하나의 프로그램이면서 다른 프로그램의 부품으로도 사용 가능

- 재사용 가능

 

 

1) CommonJS 모듈

- 표준 자바스크립트모듈 X

- 가장 널리 쓰이는 모듈

//var.js
const odd = 'CJS 홀수입니다';
const even = 'CJS 짝수입니다';

module.exports = {
  odd,
  even,
};

변수 2개 선언, module.exports에 변수들을 담은 객체 대입

이 파일이 모듈로서 기능 (변수들을 모아둔 모듈)

다른 파일에서 이 파일을 불러오면 module.exports에 대입된 값 사용 가능

//func.js
const { odd, even } = require('./var');

function checkOddOrEven(num) {
  if (num % 2) { // 홀수이면
    return odd;
  }
  return even;
}

module.exports = checkOddOrEven;

//var.js의 module.exports에 담겨있던 객체를 불러와 func.js에서 사용

require 함수 안에 불러올 모듈 경로 작성

※js같은 확장자 생략가능 (index.js도 생략 가능)

var.js에서 변수 불러온 후 숫자 홀짝 판별하는 함수 선언, 다시 module.exports에 함수 대입

다른 모듈을 사용하는 파일을 다시 모듈로 만들 수 있음.

module.exports에는 함수, 변수 대입 가능

//index.js
const { odd, even } = require('./var');
const checkNumber = require('./func');

function checkStringOddOrEven(str) {
  if (str.length % 2) { // 홀수이면
    return odd;
  }
  return even;
}

console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
//var.js와 func.js 모두 참조

모듈 하나가 여러개의 모듈을 사용 가능

 

$ node index
CJS 짝수입니다
CJS 홀수입니다

콘솔에서 index.js를 실행하면 결과는 다음과 같다

//var.js
exports.odd = 'CJS 홀수입니다';
exports.even = 'CJS 짝수입니다';

module.exports 말고 위처럼 exports 객체로 모듈을 수정해도 결과는 동일

-->module.exports와 exports가 같은 객체를 참조하기 때문

 

 

장점 : 여러파일에 걸쳐 재사용되는 함수나 변수를 모듈로 만들어두면 편리

단점 : 모듈이 많아지고 모듈간의 관계가 얽히게 되면 구조 파악 힘듦

 

-require함수

모듈을 불러오는 함수

//require.js
console.log('require가 가장 위에 오지 않아도 됩니다.');

module.exports = '저를 찾아보세요.';

require('./var');

console.log('require.cache입니다.');
console.log(require.cache);
console.log('require.main입니다.');
console.log(require.main === module);
console.log(require.main.filename);

 

require, module.exports 모두 아무 위치에서나 사용 가능

 

- require.cache

한번 require한 파일은 require.cache에저장

다시 require할 때는 require.cache에 있는 것이 재사용

새로 require을 원할 때는 속성을 제거하면 되지만, 동작이 꼬일 수도 있으므로 추천 X

 

- require.main

노드 실행 시 첫 모듈

위 코드에서는 node require을 실행했으므로 require.js가 require.main이 됨

require.main === module   -->   현재 파일이 첫 모듈인지 확인

require.main.filename    -->  첫 모듈의 이름 확인

 

- 순환 참조

서로를 require하는 두 모듈  dep1.js, dep2.js가 있다고 가정해볼때

//dep-run.js
const dep1 = require('./dep1');
const dep2 = require('./dep2');

dep1();
dep2();

$node dep-run을 통해 실행해보면 require('./dep1')이 실행되고 dep1.js에서는 reqire('./dep2')가 실행됨

이 과정에서 dep1의 module.exports가 빈 객체로 표시되는 현상 = 순환 참조

순환 참조가 있을 경우, 순환 참조되는 대상을 빈 객체로 변경

에러 발생은 안되지만 예기치 못한 동작 발생 할 수 있으므로 순환참조 되지 않도록 주의

 

 

2) ECMAScript 모듈

- 공식적인 자바스크립트 모듈 형식

- 브라우저에서도 사용 가능

//var.mjs
export const odd = 'MJS 홀수입니다';
export const even = 'MJS 짝수입니다';
//func.mjs
import { odd, even } from './var.mjs';

function checkOddOrEven(num) {
  if (num % 2) { // 홀수이면
    return odd;
  }
  return even;
}

export default checkOddOrEven;

 

//index.mjs
import { odd, even } from './var.mjs';
import checkNumber from './func.mjs';

function checkStringOddOrEven(str) {
  if (str.length % 2) { // 홀수이면
    return odd;
  }
  return even;
}

console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
$ node index.mjs
MJS 짝수입니다
MJS 홀수입니다

CommonJS의 require와  exports, module.exports가 각각 import, export, export default로 바뀜

ES 모듈의 import, export default는 문법 그 자체 (함수나 객체 X)

파일 확장자 js -> mjs 로 변경

 

package.json에 type:"module" 속성을 넣으면 js확장자에서 ES모듈 사용 가능 (5장 내용 참고)

 

차이점 CommonJS 모듈 ECMAScript 모듈
문법 require('./a');
module.exports = A;
const A = require('./a');
exports.C = D;
const E = F; exports.E = E;
const { C, E } = require ('./b');
import './a.mjs';
export default A;
import A from './a.mjs';
export const C = D;
const E = F; export { E };
import { C, E } from './b.mjs';
확장자 js
cjs
js(package.json에 type: "module" 필요)
mjs
확장자 생략 가능 불가능
다이내믹 임포트 가능(3.3.3절 참고) 불가능
인덱스(index) 생략 가능(require('./folder')) 불가능(import './folder/index.mjs')
top level await 불가능 가능
__filename, __dirname, require, module.exports, exports 사용 가능(3.3.4절 참고) 사용 불가능(__filename 대신 import.meta.url 사용)
서로 간 호출 가능

웬만하면 두 모듈 중 한 가지 형식만 사용하는 것을 권장 (서로 간의 호환되지 않는 케이스가 많음)

 

 

3) 다이내믹 임포트

- 조건부로 모듈을 불러오는 것

//dynamic.js
const a = false;
if (a) {
    require('./func');
}
console.log('성공');
$ node dynamic
성공

if문이 false이므로 require('./func')는 실행 X

import './func.mjs'; --> 에러

 

ES모듈은 if문 안에서 import하는 것 불가능 --> 다이내믹 임포트 사용

//dynamic.mjs
const a = true;
if (a) {
    const m1 = await import('./func.mjs');
    console.log(m1);
    const m2 = await import('./var.mjs');
    console.log(m2);
}
$ node dynamic.mjs
[Module: null prototype] { default: [Function: checkOddOrEven] }
[Module: null prototype] { even: 'MJS 짝수입니다', odd: 'MJS 홀수입니다' }

import 함수를 사용해 모듈을 동적으로 불러올 수 있음

import는 Promise를 반환하므로 awiat나 then을 붙어야 함 (?)

ES모듈 최상위 스코프에서는 async함수 없이 await가능 (CommonJS모듈에서는 불가능)

 

결괏값도 눈여겨볼 필요가 있습니다. export default의 경우 import할 때도 default라는 속성 이름으로 import됩니다. 참고로 CommonJS 모듈에서 module.exports한 것도 default라는 이름으로 import됩니다. (?)

 

4) __filename, __dirname

- 현재 파일명이나 파일의 경로 대한 정보 제공

- 보통 path모듈과 함께 사용 (경로가 문자열로 반환, 경로 구분자 문제 때문) 

 

※ ES모듈에서는 import.meta.url로 경로를 가져옴

 

 

03.4 노드 내장 객체 알아보기

 

내장객체

- require함수나 module객체를 따로 선언하지 않고도 사용 가능하게 해줌

 

1) global 객체- 브라우저의 window와 같은 전역 객체 --> 모든 파일에서 접근 가능

- 파일 간의 간단한 데이터를 공유할 때 사용

//globalA.js
module.exports = () => global.message;
//globalB.js
const A = require('./globalA');

global.message = '안녕하세요';
console.log(A());
$ node globalB
안녕하세요

globalB에서 넣은 global.message값을 globalA에서도 접근 가능

 

2) console 객체

- 보통 디버깅을 위해 사용

- 변수에 값이 제대로 들어 있는지 확인하기위해 사용

- 에러 발생 시 콘솔에 표기하기 위해 사용

- 코드 실행 시간을 알아보기 위해 사용

console.time(레이블) 같은 레이블을 가진 time timeEnd 사이의 시간을 측정합니다.
console.log(내용) 평범한 로그를 콘솔에 표시
console.error(에러 내용) 에러를 콘솔에 표시
console.table(배열) 배열의 요소로 객체 리터럴을 넣으면, 객체의 속성들이 테이블 형식으로 표현됨
console.dir(객체, 옵션) 객체를 콘솔에 표시할 때 사용
console.trace(레이블)  에러가 어디서 발생했는지 추적할 수 있게 함

 

3) 타이머 객체

- 타이머 기능을 제공하는 함수

 setTimeout(콜백 함수, 밀리초) 주어진 밀리초(1,000분의 1초) 이후에 콜백 함수를 실행
setInterval(콜백 함수, 밀리초) 주어진 밀리초마다 콜백 함수를 반복 실행
setImmediate(콜백 함수)  콜백 함수를 즉시 실행
clearTimeout(아이디) setTimeout을 취소합니다
clearInterval(아이디) setInterval을 취소
clearImmediate(아이디) setImmediate를 취소

 

4) process 객체

- 현재 실행되고 있는 프로세스에 대한 정보를 담고 있음

process.version 설치된 노드의 버전
process.arch 프로세서 아키텍처 정보
process.platform 운영체제 플랫폼 정보
process.pid 현재 프로세스의 아이디
process.uptime() 프로세스가 시작된 후 흐른 시간
process.execPath 노드의 경로
process.cwd() 현재 프로세스가 실행되는 위치
process.cpuUsage() 현재 cpu 사용량
process.env 시스템의 환경 변수
process.nextTick(콜백) 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선 처리
process.exit(코드) 실행 중인 노드 프로세스 종료

 

 

5) 기타 내장 객체

URL, URLSearchParams 3.5.3절 참고
 AbortController, FormData, fetch, Headers,
Request, Response, Event, EventTarget
브라우저에서 사용하던 API가 노드에도 동일하게 생성
TextDecoder Buffer를 문자열로 변경
TextEncoder 문자열을 Buffer로 변경
WebAssembly 웹어셈블리 처리를 담당

 

 

03.5 노드 내장 모듈 사용하기

 

노드 내장 모듈

- 운영체제 정보 접근

- 클라이언트가 요청한 주소에 대한 정보를 가져옴

 

1) os

- os 모듈에 정보가 담겨 있어 정보를 가져올 수 있음

- 컴퓨터 내부 자원에 빈번하게 접근하는 경우 사용

- 운영체제별로 다른 서비스를 제공하고 싶을 때 유용

os.arch() 프로세서 아키텍처(process.arch와 동일)
os.platform() 운영체제 플랫폼 정보(process.platform과 동일)
os.type() 운영체제의 종류를 보여줌
os.uptime() 운영체제 부팅 이후 흐른 시간(초)을 보여줌
os.hostname() 컴퓨터의 이름을 보여줌
os.release() 운영체제의 버전을 보여줌
os.homedir() 홈 디렉터리 경로를 보여줌
os.tmpdir() 임시 파일 저장 경로를 보여줌
os.cpus() 컴퓨터의 코어 정보를 보여즘
os.freemem() 사용 가능한 메모리(RAM)를 보여줌
os.totalmem() 전체 메모리 용량을 보여줌
os.constants() 각종 에러와 신호에 대한 정보

 

2) path

- 폴더와 파일의 경로를 쉽게 조작하도록 도와주는 모듈

- 운영체제별로 경로 구분자가 다르므로 path모듈 필요 (윈도우 : \ , POSIX(맥, 리눅스) : / )

 path.sep 경로의 구분자 (윈도는 \, POSIX는 /)
path.delimiter 환경 변수의 구분자(윈도는 세미콜론(;)이고, POSIX는 콜론(:))
path.dirname(경로) 파일이 위치한 폴더 경로를 보여줍
path.extname(경로) 파일의 확장자를 보여줌
path.basename(경로, 확장자) 파일의 이름(확장자 포함)을 표시
 path.parse(경로) 파일 경로를 root, dir, base, ext, name으로 분리
path.format(객체) path.parse()한 객체를 파일 경로로 결합
 path.normalize(경로) /나 \를 실수로 여러 번 사용했거나 혼용했을 때 정상적인 경로로 변환
path.isAbsolute(경로) 파일의 경로가 절대경로인지 상대경로인지를 true false로 알림
path.relative(기준경로, 비교경로) 첫 번째 경로에서 두 번째 경로로 가는 방법을 알림
path.join(경로, …) 여러 인수를 넣으면 하나의 경로로 합침
path.resolve(경로, …) path.join()과 비슷

 

3) url

- 인터넷 주소를 쉽게 조작하도록 도와주는 모듈

주소의 각 부분별 명칭

 

url.format(객체) url객체를 다시 원래 상태로 조립

 

4) dns

DNS란?

- 도메인 이름 시스템으로서 도메인이름을 ip주소로 변환한다

 

DNS 모듈

- DNS를 다룰 때 사용하는 모듈

- 주로 도메인을 통해 IP나 기타 DNS정보를 얻고자 할 때 사용

dns.lookup ip주소 확인
dns.resolve(도메인) ip주소 확인
dns.resolve(도메인, 레코드 이름) 해당 레코드에 대한 정보 조회

 

5) crypto

- 다양한 방식의 암호화를 도와주는 모듈

 

5-1) 단뱡향 암호화

- 한번 암호화하면 원래 문자열을 찾을 수 없음

- 복호화 할 수 없는 암호화 방식  -->   해시 함수라고도 부름

          + 복호화 : 부호(code)화 된 정보를 부호(code)화 되기 전으로 돌리는 처리방식

 

고객의 비밀번호는 복호활 필요가 없다?

a) 고객의 비밀번호를 암호화해서 데이터베이스에 저장

b) 로그인 할 때마다 입력받은 비밀번호를 같은 암호화 알고리즘으로 암호화

c) 데이터베이스의 비밀번호와 비교

--> 원래 비밀번호는 어디에도 저장되지 않고 암호화된 문자열로만 비교

 

5-2) 양방향 암호화

- 복호화 가능  -->  키(열쇠)라는 것이 사용됨

crypto.createCipheriv(알고리즘, 키, iv) 암호화 알고리즘과 키, iv를 넣음
crypto.getCiphers() 사용 가능한 알고리즘 목록 보여줌
cipher.update(문자열, 인코딩, 출력 인코딩) 암호화할 대상과 대상의 인코딩, 출력 결과물의 인코딩을 넣음
cipher.final(출력 인코딩) 출력 결과물의 인코딩을 넣으면 암호화가 완료
crypto.createDecipheriv(알고리즘, 키, iv) 복호화할 때 사용
decipher.update(문자열, 인코딩, 출력 인코딩) 암호화된 문장, 그 문장의 인코딩, 복호화할 인코딩을 넣음
decipher.final(출력 인코딩) 복호화 결과물의 인코딩을 넣음

 

6) util

- 각종 편의 기능을 모아둔 모듈

util.deprecate 함수가 deprecated 처리되었음을 알림
util.promisify 콜백 패턴을 프로미스 패턴으로 바꿈
util.callbackify
프로미스를 콜백으로 바꿈

 

7) worker_threads

- 멀티 스레드 방식으로 작업을 가능하게 하는 모듈

isMainThread 현재 코드가 메인 스레드에서 실행되는지, 우리가 생성한 워커 스레드에서 실행되는지 구분

 

worker.postMessage 부모에서 워커에 데이터를 보냄
parentPort.on('message') 부모로부터 메시지를 받음
parentPort.postMessage 부모에게 메시지를 보냄
worker.on('message') 부모가 메시지를 받음
once('message') 메시지를 한 번만 받음
parentPort.close()
부모와의 연결 종료

(부모 스레드 = 메인 스레드)

 

8) child_process

- 노드에서 다른 프로그램을 실행하고 싶거나 명령어를 수행하고 싶을 때 사용하는 모듈

- 다른언어의 코드를 실행하고 결괏값을 받을 수 있음

- 현재 프로세스 외에 새로운 프로세스를 띄어서 명령을 수행하고 결과를 알려줌

 

9) 기타 모듈들

async_hooks 비동기 코드의 흐름을 추적할 수 있는 실험적인 모듈
dgram UDP와 관련된 작업을 할 때 사용
net HTTP보다 로우 레벨인 TCP나 IPC 통신을 할 때 사용
perf_hooks 성능 측정을 할 때 console.time보다 더 정교하게 측정
querystring 쿼리스트링을 다루기 위해 사용
string_decoder 버퍼 데이터를 문자열로 바꾸는 데 사용
tls TLS와 SSL에 관련된 작업을 할 때 사용
tty 터미널과 관련된 작업을 할 때 사용
v8 v8 엔진에 직접 접근할 때 사용
vm 가상 머신에 직접 접근할 때 사용
wasi 웹어셈블리를 실행할 때 사용하는 실험적인 모듈

 

03.6 파일 시스템 접근하기

fs 모듈

- 파일 시스템에 접근하는 모듈

- 파일을 생성하거나 삭제하고, 읽거나 쓸 수 있음

- 폴더 생성, 삭제 가능

 

1) 동기 메서드와 비동기 메서드

 

1-1) 동기

직렬적으로 태스크를 실행하는 방식

 

1-2) 비동기

병렬적으로 태스크를 실행하는 방식

 

- 노드는 대부분의 메서드를 비동기 방식으로 처리

//async.js
const fs = require('fs');

console.log('시작');
fs.readFile('./readme.txt', (err, data) => {
  if (err) {
    throw err;
  }
  console.log('1번', data.toString());
});
fs.readFile('./readme.txt', (err, data) => {
  if (err) {
    throw err;
  }
  console.log('2번', data.toString());
});
fs.readFile('./readme.txt', (err, data) => {
  if (err) {
    throw err;
  }
  console.log('3번', data.toString());
});
console.log('끝');

비동기 메서드들은 해당 파일(readme.txt)을 읽으라고만 요청하고 다음 작업으로 넘어간다.

 

따라서 다음 코드를 출력하면

$ node async
시작
끝
2번 저를 여러 번 읽어보세요.
3번 저를 여러 번 읽어보세요.
1번 저를 여러 번 읽어보세요.

와 같이 끝을 먼저 찍음. 그 이후 읽기가 완료되면 메인스레드가 콜백함수를 실행하게 됨

 

위 방식은 수백 개의 요청이 들어와도 메인스레드는 백그라운드에 요청 처리를 위임하여 얼마든지 요청을 더 받을 수 있음

이후 백그라운드가 요청 처리가 완료되었다 알리면 그때 콜백함수를 처리하므로 효율적임

 

2) 버퍼와 스트림 이해하기

- 파일을 읽거나 쓰는 방식

 

2-1) 버퍼

- 메모리에 저장된 데이터

Buffer : 버퍼를 직접 다룰 수 있는 클래스

Buffer.from 문자열을 버퍼로 변경
buffer.toString(버퍼) 버퍼를 문자열로 변경
Buffer.concat(배열) 배열 안에 든 버퍼들을 합침
Buffer.alloc(바이트) 빈 버퍼를 생성

 

2-2) 스트림

- 버퍼의 크기를 작게 만들고 여러번에 걸쳐 나눠 보낼때 사용

createReadStream 읽기 스트림 생성
highWaterMark 버퍼의 크기를 결정
readStream  에러, 읽기, 종료등 상황을 확인

 

※파이핑(pipe) : 스트림끼리 연결하는 것

 

3) 기타 fs 메서드 알아보기

fs.access(경로, 옵션, 콜백) 폴더나 파일에 접근할 수 있는지를 체크
fs.mkdir(경로, 콜백) 폴더를 만드는 메서드
fs.open(경로, 옵션, 콜백) 파일의 아이디(fd 변수)를 가져오는 메서드
fs.rename(기존 경로, 새 경로, 콜백) 파일의 이름을 바꾸는 메서드
fs.readdir(경로, 콜백) 폴더 안의 내용물을 확인
 fs.unlink(경로, 콜백) 파일을 지울 수 있음
fs.rmdir(경로, 콜백) 폴더를 지울 수 있음

 

4) 스레드 풀 알아보기

- 동시에 실행되는 작업을 관리하는 데 사용

 

 

03.7 이벤트 이해하기

on(이벤트명, 콜백) 이벤트 이름과 이벤트 발생 시의 콜백을 연결
addListener(이벤트명, 콜백) on과 기능이 같음
emit(이벤트명) 이벤트를 호출하는 메서드
once(이벤트명, 콜백) 한 번만 실행되는 이벤트
removeAllListeners(이벤트명) 이벤트에 연결된 모든 이벤트 리스너를 제거
removeListener(이벤트명, 리스너) 이벤트에 연결된 리스너를 하나씩 제거
off(이벤트명, 콜백) removeListener와 기능이 같음
listenerCount(이벤트명) 현재 리스너가 몇 개 연결되어 있는지 확인

 

 

03.8 예외 처리하기

예외 : 처리하지 못한 에러

//error1.js
setInterval(() => {
  console.log('시작');
  try {
    throw new Error('서버를 고장내주마!');
  } catch (err) {
    console.error(err);
  }
}, 1000);

에러가 발생할 것 같은 부분을 미리 try/catch로 감싸면 됨

uncaughtException : 처리하지 못한 에러가 발생했을 때 프로세스가 유지

 

1) 자주 발생하는 에러들

node: command not found 노드를 설치했지만 이 에러가 발생하는 경우는 환경 변수가 제대로 설정 안 됨
ReferenceError: 모듈 is not defined 모듈을 require했는지 확인
Error: Cannot find module 모듈명  해당 모듈을 require했지만 설치하지 않음
Error [ERR_MODULE_NOT_FOUND] 존재하지 않는 모듈을 불러옴
Error: Can't set headers after they are sent 요청에 대한 응답을 보낼 때 응답을 두 번 이상 보냄
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed- JavaScript heap out of memory 코드를 실행할 때 메모리가 부족해서 스크립트가 정상적으로 작동하지 않는 경우
UnhandledPromiseRejectionWarning: Unhandled promise rejection 프로미스 사용 시 catch 메서드를 붙이지 않으면 발생
EADDRINUSE 포트 번호 해당 포트 번호에 이미 다른 프로세스가 연결되어 있음
EACCES 또는 EPERM 노드가 작업을 수행하는 데 권한이 충분하지 않음
EJSONPARSE  JSON 파일에 문법 오류
ECONNREFUSED  요청을 보냈으나 연결이 성립하지 않음
ETARGET  패키지 버전이 존재하지 않음
ETIMEOUT 요청을 보냈으나 응답이 시간 내에 오지 않을 때 발생
ENOENT: no such file or directory 지정한 폴더나 파일이 존재하지 않는 경우

더 많은 에러코드 https://nodejs.org/dist/latest-v18.x/docs/api/errors.html#errors_node_js_error_codes 참고

 

 

04. http모듈로 서버 만들기

 

04.1 요청과 응답 이해하기

서버 : 요청을 받고 응답을 보냄

클라이언트 : 요청을 보내고 응답을 받음

 

※localhost와 포트

localhost : 현재 컴퓨터의 내부 주소 

IP : 숫자 주소

포트 : 서버 내에서 프로세스를 구분하는 번호 (포트번호는 IP주소 뒤에 콜론(:)을 붙여 사용)

 

 

04.2 REST와 라우팅 사용하기

REST : 서버의 자원을 정의, 자원에 대한 주소를 지정하는 방법

 

/user : 사용자 정보에 관련된 자원 요청

/post : 게시글에 관련된 자원 요청

 

- HTTP 요청 메서드

GET 서버 자원을 가져오고자 할 때 사용
POST 서버에 자원을 새로 등록하고자 할 때 사용
PUT 서버의 자원을 요청에 들어 있는 자원으로 치환하고자 할 때 사용
PATCH 서버 자원의 일부만 수정하고자 할 때 사용
DELETE 서버의 자원을 삭제하고자 할 때 사용
OPTIONS 요청을 하기 전에 통신 옵션을 설명하기 위해 사용

 

HTTP통신을 사용하면 누구든 같은 방식으로 서버와 소통 가능  -->  서버와 클라이언트 분리되어 있음

 

 

04.3 쿠키와 세션 이해하기

 

쿠키 : 서버가 요청에 대한 응답을 할 때 누구인지 기억하기 위해 보내는 것

--> 로그인을 구현하기 위해 필요

 

- 로그인 구현 과정

1) 서버가 쿠키를 보냄

2) 웹 브라우저 쿠키 저장

3) 요청할 때마다 쿠키 동봉 후 보냄

4) 서버는 요청에 들어있는 쿠키로 사용자 파악

쿠키명=쿠키값 기본적인 쿠키의 값
Expires=날짜 이 기한이 지나면 쿠키가 제거
Max-age=초 해당 초가 지나면 쿠기가 제거
Domain=도메인명 쿠키가 전송될 도메인을 특정
Path=URL 쿠키가 전송될 URL을 특정
Secure HTTPS일 경우에만 쿠키가 전송
HttpOnly  설정 시 자바스크립트에서 쿠키에 접근 불가능 (쿠키 조작 방지)

 

※쿠키에는 한글과 줄바꿈이 들어가면 안됨 (한글은 encodeURIComponent로 감싸서 넣을 수 있음)

 

세션 : 서버에 사용자 정보 저장,하고클라이언트와는 세션 아이디로만 소통

세션 쿠키 : 세션을 위해 사용하는 쿠키

 

 

04..4 https와 http2

 

https 모듈

- 웹 서버에 SSL 암호화 추가

- 요청할 때 오가는 데이터를 암호화해서 다른 사람이 요청을 가로채더라도 내용 확인 불가

- 인증해줄 수 있는 기관 필요

 

http2 모듈

- SSL 암호화와 더불어 최신 HTTP 프로토콜인 http/2를 사용

- 효율적으로 요청을 보내고, 웹의 속도도 많이 개선됨

HTTP/1.1과 HTTP/2의 비교

 

04.4 cluster

- 싱글 프로세스로 동작하는 노드가 CPU 코어를 모두 사용할 수 있게 해주는 모듈

- 요청이 많이 들어왔을 때 서버의 개수만큼 요청을 분산되게 할 수 있음

 

 

5. 패키지 매니저

 

05.1 npm 알아보기

- 노드 패키지 매니저 (Node Package Manager)

- 다른 프로그래머들이 만든 코드들이 공개되어 있는 서버

 

05.2 package.json으로 패키지 관리하기

package.json : 설치한 패키지의 버전을 관리하는 파일

package-lock.json : 패캐지 간의 의존 관계를 명시한 파일

노드 프로젝트를 시작하기 전에는 폴더 내부에 무조건 package.json부터 만들고 시작해야 함

package name 패키지의 이름
version 패키지의 버전
entry point 자바스크립트 실행 파일 진입점
test command 코드를 테스트할 때 입력할 명령어를 의미
git repository 코드를 저장해둔 깃(Git) 저장소 주소를 의미
keywords 패키지를 쉽게 찾을 수 있게 함
license 해당 패키지의 라이선스를 넣음

 

 

05.3 패키지 버전 이해하기

노드 패키지들의 버전은 항상 세자리로 이뤄져 있음 (노드의 버전도 세 자리임)

 

SemVer : 버전을 구성하는 세 자리가 모두 의미를 갖고 있다는 뜻

- 버전 번호를 어떻게 정하고 올려야 하는지를 명시하는 규칙

 

메이저 버전

- 버전의 첫 번째 자리

- 메이저 버전이 0이면 초기 개발 중, 1부터는 정식 버전을 의미

- 하위 호한이 안 될 정도로 패캐지의 내용이 수정되었을 때 올림

 

마이너 버전

- 버전의 두 번째 자리

- 하위 호환이 되는 기능 업데이트를 할 때 올림

 

패치 버전

- 버전의 세 번째 자리

- 기존 기능에 문제가 있어 수정한 것을 내놓았을 때 패치 버전을 올림

 

 

05.4 기타 npm 명령어

npm update [패키지 이름] 업데이트 가능한 모든 패키지가 Wanted에 적힌 버전으로 업데이트 됨
npm uninstall [패키지 이름] 해당 패키지를 제거하는 명령어
npm search [검색어] npm의 패키지를 검색할 수 있음
npm info [패키지 이름] 패키지의 세부 정보를 파악하고자 할 때 사용하는 명령어
npm login npm 로그인을 위한 명령어
npm whoami 로그인한 사용자가 누구인지 알림
npm logout npm login으로 로그인한 계정을 로그아웃할 때 사용
npm version [버전] 명령어를 사용하면 package.json의 버전을 올림
npm deprecate [패키지 이름] [버전] [메시지] 해당 패키지를 설치할 때 경고 메시지를 띄우게 하는 명령어
npm publish 자신이 만든 패키지를 배포할 때 사용
npm unpublish 배포한 패키지를 제거할 때 사용

 

 

05.5 패키지 배포하기

1) npm 웹 사이트 우측 상단의 Sign Up을 눌러 회원가입을 함

2) 회원 가입 confirm 메일을 확인

3) 콘솔에서 npm login 명령어를 입력해 생성한 계정으로 로그인

4) 패키지로 만들 코드를 작성 (package.json의 main 부분의 파일명과 일치해야 함)

반응형