Node.js 교과서 개정 2판 3장 요약

Nari.·2020년 12월 9일
0

Node.js

목록 보기
3/10
post-thumbnail

3장. 노드 기능

3.1 REPL 사용하기

REPL(Read Eval Print Loop) :: 입력한 코드를 읽고(Read), 해석하고(Eval), 결과물을 반환하고(Print), 종료할 때까지 반복한다(Loop) 는 의미

한두 줄짜리 코드를 테스트하는 용도로는 적합하지만 긴 코드의 경우 자바스크립트 파일로 만든 후 파일을 통째로 실행해보는 것이 좋다.



3.2 JS 파일 실행하기

콘솔에서 node [자바스크립트 파일경로] 로 실행한다. 확장자(.js) 는 생략해도 된다.



3.3 모듈로 만들기

모듈이란 ? 특정한 기능을 하는 함수나 변수들의 집합
보통 파일 하나가 모듈 하나가 된다. 모듈로 만들어두면 여러 프로그램에 해당 모듈을 재사용할 수 있다. 파일별로 코드를 모듈화할 수 있어서 관리하기가 편하다.



3.4 노드 내장 객체 알아보기

3.4.1 global

브라우저의 window와 같은 전역 객체. 모든 파일에서 접근 가능하다.
생략해서 사용가능한데, 대표적인 예로 노드 콘솔에 로그를 기록하는 console 객체도 원래는 global.console 이다.

** 노드에는 DOM, BOM이 없어서 window, document객체는 사용할 수 없다.

3.4.2 console

보통 console 객체는 디버깅을 위해 사용하며, 노드에서는 console 이 global 객체 안에 들어있으며, 브라우저에서의 console과 거의 비슷하다. 다른 로깅함수들을 다뤄보려한다.

console.time(레이블) : console.timeEnd(레이블)과 대응되어 같은 레이블을 가진 time과 timeEnd 사이의 시간을 측정

console.log(내용) : 평범한 로그를 콘솔에 표시합니다. Console.log(내용, 내용, …) 처럼 여러 내용을 동시에 표시

console.error(에러내용) : 에러를 콘솔에 표시

console.table(배열) : 배열의 요소로 객체 리터럴을 넣으면 객체의 속성들이 테이블 형식으로 표현된다.

console.dir(객체, 옵션) : 객체를 콘솔에 표시할 때 사용

console.trace(레이블) : 에러가 어디서 발생했는지 추적할 수 있음


3.4.3 타이머

타이머 기능을 제공하는 함수
setTimeout(콜백 함수, 밀리초) : 주어진 밀리초(1,000분의 1초)이후에 콜백 함수를 실행
setInterval(콜백 함수, 밀리초) : 주어진 밀리초마다 콜백 함수를 반복 실행
setImmediate(콜백 함수) : 콜백 함수를 즉시 실행

아이디를 사용하여 타이머를 취소할 수 있음
clearTimeout(아이디) : setTimeout 을 취소
clearInterval(아이디) : setInterval 을 취소
clearImmediate(아이디) : setImmediate 를 취소

3.4.4 filename, dirname

노드에서는 파일 사이에 모듈 관계가 있는 경우가 많아서 때로는 현재 파일의 경로나 파일명을 알아야한다. 노드는 __filename, __dirname 이라는 키워드로 경로에 대한 정보를 제공한다.

3.4.5 module, exports, require

module 객체 말고 exports 객체로도 모듈을 만들 수 있다. 두개가 동일하게 동작하는 이유는 module.exports 와 exports 가 같은 객체를 참조하기 때문이다. 다시말해서 exports와 module.exports에는 참조 관계가 있으므로 한 모듈에 이 두가지를 동시에 사용하는 것는 좋지않다.

노드에서 this를 사용할 때는 주의할 점이 있다. 최상위 스코프에 존재하는 this는 module.exports(또는 exports 객체)를 가리킨다. 하지만, 함수 선언문 내부의 this는 global 객체를 가리킨다.

  • 순환 참조(circular dependency)
    순환 참조가 있을 경우 순환 참조되는 대상을 빈 객체로 만든다. 이 때 에러가 발생하지 않고 빈 객체로 변경되어서 예기치 못한 동작이 발생할 수 있다. 그래서 순환 참조가 발생하지 않도록 구조를 잘 잡는 것이 중요하다.

3.4.6 process

