Node.js 기본 개념

Jeris·2023년 5월 5일
0

코드잇 부트캠프 0기

목록 보기
83/107

1. 모듈이란?

모듈(module)

모듈이란 전체를 이루는 부품 하나하나를 의미합니다. NodeJS에서는 자바스크립트 파일을 모듈이라고 할 수 있습니다.

강의에서는 common js module(require, exports)을 사용했는데, 장기적 관점에서 ES module로 바꿔 실습하려고 합니다.


2. ES module

ES module

ES Module은 ECMAScript 6 (ES6)에서 도입된 자바스크립트 모듈 시스템입니다. ES6에서 모듈화는 기본 기능으로 추가되어 브라우저 및 Node.js에서 사용할 수 있습니다.

ES Module은 다른 자바스크립트 파일에서 함수, 클래스, 변수 등을 내보내고 가져오는 데 사용됩니다. 모듈은 독립적인 파일로 작성되어 있으며, 다른 모듈에서 내보낸 항목을 가져와 사용할 수 있습니다. 이를 통해 코드의 모듈성, 재사용성, 유지 보수성이 향상됩니다.

ES Module을 사용하려면 import 문과 export 문을 사용하여 모듈에서 내보내고 가져올 항목을 선언해야 합니다. 브라우저에서는 type="module" 속성을 사용하여 ES Module을 로드하고 사용할 수 있습니다. Node.js에서는 .mjs 확장자를 사용하여 모듈 파일을 작성하고, import와 export 문을 사용하여 모듈을 사용합니다.

export

export 선언은 자바스크립트 모듈로부터 변수들이나 함수들을 내보내는 데 사욥됩니다. 내보낸 값은 import 선언 또는 dynamic import으로 다른 프로그램으로 가져올 수 있습니다. 가져올 바인딩(binding)된 값은 내보내는 모듈에서 변경할 수 있습니다.

소스 파일에서 export 선언을 사용하려면 런타임에서 파일을 모듈로 해석해야 합니다. HTML에서는 <script> 태그에 type="module"을 추가하거나 다른 모듈에서 import하는 방식을 사용합니다.

Syntax

// Exporting declarations
export let name1, name2/*, … */; // also var
export const name1 = 1, name2 = 2/*, … */; // also var, let
export function functionName() { /* … */ }
export class ClassName { /* … */ }
export function* generatorFunctionName() { /* … */ }
export const { name1, name2: bar } = o;
export const [ name1, name2 ] = array;

// Export list
export { name1, /* …, */ nameN };
export { variable1 as name1, variable2 as name2, /* …, */ nameN };
export { variable1 as "string name" };
export { name1 as default /*, … */ };

// Default exports
export default expression;
export default function functionName() { /* … */ }
export default class ClassName { /* … */ }
export default function* generatorFunctionName() { /* … */ }
export default function () { /* … */ }
export default class { /* … */ }
export default function* () { /* … */ }

// Aggregating modules
export * from "module-name";
export * as name1 from "module-name";
export { name1, /* …, */ nameN } from "module-name";
export { import1 as name1, import2 as name2, /* …, */ nameN } from "module-name";
export { default, /* …, */ } from "module-name";
export { default as name1 } from "module-name";

// Import
import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { default as alias } from "module-name";
import { export1, export2 } from "module-name";
import { export1, export2 as alias2, /* … */ } from "module-name";
import { "string name" as alias } from "module-name";
import defaultExport, { export1, /* … */ } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

예시

// package.json
{
  "type": "module"
}


// math-tools.js
export function add(a, b) {
  return a + b;
}


// main.js
import { add as plus } from "./math-tools.js"
console.log(plus(1, 2));  // 3

3. 코어 모듈

코어 모듈

코어 모듈(Core module)은 프로그램에서 기본적으로 제공하는 내장 모듈으로, Built-in module이라고도 합니다.

Node.js 코어 모듈들

assert 단위 테스트 및 디버깅을 위한 기능을 제공합니다.
buffer 이진 데이터를 다루는 기능을 제공합니다.
child_process 다른 프로세스를 생성하고, 명령어를 실행하며, 프로세스간 통신을 할 수 있는 기능을 제공합니다.
cluster 멀티 프로세스 환경을 구성하는 기능을 제공합니다.
console 콘솔 로그와 디버깅 기능을 제공합니다.
crypto 암호화와 관련된 기능을 제공합니다.
debugger 디버깅 기능을 제공합니다.
dns DNS(도메인 네임 시스템) 조회 기능을 제공합니다.
events 이벤트 기반 프로그래밍을 위한 기능을 제공합니다.
fs 파일 시스템에 대한 접근 기능을 제공합니다.
http HTTP 서버와 클라이언트 기능을 제공합니다.
net TCP 서버와 클라이언트 기능을 제공합니다.
os 운영체제와 관련된 기능을 제공합니다.
path 파일 경로를 다루기 위한 기능을 제공합니다.
process 프로세스와 관련된 기능을 제공합니다.
querystring URL 쿼리 스트링을 다루기 위한 기능을 제공합니다.
stream 데이터 스트림 처리를 위한 기능을 제공합니다.
timers 타이머 기능을 제공합니다.
url URL을 다루기 위한 기능을 제공합니다.
util 유틸리티 함수를 제공합니다.
vm 가상 머신을 사용한 자바스크립트 코드 실행 기능을 제공합니다.
zlib 데이터를 압축하고 해제하는 기능을 제공합니다.

