안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[Node.js 교과서]의 책을 참고하여 포스팅한 개인 공부 내용입니다.
노드 기능 알아보기
노드 내장 객체 알아보기
노드에서는 기본적인 내장 객체와 내장 모듈을 제공하며, 따로 설치하지 않아도 바로 사용할 수 있습니다. (브라우저의 window 객체와 비슷)
global
- 전역 객체 (모든 파일에서 접근 가능)
- 메소드 호출 시 global 생략 가능 (global.require → require 로 사용)
- window와 document 객체를 노드에서 사용할 수 없어 이를 아우르는 globalThis 객체가 생성됨
브라우저 환경에선 globalThis → window, 노드에선 globalThis → global
@콘솔출력값
> global
<ref *1> Object [global] {
global: [Circular *1],
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
structuredClone: [Function: structuredClone],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
atob: [Function: atob],
btoa: [Function: btoa],
performance: Performance {
nodeTiming: PerformanceNodeTiming {
name: 'node',
entryType: 'node',
startTime: 0,
duration: 3558.353833999485,
nodeStart: 1.6185420006513596,
v8Start: 4.4828340001404285,
bootstrapComplete: 23.200709000229836,
environment: 14.673166999593377,
loopStart: 32.78204200044274,
loopExit: -1,
idleTime: 3450.757752
},
timeOrigin: 1672118216112.88
},
fetch: [AsyncFunction: fetch]
}
> globalThis
<ref *1> Object [global] {
global: [Circular *1],
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
structuredClone: [Function: structuredClone],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
atob: [Function: atob],
btoa: [Function: btoa],
performance: Performance {
nodeTiming: PerformanceNodeTiming {
name: 'node',
entryType: 'node',
startTime: 0,
duration: 7456.196583999321,
nodeStart: 1.6185420006513596,
v8Start: 4.4828340001404285,
bootstrapComplete: 23.200709000229836,
environment: 14.673166999593377,
loopStart: 32.78204200044274,
loopExit: -1,
idleTime: 7309.061877
},
timeOrigin: 1672118216112.88
},
fetch: [AsyncFunction: fetch]
}
> globalThis === global
true
> global.console
Object [console] {
log: [Function: log],
warn: [Function: warn],
dir: [Function: dir],
time: [Function: time],
timeEnd: [Function: timeEnd],
timeLog: [Function: timeLog],
trace: [Function: trace],
assert: [Function: assert],
clear: [Function: clear],
count: [Function: count],
countReset: [Function: countReset],
group: [Function: group],
groupEnd: [Function: groupEnd],
table: [Function: table],
debug: [Function: debug],
info: [Function: info],
dirxml: [Function: dirxml],
error: [Function: error],
groupCollapsed: [Function: groupCollapsed],
Console: [Function: Console],
profile: [Function: profile],
profileEnd: [Function: profileEnd],
timeStamp: [Function: timeStamp],
context: [Function: context]
}
수많은 속성이 들어있는 것을 확인할 수 있으며, 전역 객체라는 점을 이용해 파일 간의 간단한 데이터를 공유할 때 사용되기도 합니다.
globalA.js
module.exports = () => global.message;
globalB.js
const A = require("./globalA");
global.message = "안녕하세요";
console.log(A());
@콘솔출력값
$ node global/globalB
안녕하세요
globalA 모듈의 함수는 global.message 값을 반환하고, globalB에서는 global의 message 속성을 '안녕하세요' 값으로 대입하였습니다.
그 후 globalA 모듈에서 넘겨 받은 함수를 호출하니, globalB에서 넣은 '안녕하세요'가 출력되는 것을 확인할 수 있습니다.
console
- 보통 디버깅을 위해 사용
- 브라우저의 console과 비슷
const string = "abc";
const number = 1;
const boolean = true;
const obj = {
outside: {
inside: {
key: "value",
},
},
};
console.time("전체 시간"); // 타이머
console.log("평범한 로그입니다 쉼표로 구분해 여러 값을 찍을 수 있습니다.");
console.log(string, number, boolean);
console.error("에러 메세지는 console.error에 담음!");
console.table([
{ name: "제로", birth: 1994 },
{ name: "chany", birth: 1999 },
]);
console.dir(obj, { color: false, depth: 2 });
console.dir(obj, { color: true, depth: 1 });
console.time("시간 측정");
for (let i = 0; i < 100000; i++) {}
console.timeEnd("시간 측정");
function b() {
console.trace("에러 위치 추적");
}
function a() {
b();
}
a();
console.timeEnd("전체 시간");
@콘솔출력값
$ node part3/console
평범한 로그입니다 쉼표로 구분해 여러 값을 찍을 수 있습니다.
abc 1 true
에러 메세지는 console.error에 담음!
┌─────────┬─────────┬───────┐
│ (index) │ name │ birth │
├─────────┼─────────┼───────┤
│ 0 │ '제로' │ 1994 │
│ 1 │ 'chany' │ 1999 │
└─────────┴─────────┴───────┘
{ outside: { inside: { key: 'value' } } }
{ outside: { inside: [Object] } }
시간 측정: 0.999ms
Trace: 에러 위치 추적
at b (/Users/parkchaeeun/project/playground-cepark/part3/console.js:30:11)
at a (/Users/parkchaeeun/project/playground-cepark/part3/console.js:33:3)
at Object.<anonymous> (/Users/parkchaeeun/project/playground-cepark/part3/console.js:35:1)
at Module._compile (node:internal/modules/cjs/loader:1159:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
at Module.load (node:internal/modules/cjs/loader:1037:32)
at Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:23:47
전체 시간: 7.201ms
- console.time(레이블)
: console.timeEnd(레이블)과 대응되어 같은 레이블을 가진 time과 timeEnd 사이의 시간 측정 - console.log(내용)
: 평범한 로그 콘솔에 표시, 여러 내용을 동시에 표시도 가능 - console.error(에러 내용)
: 에러를 콘솔에 표시 - console.table(배열)
: 배열의 요소로 객체 리터럴을 넣으면, 객체 속성들이 테이블 형식으로 표현 - console.dir(객체, 옵션)
: 객체를 콘솔에 표시할 때 사용, 옵션의 color를 true로 하면 콘솔에 색 추가, depth는 객체 안의 객체를 몇 단계까지 보여줄지 결정(기본 2) - console.trace(레이블)
: 에러가 어디서 발생했는지 추적
타이머
- setTimeout(콜백 함수, 밀리초)
: 주어진 밀리초 이후에 콜백 함수 실행 - setInterval(콜백 함수, 밀리초)
: 주어진 밀리초마다 콜백 함수 반복 실행 - setImmediate(콜백 함수)
: 콜백 함수 즉시 실행 - clearTimeout(아이디)
: setTimeout 취소 - clearInterval(아이디)
: setInterval 취소 - clearImmediate(아이디)
: setImmediate 취소
timer.js
const timeout = setTimeout(() => {
console.log("1.5초 뒤에 실행");
}, 1500);
const interval = setInterval(() => {
console.log("1초마다 실행");
}, 1000);
const timeout2 = setTimeout(() => {
console.log("실행되지 않습니다.");
}, 3000);
setTimeout(() => {
clearTimeout(timeout2);
clearInterval(interval);
}, 2500);
const immediate = setImmediate(() => {
console.log("즉시 실행");
});
const immediate2 = setImmediate(() => {
console.log("실행되지 않습니다.");
});
clearImmediate(immediate2);
@콘솔출력값
$ node part3/timer
즉시 실행
1초마다 실행
1.5초 뒤에 실행
1초마다 실행
타이머는 콜백 기반 API이지만, 프로미스 방식을 사용할 수도 있습니다.
timerPromise.mjs (노드 내장 모듈)
import { setTimeout, setInterval } from "timers/promises";
await setTimeout(3000);
console.log("3초 뒤 실행");
for await (const startTime of setInterval(1000, Date.now())) {
console.log("1초마다 실행", new Date(startTime));
}
@콘솔출력값
$ node part3/timerPromise.mjs
3초 뒤 실행
1초마다 실행 2022-12-27T05:47:40.800Z
1초마다 실행 2022-12-27T05:47:40.800Z
1초마다 실행 2022-12-27T05:47:40.800Z
1초마다 실행 2022-12-27T05:47:40.800Z
1초마다 실행 2022-12-27T05:47:40.800Z
...
timers/promises 모듈에서의 setTimeout은 몇 밀리초를 기다릴지 정할 수 있으며,
setInterval(밀리초, 시작값)은 for await of 문법과 함께 사용할 수 있습니다.
process
- 현재 실행되고 있는 노드 프로세스에 대한 정보를 담은 객체
> process.version
'v18.12.1' // 설치된 노드 버전
> process.arch
'arm64' // 프로세서 아키텍처 정보
> process.platform
'darwin' // 운영체제 플랫폼 정보
> process.pid
2907 // 현재 프로세스의 아이디
> process.uptime()
35.859721209 // 프로세스가 시작된 후 흐른 시간 (초 단위)
> process.execPath
'/usr/local/bin/node' // 노드 경로
> process.cwd()
'/Users/parkchaeeun/project/playground-cepark' // 현재 프로세스가 실행되는 위치
> process.cpuUsage()
{ user: 512692, system: 78497 } // 현재 cpu 사용량
process.env
- 시스템의 환경 변수
process.env를 입력하면 많은 정보가 출력되는데, UV_THREADPOOL_SIZE와 NODE_OPTIONS가 대표적입니다.
- NODE_OPTIONS
: 노드를 실행할 때의 옵션들을 입력받는 환경 변수 - UV_THREADPOOL_SIZE
: 노드에서 기본적으로 사용하는 스레드 풀의 스레드 개수를 조절할 수 있음
이 외에도 임의로 환경 변수를 저장할 수도 있습니다.
process.env는 서비스의 중요한 키를 저장하는 공간으로도 사용됩니다. (서버나 DB 비밀번호, 각종 API 키 등)
const secretId = process.env.SECRET_ID;
const secretCode = process.env.SECRET_CODE;
process.nextTick(콜백)
- 이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선으로 처리하도록 만듦
setImmediate(() => {
console.log("immediate");
});
process.nextTick(() => {
console.log("nextTick");
});
setTimeout(() => {
console.log("timeout");
}, 0);
Promise.resolve().then(() => console.log("promise"));
@콘솔출력값
$ node part3/nextTick
nextTick
promise
timeout
immediate
process.nextTick은 setImmediate나 setTimeout보다 먼저 실행됩니다.
Promise 또한 resolve된 Promise도 nextTick처럼 다른 콜백들보다 우선시 됩니다.
이를 마이크로태스크 라고 구분하여 부릅니다.
process.exit(코드)
- 실행 중인 노드 프로세스 종료
- 서버 환경에서 사용 시 서버가 멈추므로, 특수한 경우에만 사용
- 서버 외 독립적인 프로그램에서는 수동으로 노드를 멈추기 위해 사용
let i = 1;
setInterval(() => {
if (i === 5) {
console.log("종료!");
process.exit();
}
console.log(i);
i += 1;
}, 1000);
@콘솔출력값
$ node part3/exit
1
2
3
4
종료!
process.exit 메소드는 인수로 코드 번호를 줄 수 있습니다.
- 0 : 정상 종료
- 1 : 비정상 종료
따라서 에러가 발생해서 종료하는 경우에는 1을 넣어줍니다.
기타 내장 객체
fetch를 노드에서도 쓸 수 있게 됨에 따라 브라우저에 존재하던 객체들이 노드에도 동일하게 생성되어 브라우저의 코드를 일부 재사용할 수 있습니다.
- URL, URLSearchParam
- AbortController, FormData, fetch, Headers, Request, Response, Event, EventTarget
: 브라우저에서 사용하던 API가 노드에도 동일하게 생성 - TextDecoder
: Buffer를 문자열로 바꿈 - TextEncoder
: 문자열을 Buffer로 바꿈 - WebAssembly
: 웹어셈블리 처리 담당
'JavaScript > Node.js' 카테고리의 다른 글
Node) http 모듈로 서버 만들기 - 쿠키와 세션, https와 http2, cluster (0) | 2022.12.28 |
---|---|
Node) http 모듈로 서버 만들기 - 요청과 응답 이해하기, REST와 라우팅 이용하기 (0) | 2022.12.27 |
Node) 노드 기능 알아보기 - 이벤트 이해하기, 예외 처리하기 (0) | 2022.12.27 |
Node) 노드 기능 알아보기 - 노드 내장 모듈 사용하기 (1) | 2022.12.27 |
Node) 노드 기능 알아보기 - REPL, 모듈 사용하기 (1) | 2022.12.27 |