본문 바로가기

Node.js

Node.js - REPL, 모듈, 내장 객체 (REPL, Module, Implicit Object)

앞으로의 노드 관련 포스트들은 Node.js 교과서 - 길벗, 조현영 책을 보고 배운 점들을 정리해 놓는 포스트들입니다.

REPL

브라우저 콘솔 탭에서 자바스크립트 코드를 입력하는 것처럼, 노드 또한 비슷한 기능을 제공한다. 입력한 코드를 읽고 (Read), 해석하고 (Evaluate), 결과물을 반환하고 (Print), 종료할 때까지 반복한다 (Loop) 고 해서 REPL이라고 부른다. 파이썬의 IDLE 같은 기능이라고 생각하면 된다. 커맨드에 node라고 쳐서 실행한다.

 

C:\Users\bumsu>node
Welcome to Node.js v14.7.0.
Type ".help" for more information.
> const str = 'hello'
undefined
> console.log(str)
hello
undefined

 

모듈

노드는 코드를 모듈로 만들 수 있다. 모듈이란, 특정한 기능을 하는 함수나 변수들의 집합이다. 모듈로 만들어두면 여러 프로그램에서 해당 모듈을 재사용할 수 있다는 장점이 있다.

 

실제 모듈을 만들어보자. 모듈을 만들 때는 모듈이 될 파일과 모듈을 불러와서 사용할 파일이 필요하다. 먼저 같은 폴더 안에 var.js, func.js, index.js를 만들고 var.js를 아래와 같이 작성한다.

 

const odd = '홀수입니다.';
const even = '짝수입니다.';

module.exports = {
    odd,
    even
};

 

그 다음 func.js는 다음과 같이 작성한다.

 

const { odd, even } = require('./var');

function checkOddOrEven(num) {
    if (num % 2) {
        return odd;
    }
    return even;
}

module.exports = checkOddOrEven;

 

마지막으로 index.js 를 다음과 같이 작성하고 실행시켜 준다.

 

const checkNumber = require('./func');

console.log(checkNumber(10))

 

결과

 

PS C:\Users\bumsu\nodejs-projects\노드js교과서\3. 노드 기능 알아보기\module> node index.js 
짝수입니다.

 

func.js 는 var.js 모듈의 변수들인 odd 와 even 을 객체에 담아와 사용한다. index.js 는 func.js 모듈의 함수인 checkOddOrEven 함수를 받아와 사용한다. 그러나 가져올 때 이름이 무조건적으로 같을 필요는 없다 (함수 또한 객체이기 때문에). 어차피 객체로써 오기 때문에, 새로 이름을 지정해 주어도 상관없다. 물론 같은 이름으로 받아오는 것이 직관적이며 더 보기 쉬운 코드가 되긴 한다.

 

ES2015가 도입되며 자바스크립트도 자체 모듈 시스템 문법이 생겼다. import 와 export, export default 가 그것들이다 (리액트에서 쓰던 그것 맞다). 노드에서도 9 버전부터 ES2015의 모듈 시스템을 사용할 수 있게 되었지만 파일의 확장자를 mjs로 지정해주어야 하는 제한이 있다. 따라서 mjs 확장자 대신 js 확장자를 사용하려면 package.json에 type: "module" 속성을 넣어주면 된다.

 

노드의 내장 객체

노드에서는 기본적인 내장 객체와 내장 모듈을 제공한다. 마치 브라우저의 window 객체와 비슷하다고 생각하면 된다.

 

global

global 객체는 브라우저의 window 객체와 같이 전역 객체이며, 따라서 모든 파일에서 접근할 수 있고, 생략 가능하다. 예를 들어 방금까지 사용하던 require 함수 또한 global의 기본 함수인 global.require 에서 global이 생략된 것이다. 노드 콘솔에 로그를 기록하는 console 객체 또한 원래는 global.console 이다.

 

