본문 바로가기
Runtime/Node.js

02. Node.js 내장 모듈과 객체

by 김엉배 2023. 1. 7.
728x90
반응형

1.  Console

   - 콘솔 모듈은 웹 브라우저에서 제공했던 자바스크립트 console과 매우 유사하고, 일반적으로 디버깅을 위해 사용한다. 

      Console 클래스와 전역 객체로 사용할 수 있다.

 

 1.1  Console 클래스

   - Console 클래스를 생성하고 stdout.log 파일과 stderr.log 파일로 로그를 기록하는 예제

      먼저 stdout.log 파일과 stderr.log 파일을 생성.

   

   - console_class.js 파일을 생성한 후 코드 작성

Node.js 를 실행하면 stdout.log 와 stderr.log 파일에 count: 5 가 기록되는 것을 확인할 수 있다.

  1.2 전역 객체 console

        - console 모듈은 전역 객체로 등록되기 때문에 require('conosle') 없이 바로 사용할 수 있다.
        - console_global.js 파일을 생성한 후 코드 작성

Node.js 실행 결과

* console.log(내용,... agrs): 일반적인 로그를 콘솔에 출력한다.

* console.error(내용, ...agrs): 에러를 콘솔에 출력한다.

* console.table(테이블형 데이터): 배열/오브젝터를 테이블 형태로 콘솔에 출력한다.

* console.time(레이블)/console.timeEnd(레이블): console.timeEnd에 전달한 인수값이 일치하는 코드 사이의 실행 시간을 측정해서

                                                                                   출력한다. 기본값은 'default'이다.

* console.dir(오브젝트, 옵션): 객체를 콘솔에 출력할 때 사용한다.

 

2 . Timers 

 - 타이머 모듈의 모든 함수는 전역 함수이기 때문에 require('timers') 없이 사용할 수 있다.

    Node.js 에서 타이머 함수는 웹 브라우저의 타이머 API와 매우 유사하다.

 

 - timer.js 파일 생성하고 코드 작성

실행 결과

* setTimeout(콜백 함수, 밀리초) : 설정한 밀리초(1초 = 1000미리초) 이후에 지정된 콜백 함수가 실행.

* setInterval(콜백 함수, 밀리초) : 설정한 밀리초마다 지정된 콜백 함수가 실행. 

* setImmediate(콜백 함수) : 현재 이벤트 루프 주기 끝에 코드를 실행.

 

3. Process

 - Process 객체는 현재 실행되고 있는 Node.js 프로세스에 대한 정보와 제어를 제공.

 

 3.1 Process events

   - 프로세스 객체는 EventEmitter 인스턴스로 다음과 같은 이벤트가 발생할 때마다 리스너로 등록할 수 있다.

  • beforeExit: Node.js가 이벤트 루프를 비우고 예약할 추가 작업이 없을 때 발생되는 이벤트.
                        beforeExit 이벤트에 등록된 리스너가 비동기식 호출을 하여 Node.js 프로세스를 계속할 수 있다.
  • exit: process.exit()를 호출하거나 Node.js 이벤트 루프가 더 이상 수행할 추가 작업이 없을 때 발생.
  • disconnect: Node.js 프로세스가 IPC채널(클러스터로 자식 프로세스를 생성했을 때)로 생성된 경우 채널이 닫힐 때 이벤트 발생.
  • message: Node.js 프로세스가 IPC 채널로 생성된 경우 childprocess.send()를 사용해서 상위 프로세스가 보낸 메시지를
                     하위 프로세스에서 수신할 때마다 발생.

 이외에도 multipleResolve, rejectHandled, uncaughtException, uncaughtExceceptionMonitor, unhandledRejection, 

 wanring 등의 이벤트가 있다.

프로새스의 각 이벤트는 process.on을 통해 리스너를 등록할 수 있다.

 

 3.2 process.nextTick

   - Node.js의 이벤트 루프는 다른 콜백 함수보다 nextTick에 인수로 전달한 콜백 함수를 우선적으로 처리한다.

      nextTick을 통해 추가한 콜백 함수는 'next tick queue'에 추가된다.

