다음 내용은 인프런에서 공부한 내용을 복습하는 차원에서 기록한 것입니다.
출처 : https://www.inflearn.com/course/%EB%85%B8%EB%93%9C-js-%EA%B5%90%EA%B3%BC%EC%84%9C
💻 3.1 REPL 사용하기
📌 REPL
✏️ 자바스크립트는 스크립트 언어라서 즉석에서 코드를 실행할 수 있음
- REPL이라는 콘솔 제공
- R(Read), E(Evaluate), P(Print), L(Loop)
- 윈도에서는 명령 프롬프트, 맥이나 리눅스에서는 터미널에 node 입력
✏️ 프롬프트가 > 모양으로 바뀌면, 자바스크립트 코드 입력
✏️ 입력한 값의 결괏값이 바로 출력됨
- 간단한 코드를 테스트하는 용도로 적합
- 긴 코드를 입력하기에는 부적합
- console.log()에 대한 출력은 기본적으로 undefined
💻 3.2 JS 파일 실행하기
📌 JS 파일을 만들어 실행하기
✏️ 자바스크립트 파일을 만들어 통째로 코드를 실행하는 방법
- 아무 폴더(디렉터리)에서 helloWorld.js를 만들어보자
- node [자바스크립트 파일 경로]로 실행
- 실행 결괏값이 출력됨
💻 3.3 모듈로 만들기
📌 모듈
✏️ 노드는 자바스크립트 코드를 모듈로 만들 수 있음
- 모듈: 특정한 기능을 하는 함수나 변수들의 집합
- 모듈로 만들면 여러 프로그램에서 재사용 가능
📌 파일 간의 모듈 관계
✏️ node index로 실행
- const { odd, even } 부분은 module.exports를 구조분해 할당한 것임(2장 참고)

📌 this
✏️ 노드에서 this를 사용할 때 주의점이 있음
- 최상위 스코프의 this는 module.exports를 가리킴
- 그 외에는 브라우저의 자바스크립트와 동일
- 함수 선언문 내부의 this는 global(전역) 객체를 가리킴