예시

import * as fs from "fs";
import * as os from "os";

let fileList = fs.readdirSync(".");
console.log(fileList);

fs.writeFileSync("new", "Hello Ndoe.js!");

console.log(os.cpus());

4. Node.js와 브라우저의 차이

API(Application Programming Interface)

Node.js에서는 컴퓨터 제어 API가 있습니다. 그래서 Electron 프레임워크를 통해 VS code같은 데스크탑 애플리케이션을 만드는 데도 사용될 수 있습니다.

웹 브라우저에서는 UI 관련 API가 있습니다. 그리고 window, document같은 객체가 존재합니다.

실행 엔진

Node.JS의 경우 chrome V8을 실행 엔진으로 사용합니다.

웹 브라우저의 경우 종류와 버전에 따라 다양한 실행 엔진을 사용합니다.
Chrome V8
Firefox SpiderMonkey
Microsoft(Chromium) Edge V8
Edge(구버전) Chakra

ES6 호환성

ECMAScript 6 compatibility table 참조
각 실행 환경이 지원하는 ES 문법을 확인할 수 있습니다.


5. 서드파티 모듈

서드파티 모듈(Third party module)

서드파티 모듈은 Node.js 프로젝트에서 사용되는 외부 모듈을 말합니다. 이러한 모듈은 프로젝트를 개발하는 개발자나 팀이 작성한 것이 아닌, 다른 개발자나 조직이 만들어서 배포한 것입니다. 이러한 모듈은 npm과 같은 패키지 매니저를 통해 설치할 수 있으며, Node.js 프로젝트에서 필요한 다양한 기능을 제공합니다.

package-lock.json 파일

package-lock.json 파일은 npm 패키지 매니저를 사용하여 Node.js 프로젝트에서 설치된 패키지들의 의존성 관리를 위한 파일입니다. 이 파일은 npm install 명령을 실행할 때 생성되며, 프로젝트의 루트 디렉토리에 위치합니다.

package-lock.json 파일은 설치된 패키지들의 정확한 버전과 의존하는 다른 패키지들의 버전 정보를 담고 있습니다. 이 파일을 통해 프로젝트에서 사용되는 패키지들의 버전을 고정시키고, 동일한 버전의 패키지를 여러 컴퓨터나 서버에서 사용할 수 있습니다.

또한 package-lock.json 파일은 다른 개발자들과 협업할 때, 같은 패키지 버전을 사용할 수 있도록 도와줍니다. 이 파일이 없으면 npm install 명령을 실행할 때마다 다른 버전의 패키지를 설치할 수 있으며, 이는 프로젝트의 호환성 문제를 일으킬 수 있습니다.

따라서, package-lock.json 파일은 Node.js 프로젝트에서 중요한 역할을 합니다. 프로젝트를 개발하거나 배포할 때는 이 파일을 함께 제공하여 패키지들의 버전을 일관성 있게 유지하는 것이 좋습니다.

yarn 패키지 매니저는 package-lock.json 대신 yarn.lock 파일을 사용합니다.

node_modules 디렉토리

node_modules 디렉토리는 Node.js 프로젝트에서 사용되는 모듈들을 포함하는 디렉토리입니다. 이 디렉토리는 보통 프로젝트의 루트 디렉토리 내에 위치하며, 프로젝트에서 사용되는 의존 모듈들이 여기에 저장됩니다.

모듈을 import할 때 Node.js는 모듈을 찾기 위해 node_modules 디렉토리를 탐색하며, 해당 모듈이 없는 경우 상위 디렉토리로 올라가면서 탐색합니다. 이러한 방식으로 node_modules 디렉토리를 사용함으로써 모듈의 로딩과 의존성 관리를 간편하게 할 수 있습니다.

node_modules 디렉토리는 npm이나 yarn과 같은 패키지 매니저를 사용하여 프로젝트에서 필요한 모듈들을 설치할 때 생성됩니다. 패키지 매니저는 모듈을 설치할 때 node_modules 디렉토리 내에 해당 모듈과 그 모듈이 의존하는 다른 모듈들을 모두 저장합니다. 이를 통해 프로젝트에서 사용되는 모듈들을 쉽게 관리할 수 있습니다.


6. 비동기 프로그래밍과 콜백

비동기 프로그래밍

비동기 프로그래밍은 순차적으로 실행되는 코드 흐름이 아닌, 병렬적으로 실행되는 코드 흐름을 구현하는 방법입니다.

Node.js의 비동기 실행

Design overview — libuv documentation 참조
Node.js의 비동기 실행은 libuv라는 라이브러리를 통해서 이루어집니다.

