Node.js 2일차 TIL

김민지·2023년 10월 10일
0

Node.js

목록 보기
2/8

섹션 2. 노드 기본 기능 익히기 - 2

1. exports, this, require, 순환참조

(1) module, exports

  • 하나의 모듈만 exports 할 경우
module.exports = checkOddOrEven;
  • 여러 개의 모듈 exports 경우
module.exports = {
	odd,
    even,
}

또는

exports.odd = odd;
exports.even = even;

둘 중 하나 선택 단, exports를 쓸 경우 module.exports는 사용할 수 없다.
-> 같이 쓸 수 없다.

(2) This

  • this는 전역 객체
  • 최상위 스코프의 this는 module.exports를 가리킨다.

(3) require

  • require가 제일 위에 올 필요는 없다.
  • require.chche에 한번 require한 모듈에 대한 캐싱 정보가 들어있다.
  • require.main은 노드 실행 시 첫 모듈을 가리킨다.

(4) 순환참조

두 개의 모듈이 서로를 require하는 상황을 조심해야 함


2. ECMAScript 모듈, 다이나믹 임포트, top level await

ECMAScript 모듈(ES 모듈)은 공식적인 자바스크립트 모듈 형식이다.
브라우저와 노드 모두에 같은 형식을 사용할 수 있다는 것이 장점

  • .mjs 확장자 사용
const a = true;
if (a) {
	const m1 = await import('./func.mjs');
    console.log(m1);
    const m2 = await import('./var.mjs');
    console.log(m2)
}
  • import라는 함수를 사용해서 모듈을 동적으로 불러올 수 있다.

  • import는 Promise를 반환하기에 await이나 then을 붙여야 한다.

  • ES 모듈의 최상위 스코프에선 async 함수 없이도 await 할 수 있다.

  • export default의 경우 import할 때도 default라는 속성 이름으로 임포트된다.

  • export default와 module export는 다른 것이다.


3. global, console, 타이머

(1) global

  • 노드의 전역 객체
  • 모든 파일에서 접근 가능

(2) console

브라우저의 console 객체와 매우 유사

console.log: 평범한 로그
console.error: 에러 로깅
console.trace: 호출스택 로깅

(3) 타이머

set 메서드에 clear 메서드가 대응됨
즉, set 메서드의 리턴 값(아이디)을 clear 메서드에 넣어 취소

setTimeout(콜백 함수, 밀리초): 주어진 밀리초 이후에 콜백 함수 실행
setInterval(콜백 함수, 밀리초): 주어진 밀리초마다 콜백 함수를 반복 실행
setImmediate(콜백 함수): 콜백 함수를 즉시 실행

setTimeout(아이디)
setInterval(아이디)
setImmediate(아이디)
➡️ 전부 취소할 수 있음


4. process

현재 실행 중인 노드 프로세스에 대한 정보를 담고 있다.

process.cwd()
//노드 명령어를 어디서 실행했는지, 현재프로세스가 실행되는 위치

(1) process.env

시스템 환경 변수들이 들어있는 객체

  • 비밀키(DB 비밀번호 등)을 보관하는 용도로도 쓰임
  • 환경 변수는 process.env로 접근 가능
const secretId = process.env.SECRET_ID;

(2) process.nextTick

이벤트 루프가 다른 콜백 함수들보다 netxTick의 콜백 함수를 우선적으로 처리함
➡️ 새치기

단, 너무 남용하면 다른 콜백 함수들 실행이 늦어진다.
비슷한 경우로 promise가 있는데 nextTick처럼 우선순위가 높아 가능하다

(3) process.exit

현재의 프로세스를 멈춤

  • 코드가 없거나 0이면 정상 종료
  • 이외의 코드는 비정상 종료를 의미

5. os와 path

(1) OS

운영체제의 정보를 담고 있음
모듈은 require로 가져옴 (내장 모듈이라 경로 대신 이름만 적어줘도 됨)

(2) path

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

