본문 바로가기

개발 공부/nodejs

[섹션 2-2] 노드 내장 객체, 내장 모듈, 파일 시스템 알아보기

 

내장 객체

 

global: 브라우저의 window같은 역할. window와 같이 모든 파일에서 접근이 가능해진다. 그리고 생략도 가능하다.

 

setimmediate: setTimeout(callback, 0)하고 비슷한데 실행 순서에 차이가 있다고 하니 setImmediate를 사용하자.

 

process.env: 시스템 환경 변수들이 들어있는 객체. 주로 코드에 노출되면 안되는 비밀키(db 비밀번호, 서드파티 앱 키 등)을 보관하는 용도로 쓰인다. 찾아보니 express로 가면 dotenv를 사용해서 process.env에 접근한다고 나와있다.

 

process.nextTick: 이벤트루프를 공부할 때 비동기함수 간에도 서열이 있다는 것을 알게 되었다. process.nextTick도 서열이 강한 놈중 하난데 promise같이 다른 비동기함수보다 빨리 빠져나온다.

 

 

 

내장 모듈

os: 운영체제의 정보를 담고 있다. 예를 들어 000 버전 이하에서는 안되는 앱이라고 한다면 이런 체크가 중요할 듯 하다. ios인지 android인지 체크하는 것도 중요해보인다.

 

path: 경로처리할 때 대부분 이 모듈을 사용하게 된다. / \ \\ 같이 구분자들이 여러가지 형태로 쓰이는데 이걸 구분하는 것이 빡치기 때문이다.

 

path.join(__dirname, 'var.js');

 

위와같이 쓰면 알아서 합쳐준다고 한다.

 

url: 요즘은 WHATWG 방식을 쓴다.  searchParams는 쿼리스트링 부분 처리를 도와주는 모듈이다. 리액트의 useSearchParams의 기능과 거의 흡사하다.

 

단방향 암호화(crypto): 암호화는 가능하지만 복호화는 불가능한 기술. 주로 Hash 방법을 사용한다.

 

'티스토리' 라는 걸 Hash화를 시키면 변한 값은 항상 똑같은 값이 나온다. 그래서 비밀번호 같은 것들을 서버에서는 변화한 값을 가지고 있고 내가 비밀번호를 입력했을 때 Hash화를 다시 해서 똑같으면 로그인이 되는 그런 기능을 쓴다.

 

Hash 알고리즘에는 sha1, sha256, sha512 같은 것들이 있다. firebase 연동할 때 한번씩 보던 녀석들인데 이런 의미였던 거구만. 또 pbkdf2, bcrypt같은 알고리즘도 있다. 

 

util: 각종 편의 기능을 모아둔 모듈이라고 한다. util.deprecate, util.promisify가 주로 쓰이는데 deprecate는 라이브러리에서 이제 더이상 쓰지 않으니까 바꾸라고 할 때 많이 쓰고 promisify는 콜백 패턴을 프로미스 패턴으로 바꿀 때 많이 쓴다.

 

worker_threads: 노드에서 멀티 스레드 방식으로 작업을 할 수 있게 지원해주는 모듈. 강의를 듣다보니 예전에 자바를 배울 때가 생각난다. 그때도 메인 스레드에 실행되고 있는 코드 있는지 보고 코드 나누고 별 걸 다 했는데 역시 어렵다. 아직은 싱글 스레드에 집중해야할 때인 것 같다.

 

child_process: 노드에서  다른 프로그램을 실행하고 싶을 때 사용한다.

 

 

 

파일 시스템

fs: 파일 시스템에 접근하는 모듈. 웹에서는 파일 시스템에 접근하는 것이 제한적이었는데 노드는 할 수 있다. 그래서 악성 노드를 실행하는 것을 주의해야한다. 내 파일이 어딘가로 팔려나갈 수도 있기 때문에.

 

fs는 원래 콜백 형태였는데 프로미스 방식도 나왔다. then을 붙여서 할 수도 있고 await를 사용해도 된다.

 

fs도 그렇고 노드는 대부분 내장 모듈 매서드를 비동기로 처리한다. 동시에 돌릴 수 있으니까 여러 이점이 많다. 그런데 순서가 중요한 경우에는 동기적으로 돌아가야하는 경우가 생길 수도 있다.

 

fs는 동기 매서드도 지원하지만 말 그대로 동기이기 때문에 여러번 실행시에 뒤에 코드가 대기 상태에 빠진다는 단점이 있다. 그래서 콜백 함수 안에 다른 fs를 실행하는 등등으로 사용하기도 하고 then을 계속 이어붙여서 사용하기도 한다. 그래도 역시 최고로 심플하게 await를 쓰는 것이 좋긴 하다.

 

 

버퍼: 일정한 크기로 모아두는 데이터, 버퍼링은 버퍼가 일정 크기만큼 찰 때까지 기다리다가 생기는 것.

 

스트림: 작은 크기의 청크를 만들어서 주기적으로 데이터를 전달해준다. 스트리밍이 이 스트림 작업을 의미한다.

버퍼 방식과 스트림 방식은 단순 텍스트정도를 보내는데는 큰 차이가 없을 수 있다. 청크 크기가 훨씬 크니까. 하지만 요즘은 이미지, 특히 동영상 서비스가 많아짐에 따라서 버퍼방식은 안좋은 게 아니라 사용할 수 없는 단계가 되기도 했다. 100gb 동영상을 한번에 넘겨줄 수 있는 서버가 어디 있겠는가ㅋㅋ

 

pipe: 여러개의 스트림을 이을 수 있는 방법

const fs = require('fs');

const readStream = fs.createReadStream('readme4.txt');
const writeStream = fs.createWriteStream('write.txt');
readStream.pipe(writeStream);

//readStream에서 pipe를 꽂아서 writeStream에 연결해준 느낌이다.

 

스레드풀: fs, crypto, zlib 등은 백그라운드에서 동시에 돌아가는데 스레드풀이 동시에 처리해주는 것이다. 그런데 무한대로 처리해줄 수는 없고 동시에 4개까지 돌릴 수 있다. 그런데 요즘은 32코어 64코어도 나오는 마당에 4개면 조금 짜다 싶은 느낌이 있을 것이다. 그럴 때는 process.env에 아래와 같은 문자를 추가하면 된다.

 

UV_THREADPOOL_SIZE=32 // 윈도우라면 앞에 SET 붙이고 한칸 띄기

 

 

 

예외 처리하기

노드는 기본적으로 싱글 스레드라서 에러가 나고 그 에러를 처리해주지 못하면 프로세스 전체가 멈춘다. 그래서 에러 처리를 꼭 해줘야 한다. 

 

try catch: 프론트에서 api 연동할 때 무수히 많이 쓴 구문이다. await를 주로 쓰다보니까 then catch 처럼 이어 붙일 수 있는 에러 처리 기법이 없어서 주로 쓴다.

 

신기하게도 노드에서는 프로미스의 에러를 따로 처리하지 않아도 된다고 한다. 단, 에러 메시지가 조금 길고 지저분하게 나온다. 그런데 버전이 바뀌면서 이것도 오류가 날 수도 있다. 그래서 프로미스는 그냥 에러처리를 해주는 것을 원칙으로 하자.

 

 

 

'개발 공부 > nodejs' 카테고리의 다른 글

[섹션 4] npm  (0) 2024.03.10
[섹션3-3] https, http2, Cluster  (0) 2024.03.10
[섹션3-2] 쿠키와 세션  (0) 2024.03.10
[섹션 3] http 서버  (0) 2024.03.10
[섹션 2-1] 노드 기본 기능 살피기  (0) 2024.02.22