Node.js는 단일 스레드로 작동하며, 이는 많은 요청과 동시에 처리해야 하는 I/O 작업이 많은 서버에서 문제가 될 수 있습니다. 따라서 Node.js에서는 메인 스레드에서 이벤트 루프를 실행하는 비동기 프로그래밍을 통해 I/O 작업을 비차단적(non-blocking)으로 처리할 수 있도록 설계되었습니다.

비동기 프로그래밍은 일반적으로 콜백(callback) 함수나 프로미스(promise) 객체, async/await 구문 등을 사용하여 구현됩니다. 이러한 기법들은 비동기적으로 실행되는 함수들을 동기적인 코드처럼 작성할 수 있도록 도와줍니다.

Javascript 동작원리 (Single thread, Event loop, Asynchronous) | by vincent | Medium, 동시성(Concurrency) vs 병렬성(Parallelism) 참조

콜백

콜백(callback)은 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 실행은 동기 콜백에서처럼 즉시 이루어질 수도 있고 비동기 콜백에서처럼 나중에 이루어질 수도 있습니다.

Node.js에서는 비동기적인 작업을 처리할 때, 콜백 함수를 사용하여 작업이 완료되면 해당 함수를 호출합니다. 이를 통해 Node.js는 비동기적인 작업을 비차단적으로 처리할 수 있습니다.


7. 비동기 프로그래밍과 이벤트

이벤트(events) 모듈

Node.js에서 events 모듈은 이벤트 기반(event-driven) 프로그래밍을 구현하기 위한 코어(core) 모듈 중 하나입니다. events 모듈은 이벤트를 생성하고 처리하기 위한 클래스(EventEmitter)를 제공합니다.

EventEmitter 클래스는 이벤트를 발생시키고, 이벤트를 처리하기 위한 콜백 함수들을 등록하고 관리하는 기능을 제공합니다. 즉, EventEmitter 객체를 생성하여 이벤트를 정의하고, 이벤트가 발생했을 때 실행할 콜백 함수를 등록하는 방식으로 이벤트 기반 프로그래밍을 구현할 수 있습니다.

events 모듈은 Node.js의 다른 모듈들과 함께 사용되며, 대표적으로 http, net, fs, stream 등의 모듈에서 이벤트를 사용합니다. 이를 통해 Node.js는 비동기적인 I/O 작업을 처리하고, 이벤트 기반으로 프로그램을 작성할 수 있습니다.

예시

import EventEmitter from 'events';

const myEmitter = new EventEmitter();

myEmitter.on('test', () => {
  console.log('Success!');
});

myEmitter.emit('test');

EventEmitter

Node.js core API는 대부분 비동기적인 이벤트 기반(event-driven) 아키텍처를 일관된 방식으로 구현합니다. EventEmitter 클래스를 사용하여 이벤트를 정의하고, 등록된 콜백 함수(listener)를 실행합니다. 이를 통해 emitter 객체가, 함수 객체 listener를 호출하는 named events를 내보내는(emit) 방식으로 이벤트 기반 프로그래밍을 구현합니다.

Node.js 코어 모듈에서 이벤트를 내보내는(emit) 모든 객체는 EventEmitter 클래스를 상속합니다.

EventEmitter methods

on(eventName, listener)

  • eventName에 지정한 이름의 이벤트가 발생했을 때, 실행할 콜백 함수인 listener를 등록합니다.
  • 이벤트를 여러 번 등록할 수 있습니다.
  • on 메서드는 addListener라는 alias도 내장되어 있습니다.

emit(eventName[, ...args])

  • eventName에 지정한 이름의 이벤트를 발생시킵니다.
  • 이벤트가 발생하면, 등록된 모든 콜백 함수(listener)가 실행됩니다.
  • 이벤트 발생 시에 콜백 함수에 인자를 전달하려면, emit 메서드에 인자를 전달합니다.
  • 인자는 콜백 함수의 인자로 순서대로 전달됩니다.

once(eventName, listener)

  • eventName에 지정한 이름의 이벤트가 최초로 발생했을 때, 한 번만 실행할 콜백 함수(listener)를 등록합니다.
  • 콜백 함수는 이벤트가 발생하면 한 번 실행되고, 이후에는 자동으로 제거됩니다.

listeners(eventName)

  • eventName에 지정한 이름의 이벤트에 등록된 모든 콜백 함수(listener)들을 배열로 반환합니다.
  • 이벤트에 등록된 콜백 함수가 없을 경우, 빈 배열을 반환합니다.

off(eventName, listener)

  • eventName에 지정한 이름의 이벤트에서 등록된 특정 콜백 함수(listener)를 제거합니다.
  • 제거된 콜백 함수는 이후에 실행되지 않습니다.
  • 이벤트에서 제거된 콜백 함수가 없을 경우, 에러가 발생하지 않습니다.
  • 참조할 수 있는 값을 listener 파라미터에 전달해야합니다.

Feedback

  • 싱글 스레드, 코어, 이벤트 루프, 콜 스택, 비동기 실행에 관한 내용을 엮어서 글로 정리하면 좋을 것 같다.

Reference

profile
job's done

0개의 댓글