운영체제별로 경로 구분자가 다르다. (Windows: '\', POSIX: '/')

const path = require('path');

path는 경로 처리를 알아서 해주기 때문에 중요함!

(3) 알아둬야할 path 관련 정보

  • join과 resolve의 차이
    resolve는 /를 절대경로로 처리,
    join은 상대경로로 처리

상대 경로: 현재 파일 기준. 같은 경로면 점 하나(.), 한 단계 상위 경로면 점 두 개(..)
절대 경로는 루프 폴더나 노드 프로세스가 실행되는 위치가 기준이다.

  • \와 \차이
    \: 윈도 경로 구분자
    \: 자바스크립트 문자열 안에서 사용

  • 윈도에서 POSIX path를 쓰고 싶다면 path.posix 객체 사용
    반대로 POSIX에서 윈도 path를 쓰고 싶다면 path.win32 사용


6. url, dns, searchParams

(1) url

과거의 방식과 WHATWG 방식이 있는데 최근에는 후자의 방식만 사용한다.

const url = require(.'url');

const { URL } = url;
const myURL = new URL('~');
console.log('new URL():', myURL );
console.log('url.format():', url.format(myURL));

url은 노드 내장 객체이기도 해서 require 할 필요는 없다.
이 생성자에 주소를 넣어 객체로 만들면 주소가 부분별로 정리된다.
➡️ 이 방식이 WHATWG의 url


(2) searchParams

WHATWG방식에서 쿼리스트링(search)부분 처리를 도와주는 객체
과거엔 쿼리스트링을 사용했는데 최근엔 searchParams 사용
➡️ 쿼리스트링 객체를 발견하면 searchParams를 사용하도록 하자.

(3) dns

DNS를 다룰 때 사용하는 모듈이다.
주로 도메인을 통해 IP나 기타 DNS 정보를 얻고자 할 때 사용된다.

lookup을 하면 IP주소로 접근한다.


7. crypto와 util

(1) crypto 단방향 암호화

  • 암호화는 가능하지만 복호화는 불가능하다
    암호화: 평문 -> 암호문
    복호화: 암호문 -> 평문

  • 단방향 암호화의 대표 주자는 해시 기법
    해시 기법: 문자열을 고정된 길이의 다른 문자열로 바꾸는 방식
    대표적인 해시의 예시는 비밀번호이다.

(2) Hash 사용하기(sha512)

  • createHash(알고리즘): 사용할 해시 알고리즘을 넣어준다.
  • updateHash(문자열): 변환할 문자열을 넣어준다.
  • digest(인코딩): 인코딩할 알골즘을 넣어준다.

(3) 양방향 암호화

대칭형 암호화 (암호문 복호화 가능)

  • key가 사용된다.
  • 암호화 할 때와 복호화 할 때 같은 key를 사용해야 한다.
const cipher = crypto.create(ipheriv(algorithm, key, iv);

➡️ 키 관리를 잘 하지 않으면 해킹 위험이 높다. 따라서 프론트와 서버 관계에서는 사용 불가

(4) util

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

  • deprecated와 promisfy가 자주 쓰임

deprecated란?
중요도가 떨어져 더 이상 사용되지 않고 앞으로는 사라지게 될 것이라는 뜻
새로운 기능이 나와서 기존 기능보다 더 좋을 때, 기존 기능을 deprecated 처리한다.
기능을 제거하진 않지만 곧 없앨 예정이므로 더 이상 사용하지 말라는 의미이다.

uitl.deprecated: 함수가 deprecated 처리되었음을 알려준다.

  • 첫 번째 인자로 넣은 함수를 사용했을 때 경고 메세지가 출력된다.
  • 두 번째 인자로 경고 메시지 내용을 넣으면 된다. 함수가 조만간 사라지거나 변경될 때 알려줄 수 있어 유용하다.

util.promisify: 콜백 패턴을 프로미스 패턴으로 바꿔준다.

  • 바꿀 함수를 인자로 제공하면 된다.
  • async/await 패턴가지 사용할 수 있다. 단, 콜백이 (error, data) => {} 형식

8. worker_threads

(1) worker_threads

노드에서 멀티 스레드 방식으로 작업할 수 있다.
➡️ 노드에서 멀티 스레드 방식을 지원하는 것이지 메인이 되면 안된다.

(2) new_Worker

new_Worker를 호출하는 수 만큼 워커스레드가 생성된다.


9. child_process

child_process는 노드말고 다른 프로그램 하나를 더 실행하는 것을 의미한다.
예를 들어 파이썬 실행, 엑셀 실행 등


10. 파일 시스템 사용하기

(1) fs

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

  • 파일/폴더 생성, 삭제, 읽기, 쓰기 가능
  • 웹브라우저에서는 제한적이었으나 노드는 권한을 가지고 있다.

➡️ 보안을 조심 (악성 파일을 읽을수도)

(2) fs 프로미스

콜백 방식 대신 프로미스 방식으로 사용 가능

require('fs').promises

사용하기 더 편함

(3) 동기 메서드와 비동기 메서드

동기와 비동기: 백그라운드 작업 완료 확인 여부
블로킹과 논 블로킹: 함수가 바로 return 되는지 여부
➡️ 노드에서는 대부분 동기-블로킹 방식과 비동기-논 블로킹 방식

서버 시작 후에는 동기를 웬만하면 사용하지 않는 것이 좋다.


11. 버퍼와 스트림 이해하기

(1) 버퍼와 스트림 이해하기

버퍼: 일정한 크기로 모아두는 데이터

  • 일정한 크기가 되면 한 번에 처리
  • 버퍼링: 버퍼에 데이터가 찰 때까지 모으는 작업

스트림: 데이터의 흐름

  • 일정한 크기로 나눠서 여러 번에 걸쳐서 처리
  • 버퍼(또는 청크)의 크기를 작게 만들어서 주기적으로 데이터를 전달
  • 스트리밍: 일정한 크기의 데이터를 지속적으로 전달하는 작업

(2) 버퍼와 스트림 비교

예를 들어 100 메가 바이트의 파일이 있다고 하자.
버퍼는 100메가가 다 찰 때까지 기다렸다가 클라이언트에게로 전송한다.
스트림은 1메가로 설정하면 1메가씩 클라이언트에게 계속 전송한다. (총 100번)

➡️ 스트림이 더 효율적, 서버의 메모리면에서도 효율적이다.

노드에서는 Buffer 객체를 사용한다.

(3) fs.createReadStream

파일 읽는 스트림

  • createReadStream에 인자로 파일 경로와 옵션 객체를 전달한다.
  • highWaterMark: 버퍼의 크기
  • data: 전달 / end: 전달 완료 / error: 에러 발생

(4) fs.createWriteStream

  • createReadStream에 인자로 파일 경로 전달
  • write: 입력 / end: 종료

12. pipe와 스트림 메모리 효율 확인하기

(1) 스트림 사이에 pipe 사용하기

pipe로 여러 개의 스트림을 연결할 수 있다.

readStream.pipe(writeStream);

(2) 여러 개의 스트림 연결

readStream.pipe(zlibStream).pipe(writeStream);

(3) 큰 파일 만들기

const file = fs.createWriteStream('./big.txt')

(4) 메모리 체크하기

console.log('before: ', process.memoryUsage().rss);

13. 스레드풀과 커스텀 이벤트

(1) 스레드풀

fs, crypto, zlib 모듈의 메서드를 실행할 때는 백그라운드에서 동시에 실행
스레드풀이 동시에 처리한다.

(2) UV_THREAD_SIZE

스레드풀을 직접 컨트롤 할 수는 없지만 개수 조절은 가능하다.

  • 윈도우: SET UV_THREADPOOL_SIZE=개수
  • 맥: UV_THREADPOOL_SIZE=개수

14. 에러 처리

(1) 예외 처리

예외: 처리하지 못한 에러

  • 노드 프로세스 / 스레드를 멈춤
  • 노드는 기본적으로 싱글 스레드, 스레드가 멈춘다는 것은 프로세스가 멈춘다는 것
  • 에러 처리는 필수

(2) try catch

기본적인 예외 처리 방식

  • 에러가 발생할 만한 곳을 try catch로 감싼다.

(3) 노드 비동기 메서드의 에러

노드 비동기 메서드의 에러는 따로 처리하지 않아도 된다.
왜냐하면 콜백 함수에서 에러 객체를 제공하기 때문.

(4) 프로미스의 에러

프로미스의 에러는 따로 처리하지 않아도 된다.
왜냐하면, 버전이 올라가면 동작이 바뀔 수 있기 때문

(5) 예측 불가능한 에러 처리

  • 콜백 함수의 동작이 보장되지 x
  • 따라서 복구 작업용으로 쓰는 것은 부적합하다
  • 에러 내용 기록 용으로만 쓰는게 좋다.

➡️ 최후의 수단

profile
안녕하세요

0개의 댓글