노드에는 DOM이나 BOM이 없다. 따라서 window와 document 객체는 노드에서 사용할 수 없다.

 

global 객체의 속성은 REPL에 global이라고 쳐서 검색하거나 아래에서 보도록 하자.

https://ryulog.tistory.com/97

 

[ NodeJS 09 ] global 객체

1. global 객체 지금부터는 Node내장객체에 대해 알아보자. 브라우저에서 window라는 전역 객체를 많이 사용했을것이다. 그렇다면 Node에서 window를 찍어보면 어떻게 될까? 한번찍어보자. window is not de

ryulog.tistory.com

 

global.message 라는 객체가 있는데 global 자체가 전역 객체이기 때문에 이를 이용해 파일 간 간단한 데이터의 공유 시 사용하기도 한다.

 

console

지금까지 사용했던 console도 노드에서는 window 대신 global 객체 안에 들어있으며, 브라우저에서의 console과 거의 동일하다.

 

console에는 다음과 같은 메서드들이 있다.

  • console.time(레이블): console.timeEnd(레이블) 과 대응되어, 같은 레이블을 가진 time과 timeEnd 사이의 시간을 측정한다.
  • console.log(내용): 평범한 로그를 콘솔에 표시한다. 여러 인수를 넣어 동시에 표현할 수 있다.
  • console.error(에러 내용): 에러를 콘솔에 표시한다.
  • console.table(배열): 배열의 요소로 객체 리터럴을 넣으면 객체의 속성들이 테이블 형식으로 표현된다.
  • console.dir(객체, 옵션): 객체를 콘솔에 표시할 때 사용한다. 옵션 중 colors 를 true로 하면 콘솔에 색이 추가되어 보기 편해진다. depth는 객체 안의 객체를 몇 단계까지 보여줄지 결정한다.
  • console.trace(레이블): 에러가 어디서 발생했는지 추적하게 해준다.

 

타이머

타이머 기능을 제공하는 함수인 setTimeout, setInterval, setImmediate는 노드에서 window 대신 global 객체 안에 들어있다.

  • setTimeout(콜백, 밀리초): 주어진 시간 이후에 콜백 함수를 실행한다.
  • setInterval(콜백, 밀리초): 주어진 시간마다 콜백 함수를 반복한다.
  • setImmediate(콜백): 콜백 함수를 즉시 실행한다. setTimeout(callback, 0)과 비슷한 기능을 수행하나, 둘 다 사용하면 실행 순서에 문제가 생길 수 있기 때문에 setTimeout(callback, 0)은 사용하지 않는 것을 권장한다.

이 타이머 함수들은 모두 아이디를 반환하며, 아이디를 사용하여 타이머를 아래 함수들로 취소할 수 있다.

  • clearTimeout(아이디): 해당 아이디의 setTimeout을 취소한다.
  • clearInterval(아이디): 해당 아이디의 setInterval을 취소한다.
  • clearImmediate(아이디): 해당 아이디의 setImmediate을 취소한다.

 

module, exports

module 객체 외에도 exports 객체로도 모듈을 만들 수 있다. 아까 만들었던 var.js 파일을 다음과 같이 바꾸어도 똑같이 동작한다.

 

const odd = '홀수입니다.';
const even = '짝수입니다.';

exports.odd = odd;
exports.even = even;

 

결과

 

PS C:\Users\bumsu\nodejs-projects\노드js교과서\3. 노드 기능 알아보기\module> node index.js 
짝수입니다.

 

이 경우 각각의 변수를 exports 객체에 하나씩 넣어주었다. 위 코드가 똑같이 동작하는 이유는 module.exports 와 exports가 같은 객체를 참조하기 때문이다. exports 객체가 module 객체의 exports 속성을 참조하고, 이 exports 속성이 다른 객체를 참조하는 식이다.

 

참고로 노드에서 this를 그냥 쓴다면 this는 module.exports (또는 exports) 객체를 의미한다. 또한 함수 선언문 내부의 this는 global 객체를 가리킨다.

 