setTimeout의 콜백 함수보다 nextTick의 콜백 함수가 먼저 실행되는 것을 확인.

 

  3.3 process.exit()

   - process.exit() 함수를 호출하면 실행 중인 Node.js 프로세스를 종료한다. 만약 서버를 구동 중이라면,  process.exit() 함수를

      호출하는 순간 서버가 멈추게 된다. 그러므로 조심히 사용해야 한다.

   - 상태 코드로 0과 1을 줄 수 있는데, 인수를 주지 않거나 0을 주면 '정상 종료' 인수로 1을 주면 '비정산 종료'를 뜻함

 

 4.  OS

   - OS 모듈은 운영체제 관련 유틸리티 함수 및 속성 정보를 제공.

const os = require('os');
console.log(os.arch()); // CPU 아키텍처
console.log(os.cpus()); // 컴퓨터의 CPU 코어 정보를 배열로 리턴
console.log(os.hostname()); // 운영체제 호스트명
console.log(os.networkInterfaces()); // 네트워크 정보
console.log(os.type()); // 운영체제 타입
console.log(os.platform()); // darwin
console.log(os.release()); // 운영체제 버전
console.log(os.homedir()); // 홈 디렉터리 경로
console.log(os.tmpdir()); // 임시 파일 저장
console.log(os.totalmem()); // 전체 메모리 크기
console.log(os.freemem()); // 사용 가능한 메모리 크기

 

  5. Path

    - path 모듈은 파일과 디렉터리 경로 작업을 위한 유틸리티를 제공.

const path = require('path');
  • path.basename(path [. ext]):  경로의 마지막 부분 반환
console.log(__filename); // 현재 파일의 절대 경로
console.log(path.basename(__filename)); // 경로의 마지막 부분
console.log(path.basename(__filename, '.js')) // 경로의 마지막 부분에서 확장자를 제거한 이름
  • path.delimiter: 운영체제별로 환경 변수 구분자를 가져오는데 윈도우는 시메콜론(;), 맥과 리눅스 같은 POSIX는 콜론(:)을 사용
  • path.dirname(path): 파일이 위치한 폴더 경로를 반환한다.
  • path.extname(path): 파일의 확장자를 반환한다.
  • path.format(pathObject): dir, root, base, name, ext 프로퍼티가 있고 주어진 프로퍼티를 사용해 경로 문자열로 반환.

path.format({
  root: '/ignored', // dir 값이 있으므로 root는 무시됨
  dir: '/home/user/dir',
  base: 'file.txt'
 });
 // 'home/user/dir/file.txt'
 
 path.format({
  root: '/',
  base: 'file.txt',
  ext: 'ignoerd' // base 값이 있으므로 ext는 무시됨
 });
 // 'file.txt'
 
 path.format({
  root: '/',
  name: 'file',
  ext: '.txt'
 });
 // 'file.txt'
  • path.isAbsolute(path): 주어진 파일의 경로가 절대 경로인지 상대 경로 인지 알 수 있다.(절대 경로: true 반환)
  • path.join([... paths]) : 문자열로 주어진 경로들을 모두 합쳐서 하나의 경로로 만들어서 반환
