본문 바로가기

WINK-(Web & App)/Express.js (Node.js) 스터디

[2024 여름방학 Node.js 스터디] 이종윤 #2주차

반응형

REPL(Read Eval Print Loop)

: 노드는 제공하는 콘솔은 입력한 코드를 읽고(Read), 해석하고(Eval), 결과물을 반환하고(Print), 종료할 때까지 반복한다(Loop)고 해서 REPL(Read Eval Print Loop)이라고 한다.

 

모듈

: 특정한 기능을 하는 함수나 변수들의 집합을 말한다.

: 모듈은 자체로도 하나의 프로그램이면서 다른 프로그램의 부품으로도 사용할 수 있다.

보통 위 그림처럼 파일 하나가 모듈 하나가 되며, 파일별로 코드를 모듈화할 수 있어 관리하기 편합니다.

+ 모듈을 만들 때는 모듈이 될 파일과 모듈을 불러와서 사용할 파일이 필요하다.

CommonJS 모듈

: exports나 module.exports와 require()를 사용하는 모듈이다.

우선 exports(var.js)나 module.exports(func.js)를 위 그림처럼 사용해 함수나 객체를 보낼 수 있게 만들고 require(경로)를 사용하여 가져오면 된다.

객체나 함수 모두 가능하고 하나의 파일에 여러가지 모듈을 가져올 수 있다.

ECMAScript 모듈

: 얘가 공식적인 자바스크립트 묘듈 방식이다.

: export나 export default와 import를 사용하는 모듈이다.

위 CommanJS 모듈의 문법을 사용하는 방법은 거의 비슷하다.

 

그리고 위 CommanJS 모듈과 구분되는 ECMAScript 모듈의 특징은 다이내믹 임포트(dynamic import)가 안되고 top level await가 된다는 것이다.

다이내믹 임포트(dynamic import)는 그냥 if문 안에서 require을 넣을 수 있는 것이다. 그래서 ES모듈은 다이나믹 임포트를 쓰기 위해선 import함수를 프로미스로 써야한다.

const a = true;
if (a) {
    const m1 = await import('./func.mjs');
    console.log(m1);
    const m2 = await import('./var.mjs');
    console.log(m2);
}

이렇게

그리고 top level await는 그냥 await를 쓰기 위해서는 async를 쓰고 다음 줄에 들여써서 await를 써야하지만 ES모듈에서는 맨 첫 줄에서는 await를 단독으로 써도 된다.

차이점 CommonJS 모듈 ECMAScript 모듈
문법 require('./a');
module.exports = A;
const A = require('./a');
exports.C = D;
const E = F; exports.E = E;
const { C, E } = require ('./b');
import './a.mjs';
export default A;
import A from './a.mjs';
export const C = D;
const E = F; export { E };
import { C, E } from './b.mjs';
확장자 js
cjs
js(package.json에 type: "module" 필요)
mjs
확장자 생략 가능 불가능
다이내믹 임포트 가능(3.3.3절 참고) 불가능
인덱스(index) 생략 가능(require('./folder')) 불가능(import './folder/index.mjs')
top level await 불가능 가능
__filename, __dirname, require, module.exports, exports 사용 가능(3.3.4절 참고) 사용 불가능(__filename 대신 import.meta.url 사용)
서로 간 호출 가능

노드의 내장객체

: 노드에서 기본적으로 제공하는 내장 객체이다.

global 객체

: global객체는 window와 같은 전역 객체이므로 모든 파일에서 접근할 수 있다.

: window.open 메서드를 그냥 open으로 호출할 수 있는 것처럼 global도 생략할 수 있습니다. 

지금 우리가 써왔던 console도 노드에서는 window 대신 global 객체 안에 들어 있다.

console객체

: console 객체는 보통 디버깅을 위해 사용한다. 개발 중 변수에 값이 제대로 들어 있는지 확인하기 위해 사용하기도 하고, 에러 발생 시 에러 내용을 콘솔에 표시하기 위해서도 사용하며, 코드 실행 시간을 알아보려고 할 때도 사용한다.

