[Node.js] Node.js 기본

Published: by Creative Commons Licence

참고 문서

node에서는 모든게 병렬로 수행된다. 당신 code만 빼고

시작하기

설치

아래 링크에서 OS에 맞는 파일을 받아 설치한다. https://nodejs.org/en/download/

안될 경우 NODE_PATH = C:\Users\noriter\AppData\Roaming\npm\node_modules 패스 추가.

구동

node 파일명

node 명령어는 단독으로 사용했을 때 REFL이라고 하는 Node.js shell로 진입한다. 위처럼 파일명과 같이 사용하면 해당 파일을 Node.js로 실행하라는 의미이다.

sync/async

쉽게 표현해서, 동기 방식인 blocking I/O가 아래처럼 돌아간다면:

puts("이름을 입력하세요");
var name = gets();
puts("당신의 이름은" + name + "입니다.");

비동기 방식인 non-blocking I/O는 아래와 같다:

puts("이름을 입력하세요");
gets(function (name) {
  puts("당신의 이름은" + name + "입니다.");
});

이벤트 루프란?

프로세스의 처리과정을 이벤트의 순환으로 구현한 것, 혹은 이벤트를 처리하는 스택구조 자체를 이벤트 루프라 함.

노드 표준 코딩 관례

  • 들여쓰기: 공백 2칸
  • 문장종결: 문장의 끝은 JavaScript의 관례대로 세미콜론(;)을 사용함
  • 문자열: 문자열은 큰따옴표"" 대신 작은따옴표''를 사용한다.
  • 블록을 시작하는 중괄호는 시작하는 문장과 같은 라인에 작성한다.
  • 변수와 프로퍼티: 소문자로 시작하는 카멜케이스를 사용한다.
  • 클래스: 대문자로 시작하는 카멜케이스를 사용한다.
  • 동등 비교: == 대신 ===를 사용한다.
  • 콜백 함수: 콜백 함수에서 첫 매개변수는 노드 코어의 콜백 함수처럼 에러 매개변수로 사용한다.
  • nodejs style guide(eng).pdf
  • nodejs style guide(kor).pdf

exports/require

노드에서 하나의 JavaScript 파일은 하나의 모듈이 된다. 기본적으로 노드는 각 JavaScript 파일을 익명함수로 감싸 외부에서 접근할 수 없게 만드는데 이것을 모듈화라고 하며 모듈간 참조와 호출을 위해 글로벌 객체 module의 exports/require를 사용한다.

module.exports

모듈로 내보내기.

//Syntex 1: module.exports.내보낼함수명 = 함수명
function drawCircle() {
  ...
}
exports.drawCircle = drawCircle;

//Syntex 2: module.exports = 함수리터럴 혹은 익명함수
exports.fibonacchi = function (num) {
  return -1;
};

//Syntex 3: 변수 = module.exports = 함수
var show = exports.show = function () {
  console.log('hi');
}

module.exports에서 module은 전역 객체이기 때문에 생략할 수 있다. 단, exports의 프로퍼티가 아닌 exports에 직접 할당할 때는 제외.

require

모듈 가져오기.

require(경로/파일명);

경로는 문자열' '로 표시하며 경로를 생략할 경우 기본모듈이나 확장모듈(Node.js가 기본적으로 제공하는 모듈 혹은 npm으로 설치한 모듈을 말하며 이 둘을 native module이라 한다.)을 가져온다.

같은 경로내에 가져올 js 파일이 있다면 경로는 ./가 되고 한 단계 상위의 폴더라면 경로는 ../가 된다.

var userModule = require('./user_module');

require()로 호출된 파일은 노드 애플리케이션 내에 캐싱된다. 다시 말해 같은 파일을 여러 번 호출해도 최초로 생성되었던 객체가 반복적으로 반환된다. 별도의 인스턴스가 필요하다면 함수를 따로 호출하거나, 함수 자체를 내보내 new로 인스턴스를 생성해서 사용해야 함.