path.join('/foo', 'bar', baz/asdf'); // '/foo/bar/baz/asdf'
  • path.parser(path) : path.format() 함수와 반대로 문자열로 된 경로를 pathObject로 반환.
path.parse('/home/user/dir/file.txt');
// { root: '/',
//   base: '/home/user/dir',
//   ext: '.txt',
//   name: 'file' }
  • path.sep: 경로 구분자를 반환(원도우: 역슬래시('\'),  POSIX 계열: 슬래시('/')) 반환

 

 6.  URL

   - url 모듈은 인터넷 주소에 해당하는 url을 다루기 위한 모듈.

   - 두 가지 API를 제공하는데 하나는 Node.js 전용 레거시 API, 다른 하나는 웹 브라우저에 사용하는 것과

     동일한 WHATWG URL 표준을 구현하는 최신 API이다.

  • WHATWG API: URL 클래스를 new 생성자를 사용해서 생성하면 WHATWG 방식을 사용해서 URL 객체를 생성
const myURL =
   new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
 console.log(myURL);
 
//URL {
//  href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash',
//  origin: 'https://sub.example.com:8080',
//  protocol: 'https:',
//  username: 'user',
//  password: 'pass',
//  host: 'sub.example.com:8080',
//  hostname: 'sub.example.com',
//  port: '8080',
//  pathname: '/p/a/t/h',
//  search: '?query=string',
//  searchParams: URLSearchParams { 'query' => 'string' },
//  hash: '#hash'
//}

- 각각의 속성은 클래스 프로토타입의 getter 및 setter로 구현되기 때문에 다음과 같이 각 속성 정보를 가져오거나 변경할 수 있다.

const myURL = new URL('https://example.org/foo#bar');
console.log(myURL.hash);
// #bar

myURL.hash = 'baz';
console.log(myURL.href);
// https://example.org/foo#baz

- url 모듈을 가장 많이 사용하게 되는 예는 주어진 url 정보에서 전달된 쿼리 데이터를 추출할 때이다.

   searchParams은 URLSearchParams 클래스로 쿼리 데이터를 조작하기 위한 다양한 내장 함수를 제공한다.

const myURL = new URL('https://example.org/?user=abc&query=xyz');
console.log(myURL.searchParams.get('user')); //키에 해당하는 첫번째 값을 반환
console.log(myURL.searchParams.has('user')); //키가 존재하는지 체크하고 있으면 true, 
                                             //없으면 false
console.log(myURL.searchParams.keys()); //Iterator로 모든 키를 반환
console.log(myURL.searchParams.values()); //Iterator로 모든 값을 반환
myURL.searchParams.append('user','admin'); //주어진 키로 값을 추가. 동일한 키가 이미 있으면 
                                           //그대로 유지하고 하나 더 추가
console.log(myURL.searchParams.getAll('user')); //키에 해당하는 값을 모두를 배열로  반환
myURL.searchParams.set('user','admin'); //주어진 키로 값을 추가. 동일한 키가 이미 있으면 모두 삭제하고
                                        //새로 추가
myURL.searchParams.delete('user'); //해당 키를 삭제
console.log(myURL.searchParams.toString()); //searchParams 객체를 문자열로 반환
  • 레거시 API: Node.js 레거시 API는 requrie() 함수로 url 호출 후 parse() 함수를 사용한다.
                       다음 예제처럼, WHATWG 방식과 Node.js 레거시 방식은 반환되는 Object의 구조가 다르다.

7.  Cypto

   - crypto 모듈은 다양한 암호화 기능을 제공함.

   - 암호화에는 단방향 암호화와 양방향 암호화가 있고, 양방향 암호화에는 비대칭형 암호화 대칭형 암호화가 있다.


const crypto = require("crypto");
crypto.createHash("sha512").update("pw1234").digest("base64"); 
// 9iSeOd1vv2qinR2UM5Aog5LmqBncF/oFeTTsPUjqwGoG3lG232280LqAScE7FR7HHe4K0gyedCN7iZDZl+NZaA==
crypto.createHash("sha512").update("pw1234").digest("hex"); 
// f6249e39dd6fbf6aa29d1d943390288392e6a819dc17fa057934ec3d48eac06a06de51b6df6dbcd0ba8049c13b151ec71dee0ad20c9e74237b8990d997e35968

   - createHash() 함수는 파라미터로 암호화에 사용할 알고리즘을 전달. update() 함수는 파라미터로 암호화할 문자열을 전달

      digest() 함수는 파라미터로 어떤 인코딩 방식으로 암호화된 문자열을 표시할지 전달한다.

* 실제로 해커는 레인보우 테이블(다양한 암호화 결과 값과 암호화 전 원본값의 테이블)을 사용하는데 시간은 좀 걸릴 수 있지만, 해킹의 

   노출을 피할 수 없다. 그래서 원본 값을 알기 어렵게 처리해야 하는데 가장 많이 사용하는 것이 salting 암호화이다.

   salting 말 그대로 소금(salt)을 뿌리는 것이다.

const createSalt = () => {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(64, (err, buf) => {
      if (err) reject(err);
      resolve(buf.toString("base64"));
    });
  })
};

 - randomBytes() 함수를 사용해서 64바이트 길이의 salt를 생성.


const createCryptoPassword = async (plainPassword) => {
  const salt = await createSalt(); // salt 생성

  return new Promise((resolve, reject) => {
    crypto.pbkdf2(plainPassword, salt, 100000, 64, "sha512", (err, key) => {
      if (err) reject(err);
      resolve({ password: key.toString("base64"), salt });
    });
  })
};

 - salt를 이용해 비밀번호를 암호화하는 함수로 pbkdf2() 함수를 사용하며, 파라미터로 암호화할 문자열인 비밀번호, salt, 반복 횟수,

    출력될 바이트 수, 해시 알고리즘을 사용. pdbdf2() 함수는 암호화된 값과 salt 값을 반환


const getCryptoPassword = (plainPassword, salt) => {
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(plainPassword, salt, 9999, 64, "sha512", (err, key) => {
      if (err) reject(err);
      resolve({ password: key.toString("base64"), salt });
    });
  })
};

