상세 컨텐츠

본문 제목

[Node.js 1] 1장 ~ 3장 노드 시작하기

23-24/Node.js 1

by Hetbahn 2023. 10. 13. 10:00

본문

728x90

 

 

 

 

 

 

알아둬야 할 자바스크립트

 

 

  • ES2015+

1. const, let

- var로 선언한 변수는 함수 스코프를 가지므로 블록과 관계없이 접근 가능하다. 하지만 const와 let은 블록 스코프를 가지므로 블록 밖에서는 변수에 접근이 불가능하다.

- const로 선언한 변수는 값을 한 번 할당하면 값 변경이 불가능하다. 따라서 const로 선언한 변수를 상수라 부르기도 한다.

- 변수 선언 시에는 기본적으로 const를 사용하고, 변수의 값 초기화 이후 값을 변경해야 하는 경우에만 let을 사용한다.

 

2. 템플릿 문자열

- 백틱(`)으로 문자열을 감싸 표현한다.

- `${변수}는 변수입니다.` 와 같이 ${ } 형식으로 변수의 값을 문자열에 삽입할 수 있다.

 

3. 객체 리터럴

- 객체의 메서드에 함수를 연결할 때, 콜론(:)과 function을 붙이지 않아도 된다.

- 객체의 속성명과 변수명이 동일할 때, 속성명(변수명)을 한 번만 입력해도 된다.

 

4. 화살표 함수

- const 함수 = (매개 변수) => {반환값}와 같이 함수를 선언할 수 있다.

- 화살표 함수 내부에 return문밖에 없는 경우, return을 생략할 수 있다.

- 기존의 function 선언문과는 달리, 화살표 함수 내부에서 this 키워드로 상위 스코프의 this를 사용할 수 있다.

 

5. 구조 분해 할당

- 객체의 속성을 변수에 대입할 때 속성명과 변수명이 같으면 코드를 축약하여 표현할 수 있다.

const candyMachine = {
    status: {
    	count: 5,
    },
    getCandy() {
    	return this.status.count;
    },
};

const { getCandy, status: { count } } = candyMachine;

- 위 코드를 실행하면 getCandy에 candyMachine.getCandy 함수가, count에 candyMachine.status.count 변수가 대입된다.

 

6. 클래스

- 기존의 프로토타입 상속 코드의 문법을 클래스 문법으로 작성할 수 있다.

- 하지만 클래스 문법으로 작성해도 자바스크립트는 여전히 클래스 기반이 아닌 프로토타입 기반으로 동작한다.

 

7. 프로미스

- 프로미스 객체를 생성한다.

- 프로미스 객체의 인수로 콜백 함수를 넘기는데, 이 콜백 함수는 resolve와 reject를 매개변수로 갖는다.

- resolve가 호출되면 프로미스 객체의 then 메서드가 실행되고, reject가 호출되면 catch 메서드가 실행된다. (에러가 발생했을 때 reject를 호출한다.)

- then 메서드에서 프로미스 객체를 리턴하고 then 메서드 뒤에 then 메서드를 붙이면 앞의 then 메서드가 수행된 이후 뒤의 then 메서드가 수행된다. (콜백 함수를 중첩하지 않아도 코드를 순차적으로 실행할 수 있다.)

 

8. async/await

- async function으로 함수를 선언하고 함수 내부의 프로미스 앞에 await을 붙인다.

- then 메서드를 사용할 필요 없이 코드를 순차적으로 실행할 수 있다.

- 예외를 처리하기 위해 정상적으로 수행될 문장들은 try문으로 감싸고, 에러가 발생할 경우 catch문으로 감싼 문장들이 실행된다.

 

9. Map/Set

- Map은 객체와 유사하다. 문자열이 아닌 값을 키 값으로 사용 가능하며, size 메서드로 속성의 개수를 알 수 있다.

- Set을 배열과 유사하다. 요소의 중복을 허용하지 않는다.

 

10. 널 병합/옵셔널 체이닝

-??(널 병합) 연산자는 || 연산자 대용으로 사용되며, falsy값 중 null과 undefined만 구분한다.

-?.(옵셔널 체이닝) 연산자는 null이나 undefined인 속성, 메서드, 배열 요소를 조회할 때 에러가 발생하는 것을 막는다.

 

 

  • 프론트엔드 자바스크립트

1. AJAX

- 웹 사이트에서 페이지 전환 없이 서버에 요청을 보내고 응답을 받을 수 있는 기술이다.

- jQuery나 axios와 같은 라이브러리를 이용하여 AJAX 요청을 보낸다.

- HTML 파일의 <script> 태그 내에서 axios.get함수와 axios.post함수를 이용하여 GET과 POST 방식의 요청을 보낼 수 있다.

 

2. FormData

- FormData 객체를 생성하고 append 메서드를 이용하여 키-값 형식의 데이터를 저장할 수 있다.

- axios를 이용하여 폼 데이터를 서버에 보낼 수 있다.

 

3. encodeURIComponent, decodeURIComponent

- URL 주소에 한글이 들어갈 경우, 서버가 한글로 된 주소를 인식하지 못하는 경우가 있다. 이때 한글 주소를 처리하기 위해 encodeURIComponent와 decodeURIComponent 메서드를 사용한다.

- 주소의 한글 부분만 encodeURIComponent('한글주소')와 같이 메서드를 사용하면 변환된 문자열로 반환된다.

- 변환된 문자열을 서버에 보내면 decodeURIComponent('변환된 한글주소')와 같이 메서드를 사용하면 원래의 한글 주소가 반환된다.

 

4. 데이터 속성과 dataset

- 프론트엔드에 내려보낸 데이터를 저장하는 공식적인 방법은 데이터 속성이다. (보안과 관련된 데이터는 프론트엔드에 내려보내지 않도록 주의한다.)

- HTML 태그에 data-로 시작하는 속성을 넣는다. 이 속성들은 화면에는 나타나지 않는다.

<ul>
  <li data-id="1" data-user-job="programmer">Zero</li>
</ul>
<script>
  console.log(document.querySelector('li').dataset);
  // { id: '1', userJob: 'programmer' }
</script>

- 위 예시 코드와 같이 자바스크립트에서 dataset 속성을 이용하여 데이터 속성에 쉽게 접근할 수 있다.

 

 

 


 

 

노드 기능 알아보기 (1)

 

 

  • REPL 사용하기

- REPL은 노드의 콘솔이며, 코드를 읽고(Read), 해석하고(Eval), 결과를 반환하고(Print), 종료할 때까지 반복한다.(Loop)

- 콘솔에서 node를 입력하여 REPL을 실행할 수 있다.

 

 

 

  • JS 파일 실행하기

 - 콘솔에서 node [JS 파일 경로]를 입력하여 노드를 통해 JS 파일을 실행할 수 있다.

 

 

 

  • 모듈로 만들기

- 브라우저의 자바스크립트와는 달리, 노드는 코드를 모듈로 만들 수 있다.

- 모듈이란 특정한 기능을 하는 함수나 변수의 집합을 뜻한다. 모듈은 프로그램이면서, 다른 프로그램의 부품으로 사용될 수 있다.

- 보통 JS 파일 하나가 하나의 모듈이 된다.

 

1. CommonJS 모듈

- 모듈을 만들 때는 모듈이 될 파일과 모듈을 불러올 파일이 필요하다.

// var.js

const odd = 'CJS 홀수입니다';
const even = 'CJS 짝수입니다';

module.exports = {
  odd,
  even,
};

- var.js에서 module.exports에 객체를 대입한다. var.js파일은 모듈로서 기능하며, var.js를 참조하는 파일에서 module.exports에 대입된 값을 사용할 수 있다.

- module 객체를 사용하지 않고 exports 객체를 사용해도 모듈을 만들 수 있다. 각각의 변수를 exports 객체에 대입하면 동일하게 동작한다. (module.exports와 exports는 같은 객체를 참조한다.)

 

// func.js

const { odd, even } = require('./var');

function checkOddOrEven(num) {
  if (num % 2) { // 홀수이면
    return odd;
  }
  return even;
}

module.exports = checkOddOrEven;

- func.js에서 var.js를 참조하기 위해 require 함수의 인자로 참조할 파일(모듈)의 경로를 적는다.

 

// index.js

const { odd, even } = require('./var');
const checkNumber = require('./func');

function checkStringOddOrEven(str) {
  if (str.length % 2) { // 홀수이면
    return odd;
  }
  return even;
}

console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));

- index.js에서 var.js와 func.js 파일을 모두 참조한다.

 

// 콘솔

$ node index
CJS 짝수입니다
CJS 홀수입니다

- 콘솔에서 노드를 통해 index.js 파일을 실행하면 위와 같은 결과가 출력된다.

- require 함수가 반드시 파일 최상단에 위치하지 않아도 된다. 또한 module.exports에 대입하는 문장도 파일 최하단에 위치하지 않아도 된다.

- 두 모듈이 서로를 require 할 때는 순환 참조가 발생할 수 있다. 순환 참조가 발생하면 module.exports가 빈 객체가 된다.

 

2. ECMAScript 모듈

- ES 모듈이라고도 불린다.

// var.mjs

export const odd = 'MJS 홀수입니다';
export const even = 'MJS 짝수입니다';

 

// func.mjs

import { odd, even } from './var.mjs';

function checkOddOrEven(num) {
  if (num % 2) { // 홀수이면
    return odd;
  }
  return even;
}

export default checkOddOrEven;

 

// index.mjs

import { odd, even } from './var.mjs';
import checkNumber from './func.mjs';

function checkStringOddOrEven(str) {
  if (str.length % 2) { // 홀수이면
    return odd;
  }
  return even;
}

console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));

 

// 콘솔

$ node index.mjs
MJS 짝수입니다
MJS 홀수입니다

- CommonJS 모듈로 작성한 코드를 ES 모듈로 변경한 코드이다.

- import, export default는 객체가 아닌 문법이다.

- 파일의 확장자가. js가 아닌. mjs이다.

 

3. 다이내믹 임포트

- 조건문을 사용하여 조건에 따라 모듈을 불러오는 것을 다이내믹 임포트라 한다.

- ES 모듈은 조건문 안에서 불러오는 것이 불가능하다.

- ES 모듈은 await import('mjs파일 경로')와 같이 import 함수를 사용하여 다이내믹 임포트를 할 수 있다. import 함수는 프로미스 객체를 반환하기 때문에 await 또는 then을 붙여야 한다.

 

4. __filename, __dirname

- __filename은 파일의 이름을, __dirname은 현재 파일의 경로를 나타낸다.

- ES모듈에서는 __filename과 __dirname을 사용할 수 없다. 대신 import.meta.url로 경로를 나타낼 수 있다.

 

 

 

  • 노드 내장 객체 알아보기

1. global

- 전역 객체이므로 모든 파일에서 접근이 가능하다.

- global.require, global.console 등 다양한 속성이 있으며, global. 은 생략이 가능하다.

- 어떤 파일에서 global.message에 대입한 값을 다른 파일에서 접근이 가능하다.

 

2. console

- console.time(레이블): console.timeEnd(레이블)과 대응되어 같은 레이블을 가진 time과 timeEnd 사이의 시간을 측정한다.

- console.log(내용): 로그를 콘솔에 표시한다.

- console.error(에러 내용): 에러를 콘솔에 표시한다.

- console.table(배열): 객체 리터럴 배열을 넣으면 객체의 속성들이 테이블 형식으로 표현된다.

- console.dir(객체, 옵션): 객체를 콘솔에 표시할 때 사용한다. 첫 번째 인수로 표시할 객체를 넣고, 두 번째 인수로 옵션을 넣는다. 옵션의 colors를 true로 하면 콘솔에 색이 추가된다. depth는 객체 안의 객체를 몇 단계까지 보여줄지를 설정한다. 기본값은 2이다.

- console.trace(레이블): 에러가 어디서 발생했는지 추적할 수 있다.

 

3. 타이머

- setTimeout(콜백 함수, 밀리초): 주어진 밀리초 이후에 콜백 함수를 실행한다.

- setInterval(콜백 함수, 밀리초): 주어진 밀리초마다 콜백 함수를 반복 실행한다.

- setImmediate(콜백 함수): 콜백 함수를 즉시 실행한다.

- 위 타이머 함수들은 모두 아이디를 반환한다. 아이디를 사용하여 타이머를 취소할 수 있다.

- clearTimeout(아이디): setTimeout을 취소한다.
- clearInterval(아이디): setInterval을 취소한다.
- clearImmediate(아이디): setImmediate를 취소한다.

 

4. process

- process 객체는 현재 실행되고 있는 노드 프로세스에 대한 정보를 담고 있다.

// 콘솔

$ node
> 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()
{ user: 390000, system: 203000 } // 현재 cpu 사용량이다.

 

4.1. process.env

NODE_OPTIONS=--max-old-space-size=8192
UV_THREADPOOL_SIZE=8

- 시스템의 환경 변수를 출력한다.

- NODE_OPTIONS는 노드를 실행할 때의 옵션들을 입력받는 환경 변수이고, --max-old-space-size=8192는 노드의 메모리를 8GB까지 사용할 수 있게 한다.

- UV_THREADPOOL_SIZE는 노드에서 기본적으로 사용하는 스레드 풀의 스레드 개수를 조절할 수 있게 한다.

- process.env는 중요한 키를 저장하는 공간으로도 사용된다. 중요한 비밀번호와 같은 정보는 process.env의 속성으로 대체한다.

 

4.2. process.nextTick(콜백)

- 이벤트 루프가 다른 콜백 함수들보다 nextTick의 콜백 함수를 우선으로 처리하도록 만든다.

// nextTick.js

setImmediate(() => {
  console.log('immediate');
});
process.nextTick(() => {
  console.log('nextTick');
});
setTimeout(() => {
  console.log('timeout');
}, 0);
Promise.resolve().then(() => console.log('promise'));

 

// 콘솔

$ node nextTick
nextTick
promise
timeout
immediate

- process.nextTick은 setImmediate나 setTimeout보다 먼저 실행된다. (resolve 된 Promise도 nextTick처럼 다른 콜백들보다 우선시된다.)

- process.nextTick과 Promise를 마이크로태스크(microtask)라고 구분하여 부른다.

 

4.3. process.exit(코드)

- 실행 중인 노드 프로세스를 종료한다. 서버 환경에서 이 함수를 사용하면 서버가 멈추므로 서버에서 잘 사용하지 않는다.

- 인수를 주지 않거나 0을 주면 정상 종료를 뜻하고, 1을 주면 비정상 종료를 뜻한다.

 

 

 


 

빈칸 채우기 문제 - (빈칸을 드래그해서 답을 확인해 보세요)

 

1. resolve가 호출되면 프로미스 객체의 (  then  ) 메서드가 실행되고, reject가 호출되면 (  catch  ) 메서드가 실행된다.

2. FormData 객체를 생성하고 (  append  ) 메서드를 이용하여 키-값 형식의 데이터를 저장할 수 있으며, (  axios  )를 이용하여 폼 데이터를 서버에 보낼 수 있다.

3. 프론트엔드에 내려보낸 데이터를 저장하는 공식적인 방법은 (  데이터 속성  )이다. HTML 태그에 (  data-  )로 시작하는 속성을 넣는다. 자바스크립트에서 (  dataset  ) 속성을 이용하여 데이터 속성에 쉽게 접근할 수 있다.

4. 모듈이란 특정한 기능을 하는 (  함수  )나 (  변수  )의 집합을 뜻한다. 모듈은 프로그램이면서, 다른 프로그램의 부품으로 사용될 수 있다.

5. 두 모듈이 서로를 require 할 때는 (  순환 참조  )가 발생할 수 있다. (  순환 참조  )가 발생하면 module.exports가 빈 객체가 된다.

6. (  __filename  )은 파일의 이름을, (  __dirname  )은 현재 파일의 경로를 나타낸다. ES모듈에서는 (  import.meta.url  )로 경로를 나타낼 수 있다.

7. process.nextTick와 Promise setImmediate나 setTimeout보다 먼저 실행된다. 따라서 process.nextTick과 Promise를

(  마이크로태스크  )라고 구분하여 부른다.

 

 

코드 문제 

 

 1. 다음 코드의 실행 결과 콘솔에 { id: '1234', name: 'gildong' }를 출력하도록 <li> 태그에 알맞은 속성을 추가하여 코드를 수정하시오.

<ul>
  <li>Hi!</li> // li 태그에 속성을 추가
</ul>
<script>
  console.log(document.querySelector('li').dataset);
  // { id: '1234', name: 'gildong' } 출력
</script>

 답 :

더보기

<ul>
  <li data-id="1234" data-name="gildong">Hi!</li>
</ul>
<script>
  console.log(document.querySelector('li').dataset);
</script>

(더보기로 확인)

 

 

 

2. 타이머 객체를 이용하여 다음 코드가 1초 간격으로 문자열을 출력하도록 수정하시오.

setTimeout(() => {
  console.log('1초 지남');
}, 1000);
setTimeout(() => {
  console.log('1초 지남');
}, 1000);
setTimeout(() => {
  console.log('1초 지남');
}, 1000);

답:

더보기

setInterval(() => {
    console.log('1초 지남');
}, 1000);

(더보기로 확인)

 


출처: 조현영 ,  『Node.js 교과서』 개정판 3판, 길벗, 1.4장 ~ 3.4장

Node.js #1

Editor : 호박

728x90

관련글 더보기