nodeJS에는 golobal이라는 객체가 존재한다.
전역에 어떤 변수를 선언하게 되면 해당 변수는 global 객체에 정의되게 된다.
(브라우저 위에서 동작하는 자바스크립트 런타임 환경은 windosw 객체에 정의된다.)
nodeJS에서 global 객체의 형태
console.log(global);
// 출력결과
/* <ref *1> Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
queueMicrotask: [Function: queueMicrotask],
performance: Performance {
nodeTiming: PerformanceNodeTiming {
name: 'node',
entryType: 'node',
startTime: 0,
duration: 31.01824999973178,
nodeStart: 1.1722079999744892,
v8Start: 1.708416999783367,
bootstrapComplete: 24.04904199996963,
environment: 14.396042000036687,
loopStart: -1,
loopExit: -1,
idleTime: 0
},
timeOrigin: 1641960743299.417
},
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
}
} */
global
객체 내부에는 setInterval
, setTimeout
과 같이 자바스크립트에서 기본으로 제공해주는 다양한 변수들이 존재하는 것을 확인 할 수 있다.
global
객체에 어떤 것들이 있는지 자세하게 보고 싶다면 NodeJS 문서 - Global 를 확인해보자
정의와 사용
global.greeting1 = () => {
global.console.log('hi, there!');
};
global.greeting1();
// hi, there!
greeting1();
// hi, there!
greeting2 = () => {
console.log('hello, world!');
};
global.greeting2();
// hello, world!
greeting2();
// hello, world!
global
에 직접 정의를 하거나 전역에 정의하는 것은 같은 것이다. 사용할 때 global
은 생략이 가능하다.
global 정의부 구경하기
// vscode에게 브라우저용인지 노드용인지 알려주기 위해 노드모듈 중에 하나인 fs를 임포트하여 노드용이라고 인식 시켜준다.
// 이렇게 하면 vscode에서 해당 파일이 노드용으로 인식되어 노드JS의 정의부를 탐색할 수 있다.
const fs = require('fs');
console.log(global); // global에 cmd + 왼쪽클릭을 하면 정의부로 이동할 수 있다.
이전 노드버전에서는 global 키워드 cmd + 왼쪽클릭
을 하면 정의부로 가서 어떤것들이 정의되어있는지 확인할 수 있었다. 하지만 최신 node버전인 경우 타입으로 정의된 노드만 보여서 자세한 내용을 볼 수 없는데 이 곳 에서 정의를 자세하게 확인 할 수 있다.
콘솔에는 다양한 메서드가 존재한다. 하나씩 알아보자!
// log level
console.log('log'); // 개발용, 개발이 완료된 후 지원주자.
console.info('info'); // 정보 출력용
console.warn('warn'); // 경보 출력용
console.error('error'); // 에러, 사용자 에러, 시스템 에러 출력용
// 로그에 따라 레벨을 나누어서 출력할 수 있다. 심각한 에러의 정보를 출력하는 거라면 error를, 약간의 경고정도이면 warn을 사용하는 방식으로 의미적으로 사용하는게 좋다.
// assert - 참이 아닌 경우 출력
console.assert(2 === 3, 'not same!');
console.assert(2 === 2, 'same!');
// print object - 객체를 테일블로 출력
const student = { name: 'ellie', age: 20, company: { name: 'AC' } };
console.log(student);
// { name: 'ellie', age: 20, company: { name: 'AC' } }
console.table(student);
// ┌─────────┬──────┬─────────┐
// │ (index) │ name │ Values │
// ├─────────┼──────┼─────────┤
// │ name │ │ 'ellie' │
// │ age │ │ 20 │
// │ company │ 'AC' │ │
// └─────────┴──────┴─────────┘
console.dir(student, { showHidden: true, colors: false, depth: 0 });
// { name: 'ellie', age: 20, company: [Object] }
// 시간 측정
console.time('for loop');
for (let i = 0; i < 10; i++) {
i++;
}
console.timeEnd('for loop');
// for loop: 0.031ms
// counting
function a() {
console.count('a function'); // 해당 함수가 몇번 호출되었는지 실행될 때마다 카운트 값을 출력해준다.
}
a();
// a function: 1
a();
// a function: 2
console.countReset('a function'); // 여태까지 카운트된 것을 초기화해준다.
a();
// a function: 1
// trace - 해당 함수가 어떻게 호출되었는지 정보를 출력해준다.
function f1() {
f2();
}
function f2() {
f3();
}
function f3() {
console.log('f3');
console.trace();
}
f1();
// Trace
// at f3 (/Users/uno/Desktop/web/nodejs/4-node-module/2-console/app.js:44:11)
// at f2 (/Users/uno/Desktop/web/nodejs/4-node-module/2-console/app.js:40:3)
// at f1 (/Users/uno/Desktop/web/nodejs/4-node-module/2-console/app.js:37:3)
// at Object.<anonymous> (/Users/uno/Desktop/web/nodejs/4-node-module/2-console/app.js:46:1)
// at Module._compile (node:internal/modules/cjs/loader:1101:14)
// at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
// at Module.load (node:internal/modules/cjs/loader:981:32)
// at Function.Module._load (node:internal/modules/cjs/loader:822:12)
// at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
// at node:internal/main/run_main_module:17:47
브라우저에서의 this와 nodejs의 this는 살짝 다르다. (브라우저에서의 this)
this는 어떤 scope에서 어떻게 사용하냐에 따라 근본이 달라진다.
function에서 사용한다면
class에서 사용한다면 this는 인스턴스화 된 객체를 가리킨다.
(⚠️집중!) global scope에서 사용한다면 this는 module.export
(module에 있는 exports)를 나타낸다.
// 만약 노드 전역공간이라면
console.log(this === module.exports); // true
// 만약 브라우저 전역공간이라면
console.log(this === window); // true
브라우저에서는 global scope에서 사용한다면 this는 window를 가리킨다.)
nodejs에서 모듈을 사용하는것은 크게 2가지가 있다.
nodeJS 전용으로 사용하는 모듈 방식과 (Commonjs
)
자바스크립트 es6버전 이상에서 제공하는 모듈 방식이 있다. (ECMAScriptModules
)
둘중 어느것을 사용해도 무방하다.
commonjs
module.export
)// 내보내는 파일
let count = 0;
function getCount() {
return count;
}
funtionc increase() {
counter++;
}
module.exports.getCount = getCount;
module.exports.increase = increase;
모듈을 생략하고 exports.getCount = getCount;
와 같은 방식으로 사용해도 무방하다.
하지만 혹시나 export라는 객체가 선언되어있다면 에러가 발생하므로 되도록 module.exports
로 사용하자.
require
)// 사용하는 파일
const counter = require('./counter.js');
counter.increase();
counter.increase();
counter.increase();
console.log(counter.getCount());
modules
)자바스크립트에서 제공하는 최신 문법을 사용하려면 package.json
설정파일이 필요하다.
package.json
우선 아래 명령어로 package.json
파일을 생성한다.
$ npm init
package.json
파일에서 type
필드에 값을 "modules"
로 설정한다.
이렇게 하면 node로 js파일을 실행할 때 modules
방식으로 동작 시킬 수 있다.
{
"name": "5-module",
"version": "1.0.0",
"description": "",
"main": "app.js",
"type": "module", // "commonjs"로 하면 nodejs전용 모듈방식을 따른다.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
module.export
)// 내보내는 파일
let count = 0;
export function increase() {
count++;
}
export function getCount() {
return count;
}
모듈을 생략하고 exports.getCount = getCount;
와 같은 방식으로 사용해도 무방하다.
하지만 혹시나 export라는 객체가 선언되어있다면 에러가 발생하므로 되도록 module.exports
로 사용하자.
require
)// 사용하는 파일
// import {getCount, increase} from './counter.js';
import * as counter from './counter.js';
counter.increase();
counter.increase();
counter.increase();
console.log(counter.getCount());
내 서버가 동작하고 있는 환경에 대한 정보를 알기 위해 사용한다.
const os = require('os');
console.log(os.EOL === '\n'); // 맥의 줄바꿈 형식
console.log(os.EOL === '\r\n'); // 윈도우의 줄바꿈 형식
console.log(os.totalmem()); // 전체 메모리
console.log(os.freemem()); // 사용가능한 메모리
console.log(os.type()); // 운영체제 타입
console.log(os.userInfo()); // 사용자 정보
console.log(os.cpus()); // cpu 정보
console.log(os.homedir()); // 홈디렉토리 경로
console.log(os.hostname()); // 호스트 이름
node 프로그램이 동작하고 있는 즉, node의 프로세스 정보를 알기 위해 사용한다.
const process = require('process');
console.log(process.execPath); // 현재 실행되고 있는 위치
console.log(process.version); // 노드의 버전
console.log(process.pid); // 프로세스 아이디
console.log(process.ppid); // 프로세스 부모의 아이디
console.log(process.platform); // 플랫폼 정보
console.log(process.env); // 환경변수 정보
console.log(process.uptime()); // node가 얼마나 실행되었는지
console.log(process.cwd()); // 현재 실행되고 있는 node의 경로
console.log(process.cpuUsage()); // cpu 사용량
// process.nextTick
// nextTick은 setTimeout과 비슷하다.
// 지금 당장 실행하는게 아니고 태스크큐에 콜백으로 넘기고 실행하게 도와주는 메서드이다.
// nextTick이 단순히 nextTick의 콜백 함수를 태스크 큐에 넣는데 그치는게 아니라, 태스크 큐에서 대기 중인 콜백들 중에서 가장 선처리 될 수 있도록 강제
setTimeout(() => {
console.log('setTimeout');
}, 0);
process.nextTick(() => {
console.log('nextTick');
});
for (let i = 0; i < 100; i++) {
console.log('for loop');
}
// 출력
// for loop ...
// nextTick
// setTimeout
setTimeout
: 특정 ms 이후 콜백을 태스크큐에 넣어준다.
setImmediate
: 즉시 콜백을 태스크큐에 넣준다. (setTimeout(..., 0)
과 동일하다.)
process.nextTick
: 즉시 콜백을 태스큐의 맨 처음에 넣어준다.
console.log('code1');
setTimeout(() => {
console.log('setTimeout 0');
}, 0);
console.log('code2');
setImmediate(() => {
console.log('setImmediate');
});
console.log('code3');
process.nextTick(() => {
console.log('process.nextTick');
});
// 출력
// code1
// code2
// code3
// process.nextTick
// setImmediate
// setTimeout 0
파일의 경로를 접근하거나 경로에 대해 어떤 처리를 할 때 유용하게 사용할 수 있다.
// example in /Users/uno/Desktop/node/path.js
const path = require('path');
// 운영체제별 경로 표현 방식
// POSIX (Unix: Mac, Linux): 'Users/temp/myfile.html'
// Windows: 'C:\\temp\\myfile.html'
console.log(__dirname); // 현재 파일이 위치한 디렉토리 경로
// Users/uno/Desktop/node
console.log(__filename); // 현재 파일의 경로
// Users/uno/Desktop/node/path.js
console.log(path.sep); // 경로 구분자 (운영체제별 상이)
// /
console.log(path.delimiter); // 환경변수 구분자 (운영체제별 상이)
// :
// basename
console.log(path.basename(__filename)); // 현재 파일 혹은 폴더 이름
// path.js
console.log(path.basename(__filename, '.js')); // 파일이름에서 확장자면 제거
// path
// dirname
console.log(path.dirname(__filename)); // 현재 디렉토리 이름
// Users/uno/Desktop/node
// extension
console.log(path.extname(__filename)); // 파일의 확장자
// .js
//parse
const parsed = path.parse(__filename); // 파싱
console.log(parsed); // 객체 형태
// {
// root: '/',
// dir: '/Users/uno/Desktop/node',
// base: 'path.js',
// ext: '.js',
// name: 'path'
// }
console.log(parsed.root);
// /
console.log(parsed.name);
// path
const str = path.format(parsed); // parsed된 객체를 기존의 경로 문자열로 변환
console.log(str);
// isAbsolute 절대 경로인지 상대경로인지
console.log('isAbsolute?', path.isAbsolute(__dirname));
// true
console.log('isAbsolute?', path.isAbsolute('../'));
// false
// normalize - 경로에 이상한 부분을 자동으로 수정
console.log(path.normalize('./folder////////sub'));
// './folder/sub'
// join - 경로를 편하게 조합
console.log(__dirname + path.sep + 'image');
// Users/uno/Desktop/node/image
console.log(path.join(__dirname, 'image'));
// // Users/uno/Desktop/node/image