본문 바로가기

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

[2023 백엔드 스터디] 성정규 #1주차 - 3장, 노드 기능 알아보기

반응형

3장, 노드 기능 알아보기

3.1 REPL 사용하기

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

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

3.2 JS 파일 실행하기

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

3.3 모듈로 만들기

모듈이란 특정한 기능을 하는 함수나 변수들의 집합을 말하며, 여러 프로그램에 모듈을 재사용할 수 있다.

3.3.1 CommonJS 모듈

module.exports 에 객체나 함수, 변수 등을 대입하여 const { odd, even } = require('./var');와 같은 형태로 불러와서 사용 가능

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

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

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

3.3.2 ECMAScript 모듈

CommonJS 모듈의 require와 exports, module.exports가 각각 import, export, export default로 바뀐다.

CommonJS 모듈과 ES 모듈은 서로 간에 잘 호환되지 않는 케이스가 많으므로 웬만하면 한 가지 형식만 사용하는 것을 권장합니다.

3.3.3 다이내믹 임포트

조건부로 모듈을 불러오는 것을 다이내믹 임포트라고 한다.

3.3.4 __filename, __dirname

파일에 __filename과 __dirname을 넣어두면 실행 시 현재 파일명과 현재 파일 경로로 바뀐다.

ES모듈에서는 사용불가, 대신 import.meta.url로 경로를 가져올 수 있음

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 process

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

  1. process.env대표적으로 UV_THREADPOOL_SIZE 와 NODE_OPTIONS 가 있다.
    • NODE_OPTIONS : 노드를 실행할 때의 옵션들을 입력받는 환경 변수
    • UV_THREADPOOL_SIZE : 노드에서 기본적으로 사용하는 스레드풀의 스레드 개수를 조절할 수 있게 함.
    중요한 비밀번호는 다음과 같이 process.env의 속성으로 대체할 수도 있다.
  2. const secretId = process.env.SECRET_ID; const secretCode = process.env.SECRET_CODE;
  3. REPL에 입력해보면 매우 많은 정보가 출력되는데, 이 정보들은 시스템의 환경 변수이다.
  4. process.nextTick(콜백)
    setImmediate(() => {
      console.log('immediate');
    });
    process.nextTick(() => {
      console.log('nextTick');
    });
    setTimeout(() => {
      console.log('timeout');
    }, 0);
    Promise.resolve().then(() => console.log('promise'));
    
    $ node nextTick
    nextTick
    promise
    timeout
    immediate
    //setTimeout() 콜백 함수는 타이머에 의해 0ms 이후에 실행되지만, 
    //setImmediate()는 I/O 작업이 모두 완료된 후에 실행됩니다. 
    //때문에 setImmediate()는 setTimeout()보다 늦게 실행됩니다.
    
  5. 이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선으로 처리하도록 만든다. 즉, setImmediate나 setTimeout보다 먼저 실행된다. 또한, resolve된 Promise도 nextTick처럼 다른 콜백들보다 우선시되는데, process.nextTick과 Promise를 마이크로태스크(microtask)라고 따로 구분지어 부른다.
  6. process.exit(코드)
  7. 실행 중인 노드 프로세스를 종료한다. 서버 외의 독립적인 프로그램에서 수동으로 노드를 멈추기 위해 사용한다.

3.4.5 기타 내장 객체

  • URL, URLSearchParams: 3.5.3절에서 다룹니다.
  • AbortController, FormData, fetch, Headers, Request, Response, Event, EventTarget: 브라우저에서 사용하던 API가 노드에도 동일하게 생성되었습니다.
  • TextDecoder: Buffer를 문자열로 바꿉니다.
  • TextEncoder: 문자열을 Buffer로 바꿉니다.
  • WebAssembly: 웹어셈블리 처리를 담당합니다.

3.5 노드 내장 모듈 사용하기