require

require은 함수이다. 이 함수는 객체로써 몇 가지 속성을 갖고 있다. 그 중 require.cache 와 require.main에 대해 알아보자.

 

var.js가 있는 곳에 require.js를 만들고 다음과 같이 입력해주자.

 

console.log('require가 가장 위에 오지 않아도 됩니다.');

module.exports = '저를 찾아보세요.';

require('./var');

console.log('require.cache 입니다.');
console.log(require.cache);
console.log('require.main 입니다.');
console.log(require.main);
console.log(require.main === module);
console.log(require.main.filename);

 

결과

 

PS C:\Users\bumsu\nodejs-projects\노드js교과서\3. 노드 기능 알아보기\module> node require.js
require가 가장 위에 오지 않아도 됩니다.
require.cache 입니다.
[Object: null prototype] {
  'C:\\Users\\bumsu\\nodejs-projects\\노드js교과서\\3. 노드 기능 알아보기\\module\\require.js': Module {
    id: '.',
    path: 'C:\\Users\\bumsu\\nodejs-projects\\노드js교과서\\3. 노드 기능 알아보기\\module',
    ...
}
require.main 입니다.
<ref *1> Module {
  id: '.',
  path: 'C:\\Users\\bumsu\\nodejs-projects\\노드js교과서\\3. 노드 기능 알아보기\\module',
  ...
}
true

 

process

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

process.env

process.env를 입력하면 매우 많은 정보가 출력되는데 이는 시스템의 환경 변수임을 알 수 있다. 시스템 환경 변수는 노드에 직접 영향을 미치기도 하는데, 대표적으로 UV_THREADPOOL_SIZE 와 NODE_OPTIONS가 있다.

 

PS C:\Users\bumsu\nodejs-projects\노드js교과서\3. 노드 기능 알아보기\module> node
Welcome to Node.js v14.7.0.
Type ".help" for more information.
> process.env
{
  ALLUSERSPROFILE: 'C:\\ProgramData',
  APPDATA: 'C:\\Users\\bumsu\\AppData\\Roaming',
  ChocolateyInstall: 'C:\\ProgramData\\chocolatey',
  ...
 }

 

process.nextTick(콜백)

이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선적으로 처리하도록 한다. 이 메서드로 받은 콜백 함수나 resolve 된 Promise 는 다른 이벤트 루프에서 대기하는 콜백 함수보다도 먼저 실행된다. 그래서 개발자 중 setImmediate보다 이 함수를 더 선호하는 개발자도 있다. 그러나 이런 마이크로태스크를 재귀 호출하게 되면 이벤트 루프는 다른 콜백 함수들보다 마이크로 태스크를 우선하여 처리하므로, 콜백 함수들이 실행되지 않는 문제가 생길 수 있다.

 

setImmediate(() => {
    console.log('immediate');
});
process.nextTick(() => {
    console.log('nextTick');
});
setTimeout(() => {
    console.log('timeout');
}, 0);
Promise.resolve().then(() => {
    console.log('promise');
});

 

결과

 

PS C:\Users\bumsu\nodejs-projects\노드js교과서\3. 노드 기능 알아보기\module> node promises 
nextTick
promise
timeout
immediate

 

process.exit(코드)

실행 중인 노드 프로세스를 종료한다. 서버 환경에서 이 함수의 사용은 서버를 멈추게 하므로 특수한 경우를 제외하곤 잘 사용하지 않는다. 그러나 서버 외의 프로그램에서 수동으로 노드를 멈추게 하기 위해 사용한다.

 

process.exit 메서드는 인수로 코드를 전달해줄 수 있으며, 인수를 주지 않거나 0을 주면 정상 종료를 뜻하고, 1을 주면 비정상 종료를 뜻한다. 에러가 나서 종료해야 하는 경우라면 1을 넣으면 된다.