process 객체는 현재 실행되고 있는 노드 프로세스에 대한 정보를 담고있다.

  1. process.env
    REPL에 입력해보면 매우 많은 정보가 출력되는데, 이 정보들은 시스템의 환경 변수이다.
    대표적으로 UV_THREADPOOL_SIZE 와 NODE_OPTIONS 가 있다.
    NODE_OPTIONS :: 노드를 실행할 때의 옵션들을 입력받는 환경 변수
    UV_THREADPOOL_SIZE :: 노드에서 기본적으로 사용하는 스레드풀의 스레드 개수를 조절할 수 있게 함.
  1. process.nextTick(콜백)
    이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선으로 처리하도록 만든다. 즉, setImmediate나 setTimeout보다 먼저 실행된다. 또한, resolve된 Promise도 nextTick처럼 다른 콜백들보다 우선시되는데, process.nextTick과 Promise를 마이크로태스크(microtask)라고 따로 구분지어 부른다.
  1. process.exit(코드)
    실행 중인 노드 프로세스를 종료한다. 서버 외의 독립적인 프로그램에서 수동으로 노드를 멈추기 위해 사용한다.





3.5 노드 내장 모듈 사용하기

3.5.1 os

os모듈에는 운영체제의 정보가 담겨있어서 가져올 수 있으며 process객체와 겹치는 부분도 조금 있다.

3.5.2 path

폴더와 파일의 경로를 쉽게 조작하도록 도와주는 모듈.
path 모듈이 필요한 이유 중 하나는 운영체제별로 경로 구분자가 다르기 때문이다. 크게는 윈도 타입과 POSIX타입으로 구분된다. POSIX는 유닉스 기반의 운영체제들을 의미하며 맥과 리눅스가 속해 있다.

  1. 윈도: C:\Users\nari
    -> \ (백슬레시)로 구분한다.
  1. POSIX: /home/nari
    -> /(슬레시)로 구분한다.

3.5.3 url

인터넷 주소를 쉽게 조작하도록 도와주는 모듈.
노드 버전7에서 추가된 WHATWG(웹 표준을 정하는 단체의 이름)방식의 url과 예전부터 노드에서 사용하던 방식의 url 두 가지 방법이 있다.

  • WHATWG :: url 모듈 안에 URL 생성자가 있어서 이 생성자에 주소를 넣고 객체로 만들면 주소가 부분별로 정리가 된다. username, password, origin, searchParams 속성은 WHATWG에만 존재한다.
  • 기존 노드 방식에서는 메서드를 주로 사용한다.
    - url.parse(주소) :: 주소를 분해한다. WHATWG 방식과 비교해보면 username, password 대신에 auth 속성, searchParams 대신에 query가 있다.
    - url.format(객체) :: WHATWG 방식 url과 기존 노드의 url을 모두 사용할 수 있다. 분해되었던 url객체를 다시 원래 상태로 조립한다.

3.5.4 querystring

WHATWG 방식의 url 대신 기존 노드의 url을 사용할 때, search 부분을 사용하기 쉽게 객체로 만드는 모듈.

  • querystring.parse(쿼리) : url의 query 부분을 자바스크립트 객체로 분해
  • querystring.stringify(객체) : 분해된 query 객체를 문자열로 다시 조립

3.5.5 crypto

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

  1. 단방향 암호화
    비밀번호는 보통 단방향 암호화 알고리즘을 사용해서 암호화한다.
    단방향 암호화란? 복호화할 수 없는 암호화 방식. 즉, 한 번 암호화하면 원래 문자열을 찾을 수 없어서 암호화라고 표현하는 대신 해시 함수라고 부르기도 한다.
  1. 양방향 암호화
    양방향 대칭형 암호화는 암호화된 문자열을 복호화할 수 있으며, 키가 사용된다. 그래서 복호화하려면 암호화할 때 사용한 키와 같은 키를 사용해야한다.

3.5.6 util

이름처럼 각종 편의 기능을 모아둔 모듈.
계속해서 API가 추가되고 있지만, 가끔 deprecated되어 사라지는 경우도 있다.

자주 사용하는 메서드 2개를 소개해보자면,

  • util.deprecate: 함수가 deprecated 처리되었음을 알려준다. 즉, 함수가 조만간 사라지거나 변경될때 알려줄 수 있음.
  • util.promisify : 콜백 패턴을 프로미스 패턴으로 바꿔준다.

3.5.7 worker_threads