작성 예시 #1

function printA() {};
var PI = 3.14;

exports.printA = printA;
exports.PI = PI;

// 위에서 내보낸 모듈은 다음처럼 가져온다
var userModule = require('js를_제외한_파일_경로');
userModule.printA();
console.log(userModule.PI);

작성 예시 #2

// exports-test.js
module.exports = { // 이렇게 내보낼 땐 module을 생략할 수 없음
  connectString: '10.20.30.40:1234/QADB',
  user: 'fixalot',
  password: '1234abcd!'
}
// run-me.js
const dbinfo = require('./exports-test.js');
console.log('dbinfo.connectString:', dbinfo.connectString);
console.log('dbinfo.user:', dbinfo.user);
console.log('dbinfo.password:', dbinfo.password);
PS > node .\run-me.js
dbinfo.connectString: 10.20.30.40:1234/QADB
dbinfo.user: fixalot
dbinfo.password: 1234abcd!

require로 코드 줄이기

자주 사용하는 메서드가 있다면 require로 해당 메서드를 별도의 변수에 담아 코드를 줄이는 방법이 있다:

const log = require('console').log;

여기에 ES2015의 단축 표기법을 적용하면:

const {log} = require('console');

이렇게 된다.

그런데 사실 console은 어차피 전역 객체이므로 그냥 아래처럼 쓰면 됨:

const {log} = console;

환경 변수 Environment Variable

운영체제나 실행 환경에서 애플리케이션에 전달하는 이름=값 형태의 설정값이다. 데이터베이스 주소, API 키, 포트 번호, 실행 환경 등의 값을 외부에서 주입할 때 사용한다.

환경 변수의 이름이나 용도는 공식적으로 정해져 있는 것이 없다. 다만 Node.js 생태계에서는 관례적으로 NODE_ENV를 현재 애플리케이션의 실행 환경(development, production, test)을 나타내는 용도로 사용한다.

그리고 .env, .env.development, .env.production 같은 파일로 나누어 관리하는 경우가 많은데, 이것은 Node.js가 아니라 Next.js, Nuxt 같은 프레임워크나 dotenv 같은 라이브러리에서 제공하는 기능이다.

ℹ️ Node.js는 --env-file 또는 --env-file-if-exists 옵션으로 지정한 파일의 환경 변수를 읽어오는 기능을 내장하고 있다. 이 방법으로 정의된 환경 변수는 인라인 환경 변수보다 우선순위가 낮다.

예시

package.json:

{
  "name": "test",
  "scripts": {
    "start": "cross-env NODE_ENV=development MY_CUSTOM_ENV='Hello world!' node --env-file-if-exists=.env test-me.js"
  },
  "dependencies": {
    "cross-env": "^10.1.0"
  },
  "packageManager": "yarn@4.18.0"
}

.env:

A=AAA
B=BBB
NODE_ENV=1 # 인라인 환경 변수 때문에 이 설정은 무시됨
MY_CUSTOM_ENV=2 # 인라인 환경 변수 때문에 이 설정은 무시됨

test-me.js:

console.log(process.env.NODE_ENV); // 'development'
console.log(process.env.MY_CUSTOM_ENV); // 'Hello world!'
console.log(process.env.A); // 'AAA'
console.log(process.env.B); // 'BBB'

package.json: start 스크립트 해석:

  1. cross-env: OS 호환 실행(Windows에서는 NODE_ENV=development 같은 명령이 작동하지 않음)
  2. NODE_ENV=development: NODE_ENV라는 인라인 환경 변수 설정 (이 예시에선 출력용 변수 말고 아무런 역할 없음)
  3. MY_CUSTOM_ENV='Hello world!': MY_CUSTOM_ENV라는 인라인 환경 변수 설정
  4. --env-file-if-exists=.env: .env 파일이 존재하면 그 안의 환경 변수를 읽어들인다.
  5. test-me.js: Node.js로 test-me.js 파일 실행