메서드 설명 예시
console.time(레이블) console.timeEnd(레이블)과 대응되어 같은 레이블을 가진 time과 timeEnd 사이의 시간을 측정합니다. console.time('test'); /* some code */ console.timeEnd('test');
console.log(내용) 평범한 로그를 콘솔에 표시합니다. 여러 내용을 동시에 표시할 수도 있습니다. console.log('Hello', 'World');
console.error(에러 내용) 에러를 콘솔에 표시합니다. console.error('This is an error message');
console.table(배열) 배열의 요소로 객체 리터럴을 넣으면, 객체의 속성들이 테이블 형식으로 표현됩니다. console.table([{name: 'Alice', age: 30}, {name: 'Bob', age: 25}]);
console.dir(객체, 옵션) 객체를 콘솔에 표시할 때 사용합니다. 첫 번째 인수로 표시할 객체를 넣고, 두 번째 인수로 옵션을 넣습니다. 옵션의 colors를 true로 하면 콘솔에 색이 추가됩니다. console.dir({name: 'Alice', age: 30}, {colors: true, depth: 2});
console.trace(레이블) 에러가 어디서 발생했는지 추적할 수 있게 합니다. 위치가 나오지 않는다면 사용할 만합니다. console.trace('Trace labe

타이머 객체

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

메서드 설명 예시
setTimeout(콜백 함수, 밀리초) 주어진 밀리초(1,000분의 1초) 이후에 콜백 함수를 실행합니다. const id = setTimeout(() => { console.log('Hello'); }, 1000);
setInterval(콜백 함수, 밀리초) 주어진 밀리초마다 콜백 함수를 반복 실행합니다. const id = setInterval(() => { console.log('Hello'); }, 1000);
setImmediate(콜백 함수) 콜백 함수를 즉시 실행합니다. const id = setImmediate(() => { console.log('Hello'); });
clearTimeout(아이디) setTimeout을 취소합니다. clearTimeout(id);
clearInterval(아이디) setInterval을 취소합니다. clearInterval(id);
clearImmediate(아이디) setImmediate를 취소합니다. clearImmediate(id);

process 객체

: process 객체는 현재 실행되고 있는 노드 프로세스에 대한 정보를 담고 있다. (컴퓨터 내 정보에 접근할 수 있다.)

속성/메서드 설명 예시
process.version 설치된 노드의 버전입니다. v18.7.0
process.arch 프로세서 아키텍처 정보입니다. x64
process.platform 운영체제 플랫폼 정보입니다. win32
process.pid 현재 프로세스의 아이디입니다. 14736
process.uptime() 프로세스가 시작된 후 흐른 시간입니다. 단위는 초입니다. 199.36
process.execPath 노드의 경로입니다. C:\Program Files\nodejs\node.exe
process.cwd() 현재 프로세스가 실행되는 위치입니다. C:\Users\zerocho
process.cpuUsage() 현재 CPU 사용량입니다. { user: 390000, system: 203000 }

process.env

: 환경변수(컴퓨터 환경)에 접근 가능하다.

- 일부 환경 변수는 노드 실행시 영향을 미친다.

process.nextTick(콜백)

: 이벤트 루프가 다른 콜백함수보다 우선으로 처리해준다.

- 남용하면 콜백 함수들 실행이 늦어진다.

- 비슷한 예시로 promise가 있다.

process.exit(코드)

: 현재의 프로세스를 멈춘다.

- 코드가 없거나 0이면 정상종료이고, 아니면 비정상종료이다.

내장모듈

: 노드에 내장된 모듈이다.

os

: 웹 브라우저에 사용되는 자바스크립트는 운영체제의 정보를 가져올 수 없지만, 노드는 os 모듈에 정보가 담겨 있어 정보를 가져올 수 있다.

메서드 설명 예시
os.arch() process.arch와 동일합니다. x64
os.platform() process.platform와 동일합니다. win32
os.type() 운영체제의 종류를 보여줍니다. Windows_NT
os.uptime() 운영체제 부팅 이후 흐른 시간(초)을 보여줍니다. process.uptime()은 노드의 실행 시간입니다. 3600
os.hostname() 컴퓨터의 이름을 보여줍니다. my-computer
os.release() 운영체제의 버전을 보여줍니다. 10.0.19042
os.homedir() 홈 디렉터리 경로를 보여줍니다. C:\Users\zerocho
os.tmpdir() 임시 파일 저장 경로를 보여줍니다. C:\Users\zerocho\AppData\Local\Temp
os.cpus() 컴퓨터의 코어 정보를 보여줍니다. [{ model: 'Intel(R) Core(TM) i7', speed: 2900, times: { user: 1000, nice: 0, sys: 500, idle: 2000, irq: 0 } }, ... ]
os.freemem() 사용 가능한 메모리(RAM)를 보여줍니다. 8589934592 (8GB)
os.totalmem() 전체 메모리 용량을 보여줍니다. 17179869184 (16GB)

path

: 폴더와 파일의 경로를 쉽게 조작하도록 도와주는 모듈이다.

메서드 설명 예시
path.sep 경로의 구분자입니다. 윈도는 \, POSIX는 /입니다. \ (윈도) 또는 / (POSIX)
path.delimiter 환경 변수의 구분자입니다. 윈도는 세미콜론(;), POSIX는 콜론(:)입니다. ; (윈도) 또는 : (POSIX)
path.dirname(경로) 파일이 위치한 폴더 경로를 보여줍니다. C:\Users\zerocho
path.extname(경로) 파일의 확장자를 보여줍니다. .txt
path.basename(경로, 확장자) 파일의 이름(확장자 포함)을 표시합니다. 파일의 이름만 표시하고 싶다면 두 번째 인수로 확장자를 넣습니다. file.txt (확장자 포함), file (확장자 제외)
path.parse(경로) 파일 경로를 root, dir, base, ext, name으로 분리합니다. { root: 'C:\\', dir: 'C:\\Users\\zerocho', base: 'file.txt', ext: '.txt', name: 'file' }
path.format(객체) path.parse()한 객체를 파일 경로로 합칩니다. C:\Users\zerocho\file.txt
path.normalize(경로) /나 \를 실수로 여러 번 사용했거나 혼용했을 때 정상적인 경로로 변환합니다. C:\Users\zerocho\file.txt
path.isAbsolute(경로) 파일의 경로가 절대경로인지 상대경로인지를 true나 false로 알립니다. true (절대경로), false (상대경로)
path.relative(기준경로, 비교경로) 경로를 두 개 넣으면 첫 번째 경로에서 두 번째 경로로 가는 방법을 알립니다. ..\another\path
path.join(경로, …) 여러 인수를 넣으면 하나의 경로로 합칩니다. 상대경로인 .. (부모 디렉터리)과 . (현 위치)도 알아서 처리합니다. C:\Users\zerocho\file.txt
path.resolve(경로, …) path.join()과 비슷하지만, 모든 경로를 절대경로로 변환하여 반환합니다. C:\Users\zerocho\file.txt (절대경로로 변환)

 

url

: 인터넷 주소를 쉽게 조작하도록 도와주는 모듈이다.

- url 처리에는 크게 두 가지 방식이 있다. WHATWG(웹 표준을 정하는 단체의 이름) 방식의 url이고, 기존 노드에서 사용하던 방식의 url이다. 

WHATWG(웹 표준을 정하는 단체의 이름) 방식의 체계

메서드 설명 예시
getAll(키) 키에 해당하는 모든 값을 가져옵니다. category 키에는 nodejs와 javascript라는 두 가지 값이 들어 있습니다. ['nodejs', 'javascript']
get(키) 키에 해당하는 첫 번째 값만 가져옵니다. nodejs
has(키) 해당 키가 있는지 없는지를 검사합니다. true (키가 존재할 경우), false (키가 없을 경우)
keys() searchParams의 모든 키를 반복기(iterator) 객체로 가져옵니다. Iterator { 'category', 'type' }
values() searchParams의 모든 값을 반복기 객체로 가져옵니다. Iterator { 'nodejs', 'javascript' }
append(키, 값) 해당 키를 추가합니다. 같은 키의 값이 있다면 유지하고 하나 더 추가합니다. category=nodejs&category=javascript
set(키, 값) append와 비슷하지만 같은 키의 값들을 모두 지우고 새로 추가합니다. category=javascript
delete(키) 해당 키를 제거합니다. category 키 삭제
toString() 조작한 searchParams 객체를 다시 문자열로 만듭니다. 이 문자열을 search에 대입하면 주소 객체에 반영됩니다. category=javascript&type=backend

cryto

: 다양한 방식의 암호화를 도와주는 모듈이다.

단방향 암호화

: 단방향 암호화란 복호화할 수 없는 암호화 방식을 뜻한다.

: 복호화할 수 없으므로 암호화라고 표현하는 대신 해시 함수라고 부르기도 한다.

: 단방향 암호화 알고리즘은 주로 해시 기법을 사용한다. (* 해시 기법이란 어떠한 문자열을 고정된 길이의 다른 문자열로 바꿔버리는 방식입니다.)

양방향 암호화

: 암호화된 문자열을 복호화할 수 있으며, 키(열쇠)라는 것이 사용된다.

: 대칭형 암호화에서는 암호를 복호화하려면 암호화할 때 사용한 키와 같은 키를 사용해야 한다.

메서드 설명 예시
crypto.createCipheriv(알고리즘, 키, iv) 암호화 알고리즘과 키, 초기화 벡터(iv)를 설정합니다. AES-256-CBC의 경우, 키는 32바이트, iv는 16바이트여야 합니다. crypto.createCipheriv('aes-256-cbc', key, iv)
cipher.update(문자열, 인코딩, 출력 인코딩) 암호화할 데이터와 인코딩, 출력 인코딩을 지정합니다. 일반적으로 입력 문자열은 utf8, 출력 결과는 base64 사용합니다. cipher.update('plain text', 'utf8', 'base64')
cipher.final(출력 인코딩) 암호화가 완료된 후, 출력 인코딩을 지정하여 최종 결과를 얻습니다. cipher.final('base64')
crypto.createDecipheriv(알고리즘, 키, iv) 복호화할 때 사용합니다. 암호화 시 사용한 알고리즘, 키, iv와 동일해야 합니다. crypto.createDecipheriv('aes-256-cbc', key, iv)
decipher.update(문자열, 인코딩, 출력 인코딩) 암호화된 데이터와 인코딩, 복호화 결과의 인코딩을 지정합니다. 암호화 시 utf8, base64로 했으면 복호화 시에는 base64, utf8로 지정합니다. decipher.update('encrypted text', 'base64', 'utf8')
decipher.final(출력 인코딩) 복호화가 완료된 후, 출력 인코딩을 지정하여 최종 복호화 결과를 얻습니다. decipher.final('utf8')

fs 모듈

: 파일 시스템에 접근하는 모듈, 즉, 파일을 생성하거나 삭제하고, 읽거나 쓸 수 있으며 폴더도 만들거나 지울 수도 있다.

동기 메서드와 비동기 메서드

: setTimeout 같은 타이머와 process.nextTick 외에도, 노드는 대부분의 메서드를 비동기 방식으로 처리한다. 하지만 몇몇 메서드는 동기 방식으로도 사용할 수 있다. 특히 fs 모듈이 그러한 메서드를 많이 갖고 있다.

 동기와 비동기: 백그라운드 작업 완료 확인 여부

 블로킹과 논블로킹: 함수가 바로 return되는지 여부

버퍼와 스트림

: 파일을 읽거나 쓰는 방식에는 크게 두 가지 방식, 즉 버퍼를 이용하거나 스트림을 이용하는 방식이 있다.

버퍼링은 영상을 재생할 수 있을 때까지 데이터를 모으는 동작이고, 스트리밍은 방송인의 컴퓨터에서 시청자의 컴퓨터로 영상 데이터를 조금씩 전송하는 동작이다.

또한 스트리밍하는 과정에서 버퍼링을 할 수도 있다. 전송이 너무 느리면 화면을 내보내기까지 최소한의 데이터를 모아야 하고, 영상 데이터가 재생 속도보다 빨리 전송되어도 미리 전송받은 데이터를 저장할 공간이 필요하기 때문이다.

Buffer 객체

: 노드는 파일을 읽을 때 메모리에 파일 크기만큼 공간을 마련해두며 파일 데이터를 메모리에 저장한 뒤 사용자가 조작할 수 있도록 한다. 이때 메모리에 저장된 데이터가 바로 버퍼다.

메서드 설명
Buffer.from(문자열) 문자열을 버퍼로 변환합니다. length 속성은 버퍼의 크기를 바이트 단위로 알려줍니다.
buffer.toString(인코딩) 버퍼를 문자열로 변환합니다. base64나 hex와 같은 인코딩 방식을 지정하여 변환할 수도 있습니다.
Buffer.concat(배열) 배열 안에 있는 버퍼들을 하나로 합칩니다.
Buffer.alloc(바이트) 빈 버퍼를 생성합니다. 지정한 바이트 크기의 버퍼가 생성됩니다.

스트리밍 객체

: 버퍼의 크기를 작게 만들고 여러 번에 걸쳐 나눠 보내는 방식이 스트리밍이다. 

반응형