3.5.1 os

  • os.arch(): process.arch와 동일합니다.
  • os.platform(): process.platform과 동일합니다.
  • os.type(): 운영체제의 종류를 보여줍니다.
  • os.uptime(): 운영체제 부팅 이후 흐른 시간(초)을 보여줍니다. process.uptime()은 노드의 실행 시간이었습니다.
  • os.hostname(): 컴퓨터의 이름을 보여줍니다.
  • os.release(): 운영체제의 버전을 보여줍니다.
  • os.homedir(): 홈 디렉터리 경로를 보여줍니다.
  • os.tmpdir(): 임시 파일 저장 경로를 보여줍니다.
  • os.cpus(): 컴퓨터의 코어 정보를 보여줍니다.
  • os.freemem(): 사용 가능한 메모리(RAM)를 보여줍니다.
  • os.totalmem(): 전체 메모리 용량을 보여줍니다.

3.5.2 path

  • path.sep: 경로의 구분자입니다. 윈도는 \, POSIX는 /입니다.
  • path.delimiter: 환경 변수의 구분자입니다. process.env.PATH를 입력하면 여러 개의 경로가 이 구분자로 구분되어 있습니다. 윈도는 세미콜론(;)이고, POSIX는 콜론(:)입니다.
  • path.dirname(경로): 파일이 위치한 폴더 경로를 보여줍니다.
  • path.extname(경로): 파일의 확장자를 보여줍니다.
  • path.basename(경로, 확장자): 파일의 이름(확장자 포함)을 표시합니다. 파일의 이름만 표시하고 싶다면 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()과 비슷하지만 차이가 있습니다.
path.join('/a', '/b', 'c'); /* 결과: /a/b/c/ */
path.resolve('/a', '/b', 'c'); /* 결과: /b/c */

3.5.3 url

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

  • WHATWG
    • url 모듈 안에 URL 생성자가 있어 이 생성자에 주소를 넣어 객체로 만들면 주소가 부분별로 정리됨.
    • username, password, origin, searchParams 속성이 존재
  • search 부분(쿼리스트링)은 보통 주소를 통해 데이터를 전달할 때 사용

http://www.gilbut.co.kr/?page=3&limit=10&category=nodejs&category=javascript

에서 ?page=3&limit=10&category=nodejs&category=javascript 부분이 search이다.

search 부분을 다루기 위해 searchParams하는 특수한 객체 생성

  • searchParams
    • getAll(키): 키에 해당하는 모든 값을 가져옵니다. category 키에는 nodejs와 javascript라는 두 가지 값이 들어 있습니다.
    • get(키): 키에 해당하는 첫 번째 값만 가져옵니다.
    • has(키): 해당 키가 있는지 없는지를 검사합니다.
    • keys(): searchParams의 모든 키를 반복기(iterator)(ES2015 문법) 객체로 가져옵니다.
    • values(): searchParams의 모든 값을 반복기 객체로 가져옵니다.
    • append(키, 값): 해당 키를 추가합니다. 같은 키의 값이 있다면 유지하고 하나 더 추가합니다.
    • set(키, 값): append와 비슷하지만 같은 키의 값들을 모두 지우고 새로 추가합니다.
    • delete(키): 해당 키를 제거합니다.
    • toString(): 조작한 searchParams 객체를 다시 문자열로 만듭니다. 이 문자열을 search에 대입하면 주소 객체에 반영됩니다.

3.5.4 dns

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

ip 주소는 간단하게 dns.lookup이나 dns.resolve(도메인)으로 얻을 수 있다.

A(ipv4 주소), AAAA(ipv6 주소), NS(네임서버), SOA(도메인 정보), CNAME(별칭, 주로 www가 붙은 주소는 별칭인 경우가 많습니다), MX(메일 서버) 등은 레코드라고 부르는데, 해당 레코드에 대한 정보는 dns.resolve(도메인, 레코드 이름)으로 조회하면 된다.

3.5.5 crypto

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

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