1. REPL과 JS 파일 실행하기
1) REPL
자바스크립트는 스크립트 언언어라서 즉석에서 코드를 실행할 수 있음
- REPL 이라는 콘솔 제공
- Read Evaluate Print Loop
- 맥에서 터미널에 node 입력
- 간단한 코드 테스트 용으로 적합
-> 불편하기 때문에 ~.js
파일 만들고 터미널에서 node 파일명
으로 실행
console.log('Hello')
- console.log 자체의 리턴값은
Undefined
이다
2. 모듈 만들기
- 노드는 자바스크립트 코드를 모듈로 만들 수 있음 -> 재사용성
- 파일 끝에 module.exports로 모듈로 만들 값을 지정
- 다른 파일에서
require(파일 경로)
로 그 모듈의 내용을 가져올 수 있음
- require는 노드에서 제공해주는 함수
require
은 모듈을 가져와서 사용할때 쓰고
module.exports
은 만든 함수를 모듈로 내보낼 때 사용한다 ( 한 파일에서 1번만 쓸 수 있다)
- 노드랑 자바스크립트의 모듈 시스템은 다르다
구조분해할당
3. global과 콘솔, 타이머
노드의 내장 객체
global
- 노드의 전역 객체
- 브라우저의 window와 같은 역할
- 모든 파일에서 접근 가능
- window처럼 생략도 가능(console.require도 global의 속성)
- 원래 console.log도 global.console.log 인데 생략한 것
- global 속성에 값을 대입하면 다른 파일에서도 사용 가능
console 객체
console.time
, console.timeEnd
: 시간 로깅
console.error
: 에러로깅
console.log
: 평범한 로그
console.dir
: 객체 로깅
console.trace
: 호출스택 로깅
set 메서드에 clear 메서드가 대응됨
- set 메서드의 리턴 값(아이디)을 clear 메서드에 넣어 취소
setTimeout(콜백 함수, 밀리초)
: 주어진 밀리초(1000분의 1초)이후에 콜백 함수를 실행
setInterval(콜백 함수, 밀리초)
: 주어진 밀리초마다 콜백 함수를 반복 실행
setImmediate(콜백 함수)
: 콜백 함수를 즉시 실행, setTimeout(A, 0)은 하지말고 setImmediate 쓸것
clearTimouout(아이디)
: setTimeout을 취소
clearInterval(아이디)
: setInterval을 취소
clearImmediate(아이디)
: setImmediate를 취소
4. exports와 this
- 노드는 브라우저와 다르게 우리 컴퓨터에 접근 가능하다 -> 파일 관리 가능
__filename
: 현재 파일 경로
__dirname
: 현재 폴더(디렉토리) 경로
module.exports = { a, b };
= exports.a = a; 이렇게 쓸 수 있음
-> 한가지만 exports 하고 싶을 때는 module.exports = A
-> 두가지 이상을 exports 하고 싶을 때는
export.a = a;
export.b = b;
module.exports = {
a,
b,
}
this
- 보통 자바스크립트에서 this 는 window -> 전역 객체를 가리킴
- node에서는 전역 스코프의 this만 빈 객체가 되고, 함수 안의 this는 global이다
5. 모듈 심화, 순환 참조
require의 특성
- require가 제일 위에 올 필요는 없음
- require.cache에 한 번 require한 모듈에 대한 캐싱 정보가 들어있음
- require.main은 노드 실행 시 첫 모듈을 가리킴
순환 참조
- 두 개의 모듈이 서로를 require 하는 상황을 조심해야 함
6. process
- 현재 실행중인 노드 프로세스에 대한 정보를 담고 있음
process.env
시스템 환경 변수들이 들어있는 객체
- 비밀키(데이터베이스 비밀번호, 서드파티 앱 키 등)를 보관하는 용도로 쓰임
- 환경 변수는 process.env로 접근 가능
- 일부 환경 변수는 노드 실행 시 영향을 미침
예시) NODE_OPTIONS(노드 실행 옵션), UV_THREADPOOL_SIZE(스레드풀 개수)
process.nextTick(콜백)
이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선적으로 처리함
- 너무 남용하면 다른 콜백 함수들 실행이 늦어짐
- 비슷한 경우로 promise가 있음 (nextTick처럼 우선순위가 높음)
ex) 아래 예제에서 setImmediate
, setTimeout
보다 promise와 nextTick이 먼저 실행됨
setImmediate(() => {
console.log('immediate');
});
process.nextTick(() => {
console.log('nextTick');
});
setTimeout(() => {
console.log('timeout');
}, 0);
Promise.resolve().then(() => console.log('promise'));
process.exit()
현재의 프로세스를 멈춤
- 코드가 없거나 0이면 정상 종료
- 이외의 코드는 비정상 종료를 의미함
7. 노드 내장 모듈. os와 path
os -> 운영체제의 정보를 담고 있음
8. url과 querystring
인터넷 주소를 쉽게 조작하도록 도와주는 모듈
- url 처리에 크게 두 가지 방식이 있음( 기존 노드 방식 vs WHATWG 방식 )
- 위 그림에서 가운데 주소를 기준으로 위쪽은 기존 노드 방식, 아래쪽은 WHATWG 방식
searchParams
WHATWG 방식에서 쿼리스트링(search) 부분 처리를 도와주는 객체
searchParams.getAll()
: 모든 키 값들 가져옴
searchParams.get()
: 키에 해당하는 첫 번째 값만 가져옴
searchParams.has()
: 해당 키가 있는지 없는지를 검사
searchParams.keys()
: searchParams의 모든 키를 이터레이터 객체로 가져옴
searchParams.values()
: searchParams의 모든 값을 이터레이터 객체로 가져옴
searchParams.append(키, 값)
: 해당 키를 추가. 같은 키의 값이 있다면 유지하고 하나 더 추가
searchParams.set(키, 값)
: append와 비슷하지만 같은 키의 값들을 모두 지우고 새로 추가
searchParams.delete(키)
: 해당 키를 제거
searchParams.toString()
기존 노드 방식에서는 url querystring을 querystring 모듈로 처리
- querystring.parse(쿼리) : url의 query 부분을 자바스크립트 객체로 분해해줌
- querystring.stringify(객체) : 분해된 query 객체를 문자열로 다시 조립해줌
9. crypto와 util
단반향 암호화(crypto)
Hash 사용하기 (sha512)
- createHash(알고리즘) : 사용할 해시 알고리즘을 넣어줌
- update(문자열) : 변환할 문자열을 넣어줌
- digest(인코딩) : 인코딩할 알고리즘을 넣어줌
pbkdf2
- 컴퓨터의 발달로 기존 암호화 알고리즘이 위협받고 있음
- sha512가 취약해지면 sha3으로 넘어가야함
- bcrypt는 노드에서 지원하지 않음
- 노드는 pbkdf2와 scrypt 지원
양방향 암호화
대칭형 암호화 (암호문 복호화 가능)
- key가 사용됨
- 암호화할 때와 복호화 할 때 같은 key를 사용해야 함
양방향 암호화 메서드
util
각종 편의 기능을 모아둔 모듈
- deprecated 와 promisify가 자주 쓰임
- util.deprecate : 함수가 deprecated 처리되었음을 알려줌
- 첫 번째 인자로 넣은 함수를 사용했을 때 경고 메세지 출력
- 두 번째 인자로 경고 메시지 내용을 넣으면 됨. 함수가 조만간 사라지거나 변경될 때 알려줄 수 있어 유용
- util.promisify : 콜백 패턴을 프로미스 패턴으로 바꿔줌
- 바꿀 함수를 인자로 제공하면 됨. 이렇게 바꿔두면 async/await 패턴까지 사용할 수 있어서 좋음. 단, 콜백이 (error, data) => {} 형식이어야 함
- 3.5.5.1절의 randonBytes와 비교해보자. 프로미스를 콜백으로 바꾸는 util.callbackify도 있지만 자주 사용되지는 않음
deprecated 란?
프로그래밍 용어로, '중요도가 떨어져 더 이상 사용되지 않고 앞으로는 사라지게 될' 이라는 뜻. 새로운 기능이 나와서 기존 기능보다 더 좋을때, 기존 기능을deprecated 처리한다. 이전 사용 기능을 제거하지는 않지만 곧 없앨 예정이므로 더 이상 사용하지 말라는 의미.
10. worker_threads
노드에서 멀티 스레드를 사용하는 방식은 극히 드물고 보통 싱글 스레드로 생각하면 된다.
- isMainThread : 현재 코드가 메인 스레드에서 실행되는지, 워커 스레드에서 실행되는지 구분
- 메인 스레드에서는 new Worker를 통해 현재 파일(__filename)을 워커 스레드에서 실행시킴
- worker.postMessage로 부모에서 워커로 데이터를 보냄
- parentPort.on('message')로 부모로부터 데이터를 받고, postMessage로 데이터를 보냄
11. child_process
-> 노드가 다른 언어를 대신 실행해주는 것이 아니라 그 언어한테 실행을 요청하는 것 ( 해당 언어가 설치되어 있어야 함)
12. 파일 시스템 사용하기 (다시 듣기)
fs
파일 시스템에 접근하는 모듈
- 파일/폴더 생성, 삭제, 읽기, 쓰기 가능
- 웹 브라우저에서는 제한적이었으나 노드는 권한을 가지고 있음
- 파일 읽기 예제 (결과의 버퍼는 뒤에서 설명함)
13. 버퍼와 스트림 이해하기
버퍼 : 일정한 크기로 모아두는 데이터
- 일정한 크기가 되면 한 번에 처리
- 버퍼링 : 버퍼에 데이터가 찰 때까지 모으는 작업. 일정 크기가 되면 그때 전송
스트림 : 데이터의 흐름
- 일정한 크기로 나눠서 여러 번에 걸쳐서 처리
- 버퍼(또는 청크)의 크기를 작게 만들어서 주기적으로 데이터를 전달
- 스트림 : 일정한 크기의 데이터를 지속적으로 전달하는 작업
- 대부분의 경우 스트림이 효율적이다. -> 서버의 메모리를 적게 차지하면서 효율적으로 데이터를 보낼 수 있다. 요청응답도 기본적으로 스트림 방식
14. pipe와 스트림 메모리 효율 확인 (다시 듣기)
15. 스레드풀과 커스텀
- fs, crypto, zlib 모듈의 메서드를 실행할 때는 백그라운드에서 동시에 실행됨 -> 스레드풀이 동시에 처리해줌
16. 에러 처리하기
예외(Exception) : 처리하지 못한 에러
- 자바스크립트에서는 예외랑 에러랑 같다고 보면 됨
- 노드는 기본적으로 싱글스레드라 스레드가 멈춘다는 것은 프로세스가 멈추는 것
- 에러처리는 필수
기본적으로 try catch문으로 예외를 처리
- 에러가 발생할 만한 곳을 try catch로 감쌈
노드 비동기 메서드의 에러는 따로 처리하지 않아도 됨
프로미스의 에러는 따로 처리하지 않아도 됨
최후의 수단으로 사용
- 콜백 함수의 동작이 보장되지 않음
- 따라서 복구 작업용으로 쓰는 것은 부적합
- 에러 내용 기록용으로만 쓰는게 좋음