- 사용자로부터 입력받은 비밀번호화 데이터베이스에 저장된 salt 값을 파라미터로 전달해서 암호화된 비밀번호 값을 가져오는 함수

 

  8.  File system

    - fs 모듈은 파일 읽기, 쓰기, 삭제 그리고 폴더 생성, 삭제 등과 같은 파일 처리와 관련된 작업을 위한 모듈.

  • fs.readFile(path, [options], callback) : 파일(path)을 옵션으로 지정한 문자 인코딩(utf-8)을 사용해 읽은 후 결과를 
                                                                     callback() 함수로 전달하는 비동기 방식 함수.
const fs = require('fs');
 
// 비동기 파일 읽기
fs.readFile('./sample/text.txt', 'utf8', (err, data) => {
    if(err) {
        throw err;
    }
    console.log(data);
});
  • fs.readFileSync(path, [options]): 파일을 옵션으로 지정한 문자 인코딩을 이용해서  utf-8 형식으로 읽은 후 결과를 반환하는
                                                            동기 방식 함수.
const fs = require('fs');

// 동기 파일 읽기
var text = fs.readFileSync('./sample/text.txt', 'utf8');
console.log(text);
  • fs.writeFile(path, data, [options], callback): 파일을 옵션방식을 사용해서 data를 쓰고 callback() 함수로 결과를 전달하는
                                                                               비동기 방식 함수.
const fs = require('fs');

let data = '파일 쓰기 테스트';

// 비동기 파일 쓰기
fs.writeFile('./sample/text_w.txt', data, 'utf8', (err) => {
     if(err) {
         throw err;
       }
     console.log('비동기적 파일 쓰기 완료');
 });
  • writeFoleSync(path, data, [options]): 파일을 옵션 방식을 사용해서 data를 쓰는 동기 방식 함수.
const fs = require('fs');
let data = '파일 쓰기 테스트';

// 동기 파일 쓰기
fs.writeFileSync('./sample/text_w2.txt', data, 'utf8');
console.log('동기적 파일 쓰기 완료');
  • fs.watchFile(filename [, options], listner) : 대상이 되는 파일의 변경 사항 여부를 감시할 수 있으며,
                                                                            변경 사항이 발생하면 지정항 콜백 리스너 함수를 실행시킬 수 있다.
let sql = require('./sql.js); // 데이터베이스 쿼리문이 작성되어 있는 파일

fs.watchFile(__dirname + '/sql.js', (curr, prev) => {
  console.log('sql 변경 시 재시작 없이 반영되도록 함.');
  delete require.cache[require.resolve('./sql.js')]; // 캐시에 저장되어 있는 파일 삭제
  sql = require('/.sql.js'); // sql.js 파일에 변경이 일어날 때마다 sql.js 재할당
 });
728x90
반응형

'Runtime > Node.js' 카테고리의 다른 글

6. Express(에러, 정적 파일)  (2) 2023.01.29
05. 라우팅 처리  (2) 2023.01.19
04. Express 웹 서버 환경설정  (0) 2023.01.17
03. json-server 이용하기  (0) 2023.01.17
01. Node.js 시작하기  (0) 2023.01.07