노드에서 멀티 스레드 방식으로 작업하는 방법은 worker_threads 모듈로 가능하다.
멀티 스레딩을 할 때는 일을 나눠서 처리하도록 하는 게 제일 어렵다. 스레드를 생성하고 스레드 사이에서 통신하는 데 상당한 비용이 발생하므로, 이 점을 고려해서 멀티 스레딩을 해야한다.


3.5.8 child_process

노드에서 다른 프로그램을 실행하고 싶거나 명령어를 수행하고 싶을 때 사용하는 모듈.
이 모듈을 통해 다른 언어의 코드를 실행하고 결괏값을 받을 수 있다.




3.6 파일 시스템 접근하기

fs 모듈은 파일 시스템에 접근하는 모듈이다. 즉, 파일을 생성하거나 삭제하고, 읽거나 쓸 수 있으며 폴더도 만들거나 지울 수 있다.


3.6.1 동기 메서드와 비동기 메서드

노드는 대부분의 메서드를 비동기 방식으로 처리한다. 하지만 몇몇 메서드는 동기 방식으로 사용할 수 있는데, fs 모듈이 그런 메서드를 많이 갖고 있다.


3.6.2 버퍼와 스트림 이해하기

파일을 읽거나 쓰는 방식에는 크게 두 가지 방식, 즉 버퍼를 이용하는 방식과 스트림을 이용하는 방식이 있다.

영상을 시청할 때, 영상을 로딩하는 시간을 버퍼링한다라고 말하고, 영상을 실시간으로 송출할 때는 스트리밍한다고 말한다. 즉, 버퍼링은 영상을 재생할 수 있을 때까지 데이터를 모으는 동작이며, 스트리밍은 영상 데이터를 조금씩 전송하는 동작이다.

노드의 버퍼와 스트림도 비슷한 개념이다. 노드는 파일을 읽을 때 메모리에 파일 크기만큼 공간을 마련해두며 파일 데이터를 메모리에 저장한 뒤 사용자가 조작할 수 있도록 한다. 이 때 메모리에 저장된 데이터가 바로 버퍼이다.


3.6.3 기타 fs 메서드 알아보기

  • fs.access(경로, 옵션, 콜백) :: 폴더나 파일에 접근할 수 있는지 확인한다.
  • fs.mkdir(경로, 콜백) :: 폴더를 만드는 메서드. 이미 존재하는 폴더라면 에러가 발생하므로 access 메서드를 호출해서 확인하는 것이 좋다.
  • fs.open(경로, 옵션, 콜백) :: 파일의 아이디(fd 변수)를 가져오는 메서드
    만약 파일이 없다면 파일을 생성한 뒤 그 아이디를 가져온다.
  • fs.rename(기존 경로, 새 경로, 콜백) :: 파일의 이름을 바꾸는 메서드.
    꼭 같은 폴더를 지정할 필요는 없으므로 잘라내기 같은 기능을 할 수도 있다.
  • fs.readdir(경로, 콜백) : 폴더 안의 내용물을 확인할 수 있다.
  • fs.unlink(경로, 콜백) : 파일을 지울 수 있다.
  • fs.rmdir(경로, 콜백) : 폴더를 지울 수 있다.

3.6.4 스레드풀 알아보기

비도익 메서드를 여러 번 실행해도 백그라운드에서 동시에 처리되는데, 이 이유가 스레드풀이 존재하기 때문이다. 스레드풀이 작업을 동시에 처리하게되면 어느 것이 먼저 처리될지 몰라서 실행할 때마다 시간과 순서가 달란진다. 스레드풀을 직접 컨트롤할 수는 없지만 개수는 조절 할 수 있다.




3.7 이벤트 이해하기

events 모듈을 사용하여 객체를 만들어서 사용한다. 이벤트 객체는 이벤트 관리를 위한 메서드를 갖고 있다.




3.8 예외 처리하다

노드에서는 예외 처리가 정말 중요하다. 예외란 보통 처리하지 못한 에러를 가리키는데, 이러한 예외들이 실행 중인 노드 프로세스를 멈추게 만들기 때문이다.

  • 에러가 발생할 것 같은 부분을 try / catch 문으로 감싼다.
  • 에러가 발생했을 때 에어를 throw 한다. (반드시 try / catch 문으로 throw 한 에러를 잡아야한다.)
  • 프로미스의 에러는 catch하지 않아도 알아서 처리된다.
  • process 객체에 uncaughtException 이벤트 리스너를 단다.

0개의 댓글