📌 require의 특성
✏️ 몇 가지 알아둘 만한 속성이 있음
- require가 제일 위에 올 필요는 없음
- require.cache에 한 번 require한 모듈에 대한 캐슁 정보가 들어있음.
- require.main은 노드 실행 시 첫 모듈을 가리킴
📌 ES 모듈
✏️ 자바스크립트 자체 모듈 시스템 문법이 생김
- mjs 확장자를 사용하거나 package.json에 type: “module”을 추가해야 함
- 크게는 require 대신 import, module.exports 대신 export default, exports 대신 export를 쓰는 것으로 바뀜
📌 CommonJS와 ES 모듈의 차이
📌 다이내믹 임포트, top level await
✏️ 코드 중간에 동적으로 불러올 수 있음
- Commonjs에서는 require()
- ES 모듈에서는 import()
✏️ mjs 파일에서 최상위 스코프에선 async 없이 await할 수 있음
📌 filename, dirname
✏️ __filename: 현재 파일 경로
✏️ __dirname: 현재 폴더(디렉터리) 경로
💻 3.4 노드 내장 객체 알아보기
📌 process.env
✏️ 시스템 환경 변수들이 들어있는 객체
- 비밀키(데이터베이스 비밀번호, 서드파티 앱 키 등)를 보관하는 용도로도 쓰임
- 환경 변수는 process.env로 접근 가능
const secretId = process.env.SECRET_ID;
const secretCode = process.env.SECRET_CODE;
- 일부 환경 변수는 노드 실행 시 영향을 미침
- 예시) NODE_OPTIONS(노드 실행 옵션), UV_THREADPOOL_SIZE(스레드풀 개수)
- max-old-space-size는 노드가 사용할 수 있는 메모리를 지정하는 옵션
NODE_OPTIONS = --max-old-space-size=8192
UV_THREADPOLL_SIZE=8
📌 마이크로태스크
✏️ Promise, nextTick 등
- setImmediate, setTimeout보다 promise와 nextTick이 먼저 실행됨
💻 3.5 노드 내장 모듈 알아보기
📌 url 모듈
✏️ 인터넷 주소를 쉽게 조작하도록 도와주는 모듈
- url 처리에 크게 두 가지 방식이 있음(기존 노드 방식 vs WHATWG 방식)
- 요즘은 WHATWG 방식만 사용함 (웹표준 방식으로 통일)
- WHATWG 방식 주소 체계는 다음과 같음
📌 searchParams
✏️ WHATWG 방식에서 쿼리스트링(search) 부분 처리를 도와주는 객체
- ?page=3&limit=10&category=nodejs&category=javascript 부분
📌 searchParams 예제 결과
✏️ getAll(키): 키에 해당하는 모든 값들을 가져옵니다. category 키에는 두 가지 값, 즉 nodejs와 javascript의 값이 들어 있습니다.
✏️ get(키): 키에 해당하는 첫 번째 값만 가져옵니다.
✏️ has(키): 해당 키가 있는지 없는지를 검사합니다.
✏️ keys(): searchParams의 모든 키를 반복기(iterator, ES2015 문법) 객체로 가져옵니다.
✏️ values(): searchParams의 모든 값을 반복기 객체로 가져옵니다.
✏️ append(키, 값): 해당 키를 추가합니다. 같은 키의 값이 있다면 유지하고 하나 더 추가합니다.
✏️ set(키, 값): append와 비슷하지만 같은 키의 값들을 모두 지우고 새로 추가합니다.
✏️ delete(키): 해당 키를 제거합니다.
✏️ toString(): 조작한 searchParams 객체를 다시 문자열로 만듭니다. 이 문자열을 search에 대입하면 주소 객체에 반영됩니다.
📌 dns
✏️ DNS를 다룰 때 사용하는 모듈
- 도메인을 통해 IP나 DNS 레코드를 얻고자 할 때 사용
- A(ipv4 주소), AAAA(ipv6 주소), NS(네임서버), SOA(도메인 정보), CNAME(별칭, 주로 www가 붙은 주소는 별칭인 경우가 많습니다), MX(메일 서버)
📌 단방향 암호화(crypto)
✏️ 암호화는 가능하지만 복호화는 불가능
- 암호화: 평문을 암호로 만듦
- 복호화: 암호를 평문으로 해독
✏️ 단방향 암호화의 대표 주자는 해시 기법
- 문자열을 고정된 길이의 다른 문자열로 바꾸는 방식
- abcdefgh 문자열 -> qvew
📌 Hash 사용하기(sha512)
✏️ createHash(알고리즘): 사용할 해시 알고리즘을 넣어줍니다.
- md5, sha1, sha256, sha512 등이 가능하지만, md5와 sha1은 이미 취약점이 발견되었습니다.
- 현재는 sha512 정도로 충분하지만, 나중에 sha512마저도 취약해지면 더 강화된 알고리즘으로 바꿔야 합니다.
✏️ update(문자열): 변환할 문자열을 넣어줍니다.
✏️ digest(인코딩): 인코딩할 알고리즘을 넣어줍니다.
- base64, hex, latin1이 주로 사용되는데, 그중 base64가 결과 문자열이 가장 짧아 애용됩니다. 결과물로 변환된 문자열을 반환합니다.
📌 pbkdf2
✏️ 컴퓨터의 발달로 기존 암호화 알고리즘이 위협받고 있음
- sha512가 취약해지면 sha3으로 넘어가야함
- 현재는 pbkdf2나, bcrypt, scrypt 알고리즘으로 비밀번호를 암호화
- Node는 pbkdf2와 scrypt 지원
📌 child_process
✏️ 노드에서 다른 프로그램을 실행하고 싶거나 명령어를 수행하고 싶을 때 사용
- 현재 노드 프로세스 외에 새로운 프로세스를 띄워서 명령을 수행함.
- 명령 프롬프트의 명령어인 dir을 노드를 통해 실행(리눅스라면 ls를 대신 적을 것)
✏️ 파이썬 프로그램 실행하기
📌 기타 모듈들
✏️ async_hooks: 비동기 코드의 흐름을 추적할 수 있는 실험적인 모듈입니다.
✏️ dgram: UPD와 관련된 작업을 할 때 사용합니다.
✏️ net: HTTP보다 로우 레벨인 TCP나 IPC 통신을 할 때 사용합니다.
✏️ perf_hooks: 성능 측정을 할 때 console.time보다 더 정교하게 측정합니다.
✏️ querystring: URLSearchParams가 나오기 이전에 쿼리스트링을 다루기 위해 사용했던 모듈입니다.
✏️ string_decoder: 버퍼 데이터를 문자열로 바꾸는 데 사용합니다.
✏️ tls: TLS와 SSL에 관련된 작업을 할 때 사용합니다.
✏️ tty: 터미널과 관련된 작업을 할 때 사용합니다.
✏️ v8: V8 엔진에 직접 접근할 때 사용합니다.
✏️ vm: 가상 머신에 직접 접근할 때 사용합니다.
✏️ wasi: 웹어셈블리를 실행할 때 사용하는 실험적인 모듈입니다.
💻 3.6 파일 시스템 접근하기
📌 fs
✏️ 파일 시스템에 접근하는 모듈
파일/폴더 생성, 삭제, 읽기, 쓰기 가능
웹 브라우저에서는 제한적이었으나 노드는 권한을 가지고 있음
const fs = require('fs');
fs.readFile('./readme.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data);
console.log(data.toString());
});
📌 fs 프로미스
✏️ 콜백 방식 대신 프로미스 방식으로 사용 가능
- require('fs').promises
- 사용하기 훨씬 더 편해서 프로미스 방식을 추천
const fs = require('fs').promises;
fs.readFile('./readme.txt')
.then((data) => {
console.log(data);
console.log(data.toString());
})
.cath((err) => {
console.error(err);
});
📌 fs로 파일 만들기
✏️ 파일을 만드는 예제
- writeFile()로 파일을 생성하고 프로미스에 의해서 then()이 순서대로 실행됨
- 첫 번째 then()에서 return한 값이 두 번째 then()의 data로 전달
const fs = require('fs').promises;
fs.writeFile('./writeme.txt', '글이 입력됩니다.')
.then(() => {
return fs.readFile('./writeme.txt');
})
.then((data) => {
console.log(data.toString());
})
.cath((err) => {
console.error(err);
});
📌 동기 메서드와 비동기 메서드
✏️ 노드는 대부분의 내장 모듈 메서드를 비동기 방식으로 처리
- 비동기는 코드의 순서와 실행 순서가
- 일치하지 않는 것을 의미
- 일부는 동기 방식으로 사용 가능
✏️ 동기와 비동기: 백그라운드 작업 완료 확인 여부
✏️ 블로킹과 논 블로킹: 함수가 바로 return 되는지 여부
✏️ 노드에서는 대부분 동기-블로킹 방식과 비동기-논 블로킹 방식임
📌 비동기 메서드로 순서 유지하기
✏️ 콜백 형식 유지
- 코드가 우측으로 너무 들어가는 현상 발생(콜백 지옥)
✏️ 프로미스로 극복
📌 버퍼와 스트림 이해하기
✏️ 버퍼: 일정한 크기로 모아두는 데이터
- 일정한 크기가 되면 한 번에 처리
- 버퍼링: 버퍼에 데이터가 찰 때까지 모으는 작업
✏️ 스트림: 데이터의 흐름
- 일정한 크기로 나눠서 여러 번에 걸쳐서 처리
- 버퍼(또는 청크)의 크기를 작게 만들어서 주기적으로 데이터를 전달
- 스트리밍: 일정한 크기의 데이터를 지속적으로 전달하는 작업
💻 3.7 이벤트 이해하기
📌 이벤트 만들고 호출하기
✏️ events 모듈로 커스텀 이벤트를 만들 수 있음
- 스트림에 쓰였던 on(‘data’), on(‘end’) 등과 비교
- on(이벤트명, 콜백): 이벤트 이름과 이벤트 발생 시의 콜백을 연결해줍니다. 이렇게 연결하는 동작을 이벤트 리스닝이라고 부릅니다. event2처럼 이벤트 하나에 이벤트 여러 개를 달아줄 수도 있습니다.
- addListener(이벤트명, 콜백): on과 기능이 같습니다.
- emit(이벤트명): 이벤트를 호출하는 메서드입니다. 이벤트 이름을 인자로 넣어주면 미리 등록해뒀던 이벤트 콜백이 실행됩니다.
- once(이벤트명, 콜백): 한 번만 실행되는 이벤트입니다. myEvent.emit('event3')을 두 번 연속 호출했지만 콜백이 한 번만 실행됩니다.
- removeAllListeners(이벤트명): 이벤트에 연결된 모든 이벤트 리스너를 제거합니다.event4가 호출되기 전에 리스너를 제거했으므로 event4의 콜백은 호출되지 않습니다.
- removeListener(이벤트명, 리스너): 이벤트에 연결된 리스너를 하나씩 제거합니다. 역시event5의 콜백도 호출되지 않습니다.
- off(이벤트명, 콜백): 노드 10 버전에서 추가된 메서드로, removeListener와 기능이 같습니다.
- listenerCount(이벤트명): 현재 리스너가 몇 개 연결되어 있는지 확인합니다.
💻 3.8 예외 처리하기
📌 예외 처리
✏️ 예외(Exception): 처리하지 못한 에러
- 노드 프로세스/스레드를 멈춤
- 노드는 기본적으로 싱글 스레드라 스레드가 멈춘다는 것은 프로세스가 멈추는 것
- 에러 처리는 필수
📌 try catch문
✏️ 기본적으로 try catch문으로 예외를 처리
- 에러가 발생할 만한 곳을 try catch로 감쌈
📌 노드 비동기 메서드의 에러
✏️ 노드 비동기 메서드의 에러는 따로 처리하지 않아도 됨
📌 프로미스의 에러
✏️ 프로미스의 에러는 따로 처리하지 않아도 됨
- 버전이 올라가면 동작이 바뀔 수 있음
- catch()를 넣지 않으면 경고 표시가 길게 출력됨
- 그렇기에 then(), catch()형식을 지키는 것을 추천
📌 예측 불가능한 에러 처리하기
✏️ 최후의 수단으로 사용
- 콜백 함수의 동작이 보장되지 않음
- 따라서 복구 작업용으로 쓰는 것은 부적합
- 에러 내용 기록 용으로만 쓰는 게 좋음
📌 프로세스 종료하기
✏️ 윈도우
- netstat -ano | findstr 포트
- taskkill /pid 프로세스아이디 /f