본문 바로가기

4. Node.js | React.js

4/17(월) IT K-DT(33일차) / 1.개요~6.module

 

0. Node.js에 들어가기 전

 

* Node.js 교육 간 사용할 에디터 : Visual Studio Code

교육에 사용할 폴더를 드래그해서 바탕화면 아이콘에 드롭하여 실행.

 

 

* Node.js 다운로드

https://nodejs.org/ko/download

 

다운로드 | Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

 

LTS Windows Installer 선택 후 다운로드

LTS: 실무에 사용함에 있어 '가장 안정적인 버전'을 의미.

 

 

설치 간 따로 지정해야 할 옵션은 없음.

 

 

설치 후, 명령 프롬프트에 ' node -v ' 를 입력하여 정상적인 node.js 프로그램 설치 여부 확인.

 

 

* Node.js 교육 간 참고한 강의

https://opentutorials.org/module/3549

 

Node.js

수업소개 이 수업은 JavaScript를 이용해서 Node.js를 제어해 동적으로 HTML 코드를 생성하는 웹애플리케이션을 만드는 방법에 대한 수업입니다.  수업대상 예를들어 1억개의 페이지로 이루어진 웹사

opentutorials.org

 

 

 

* VS Code 내부에서 터미널 기능 적용 방법

 

1. '고급 시스템 설정 보기' 검색 후 클릭

    '시스템 속성'에서 '환경 변수' 클릭

 

2. '시스템변수'에서 '새로만들기' 클릭 후 해당 내용 작성.

(변수 값으로 지정할 디렉토리 경로는 node.js를 설치한 경로를 이용)

 

* 변수 이름: path

* 변수 값: C:\Program Files\nodejs

 

 

3. VS Code 종료 후 재실행

하단 터미널탭에서 PowerShell에서 Command Prompt 변경 후 사용

 

 

(출처: https://oyounghyun.tistory.com/101)

 


1. Node.js의 개요

 

1-1. Node.js의 역사

2009년  'JavaScript로 프론트와 백엔드를 모두 구성하면 하나의 언어로 풀스택을 구성할 수 있지 않을까?' 라는 생각에서 시작.

 

1-2. Node.js의 특징

Node.js는 오픈 소스 JavaScript 엔진인 크롬 V8에 비동기 이벤트 처리 라이브러리인 libuv를 결합한 플랫폼. 
다시 말해, JavaScript로 브라우저 밖에서 서버를 구축하는 등의 코드를 실행할 수 있게 해주는 런타임 환경.

(원래는 브라우저 안에서만 사용할 수 있었음!)

browser에서는 DOM APIs, Network APIs, Audio/Video APIs, Storage APIs 등의 API를 사용할 수 있고,
Node.js에서는 Console, Crypto, HTTP, File, OS 등과 관련된 API를 사용할 수 있음.

전세계 50%의 점유율로 가장 많이 사용하는 언어(플랫폼)로 선정(2021, 스택오버플로우 조사)
국가 및 다양한 회사에서 node.js에 대한 능력을 많이 요구함.
(넷플릭스, 우버, 이베이, 페이팔, 쿠팡, 네이버, 카카오톡 등의 회사에서 node.js를 서버로 두고 있음.)

 

Node의 4가지 포인트:
   1. JavaScript Runtime →  속도가 빠름.

   2. Single Thread  →  동시에 여러 작업의 처리를 하지 않음.

   3. Non-Blocking I/O  →  비동기 작업이 가능.

   4. Event-Driven → 이벤트가 발생하면 그에 따른 동작을 취하도록 설계됨.


JavaScript Runtime 환경의 특징:
JavaScript 엔진을 사용. 오픈소스 및 c++기반. performance가 높아 속도가 빠름.

 


    Thread(쓰레드): 
    프로세스(process) 내에서 실제로 작업을 수행하는 주체.

    싱글 스레드(Single Thread)는, 하나의 프로세스 내에서 동시에 실행되는 스레드가 하나뿐인 것을 의미. 
    이러한 실행 방식에서는 프로세스 내에서 하나의 작업이 완료될 때까지 다른 작업이 실행될 수 없음. 

    반면 멀티 스레드(Multi-Thread)는 여러 개의 스레드가 동시에 실행되므로, 
    한 스레드에서 작업을 수행하는 동안 다른 스레드에서는 다른 작업을 수행할 수 있음.

    Non-Blocking I/O(논블로킹 I/O):
    입출력 작업을 처리할 때 블로킹(Blocking)되는 것을 방지하기 위한 방법 중 하나. 
    블로킹(Blocking)은 입출력 작업이 완료될 때까지 해당 스레드에서는 다른 작업을 수행할 수 없는 상태를 의미. 
    이러한 블로킹을 피하기 위해 논블로킹 I/O는 입출력 작업이 완료되기 전에 다른 작업을 처리할 수 있도록 함.

 

Single Thread와 Non-Blocking I/O를 함께 사용하는 경우 모순적으로 보일 수 있으나,

Single Thread에서 작업을 처리하면서 입출력 작업의 Non-Blocking 처리가 가능함. 

이를 통해, 멀티 스레드를 사용하지 않으면서도 다수의 클라이언트 요청을 동시에 처리할 수 있음.
→ 높은 처리량과 낮은 지연 시간이 특징인 웹 어플리케이션의 개발이 가능.

 


 Event-Driven(이벤트-드리븐):
 프로그램에서 발생하는 이벤트에 따라 동작하는 방식을 의미. 
 이벤트는 일종의 신호로, 예를 들어 사용자가 '마우스를 클릭'하거나 '키보드를 누르는' 등의 작업을 수행할 때 발생할 수 있음.
 Event-Driven 방식은 이러한 이벤트를 기다리고, 이벤트가 발생하면 그에 따른 동작을 취하도록 설계됨. 

 이벤트는 일반적으로 큐(queue)나 스택(stack)과 같은 자료구조에 저장되며, 이벤트 루프(event loop)를 사용하여 처리됨.
 예를 들어, 웹 애플리케이션에서는 사용자가 버튼을 클릭하면 해당 버튼의 클릭 이벤트가 발생. 
 이 이벤트에 대한 이벤트 핸들러는 이벤트 루프에서 처리되어, 버튼을 클릭한 사용자에게 응답하거나 다른 동작을 수행. 

 Event-Driven 방식은 비동기(asynchronous) 동작을 가능하게 하여, 여러 이벤트가 동시에 발생하는 경우에도 처리할 수 있음. 
 또한 Event-Driven 아키텍처는 확장성과 유연성이 뛰어나며, 실시간성이 중요한 시스템에서 많이 사용.

 

2. global

전역 객체(global object)를 나타내는 변수.

Node.js에서 사용할 수 있는 내장 함수와 객체들이 포함되어 있음.

 

global 객체는 어디에서나 접근할 수 있으며,

일반적으로 모듈 내부에서는 전역 객체에 속한 함수나 객체를 직접 호출하지 않고,

이들을 모듈로 가져와서 사용.

전역 객체는 Node.js에서 사용하는 기본 모듈을 포함하여, 사용자가 직접 정의한 전역 변수나 함수 등을 포함.

예를 들어, console 객체, process 객체, setTimeout() 함수, setInterval() 함수 등이 global 객체에 속함.

전역 객체는 모든 모듈에서 공유되기 때문에,

전역 객체에 속한 함수나 객체를 다른 모듈에서 사용할 때 의도치 않은 결과를 초래할 수 있음.

따라서 모듈 내부에서 전역 객체를 사용하는 것은 권장되지 않음.

 

global에 hello()라는 메서드를 생성하여 'hello'를 출력.  (둘 중 하나를 선택해서 사용할 수 있음.)


 global.hello = () => {
    console.log('hello');

 };


 global.hello();
 hello();            // windows.alert에서 windows를 생략한 것 처럼 global도 생략이 가능하다.

cmd에서 해당 코드가 존재하는 파일의 이름을 이용하여 ' node 1-global '라고 입력. → 코드의 출력이 가능.

 (현재 해당 코드가 위치하는 파일의 이름은 1-global.js임)

 

3. console

콘솔 출력을 관리하는 객체.

console 객체는 Node.js 애플리케이션에서 '메시지를 기록'하는 데 사용하며, 다양한 유형의 메시지가 출력.

 

console.log(): 문자열, 숫자, 객체, 배열 등의 값을 출력. 개발 목적으로 사용.

console.error(): 에러 메시지를 출력.

console.warn(): 경고 메시지를 출력.

console.time() / console.timeEnd(): 코드 실행 시간 측정.
console.info(): 정보를 출력.


console.log('로딩중...');
console.clear();           // console을 지우는 코드. cmd에 node 2-console을 입력하면 console이 삭제됨.


console.log('log');         // 개발 목적
console.info('info');       // 정보 제공 목적
console.warn('warn');   // 경고 목적
console.error('error');    // (사용자, 시스템)에러 발생 시 알림 목적

[F12]의 console을 open하여 출력됨.

 

3-1. assert()

console.assert('가정문' , '출력내용')

assert() 메소드 내의 '가정문의 결과값'이 true면 출력되지 않고, false일 경우 출력됨.


console.assert(2 === 2, '두 값이 같아요'); // 가정문의 결과가 true이므로 값이 출력되지 않음.
console.assert(2 === 3, '두 값이 달라요'); //  'Assertion failed: 두 값이 달라요' 의 error 출력 // 가정문의 결과가 false.

 

3-2. table()

배열이나 객체의 데이터를 표 형식으로 출력.

 

const user = {userid:'apple', name:'김사과', age:20, company: {name: 'SK', addr: '서울 중구'}};

user의 data를 출력.


console.log(user);

 

console.table('데이터')

user의 data를 table형태로 출력.


console.table(user);

 

3-3. dir()

console.dir( '객체명' , '[옵션]' )

객체의 속성과 메소드를 출력.

해당 객체의 속성과 메소드 목록이 콘솔에 출력되기 때문에, 객체를 탐색하고 디버깅할 때 유용.


console.dir(user, {showHidden: true, depth: 0, colors: false}); 
// 옵션을 추가하고 싶다면 중괄호를 사용  // depth:0 (depth를 0으로 지정하여 object를 숨기는 기능)

 

3-4. time()

console.time( '인자명' )

실행 시간을 측정하여 console에 출력.

예) 'for loop라는 이름을 인자로 하여 1을 증가시키는 타이머를 작동, 10이 되기 전에 타이머를 종료하는 예제.


console.time('for loop');           // 고유한 이름인 'for loop'를 인자로 전달해야 함.
for(let i=0; i<10; i++){           
    console.log(i);
}

console.timeEnd('for loop');    // 타이머가 종료. 밀리초 단위의 실행시간이 끝부분에 기재.

 

3-5. count()

console.count( '라벨명' )

특정 라벨(label)에 대한 호출 횟수를 console에 출력.

console.countReset( '라벨명' )

특정 라벨(label)에 대한 호출 횟수를 0으로 초기화(reset).


function func1(){
    console.log('func1()이 실행되었음.');      // 'func1()이 실행되었음.' 출력
    console.count('func1 function');       // func1 function: 1 출력 // 'func1 function'에 대한 호출횟수가 console에 출력.
}

function func2(){
    console.log('func2()가 실행되었음.');       // 'func2()가 실행되었음.' 출력
}

func1();
func2();
func1();               // func1 function: 2 출력

console.countReset('func1 function');       // count를 reset하는 기능. 특정 라벨에 대한 호출 횟수를 다시 0으로 초기화.
func1();               // func1 function: 2 출력

 

3-6. trace()

console.trace( )

현재 실행 중인 코드의 호출 경로(호출스택)를 출력.

호출 스택의 모든 함수와 메서드의 이름과 위치가 콘솔에 출력됨.

호출 스택을 분석하면 코드 실행 경로를 추적하고 디버깅하는 데 도움이 됨.


function func3(){
    func4();
}
function func4(){
    func5();
}
function func5(){
    console.log('func5()가 실행되었음.');
    console.trace();
}

func3();

 

4. this

현재 실행 중인 코드에서 사용된 객체를 참조하는 JavaScript 키워드.

JavaScript에서 '객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 핵심 개념' 중 하나.

함수가 전역 범위에서 호출될 경우, this는 전역 객체를 참조.

메서드가 객체의 프로퍼티로 호출될 경우, this는 해당 객체를 참조.


global.hello = () => {
    console.log('hello');

 };               // 1.global에서 사용했던 예제를 참고하여 hello가 global의 메서드라는 것을 확인.


function hello(){
    console.log(this);
    console.log(this === global);    
}
hello(); // true  // hello()라는 함수의 this는 global과 동일하다는 것을 출력.


class A {     // class A : num이라는 멤버 변수를 가지고 있으며, memberFunction()이라는 멤버 함수를 정의.

    constructor(num){    // constructor() 메서드는 클래스의 인스턴스를 생성할 때 자동으로 호출.
        this.num = num;    // 인스턴스의 num 멤버 변수에 값을 할당하는 코드
    }

    memberFunction(){
        console.log(this);  // this 키워드가 현재 객체를 참조하는지 확인
    }
}

const a = new A(10);

a.memberFunction();    //   A {num: 10} 출력


console.log(this);        // {    } // global scope에서의 this는 module.exports의 기능을 가짐.
console.log(this === module.exports);     // true

 

5. module

Node.js 애플리케이션의 기능을 나누고 조직화하기 위한 코드 블록.

모듈은 JavaScript 파일로 작성되며, Node.js에서는 파일 시스템에서 모듈을 로드하여 사용할 수 있음.

일반적으로 Node.js 애플리케이션은 여러 개의 모듈로 구성되며,

각각의 모듈은 module.exports를 사용하여 모듈 내에서 공개하려는 데이터 또는 함수를 지정.

 

모듈은 Node.js에서 코드를 조직하고 재사용 가능한 코드를 작성하는 데 매우 유용함.

Node.js 자체에 포함된 내장 모듈 외에도, 수많은 개발자들이 만든 모듈이 NPM(Node Package Manager)을 통해 제공됨.

 

module.exports

모듈에서 공개하려는 항목을 정의하는 객체.

이를 통해 모듈 외부에서 해당 모듈의 내용에 접근할 수 있음.

module.exports에 할당된 객체만 모듈 외부에서 접근 가능함.

 

예) counter2.js의 increase(), getCount() 함수 모듈을 가져와서 출력하는 경우 


import * as counter from './counter2.js';      // 'counter'라는 고유 이름을 사용. 같은 폴더의 counter2.js에서 모듈을 가져옴.

counter .increase();
counter .increase();
counter .increase();
console.log(counter .getCount());




// 이런식으로 사용할 수도 있다.
import {increase, getCount} from '/.counter2.js';

increase();
increase();
increase();
console.log(getCount());

<counter2.js>


let count = 0;

export function increase() {                // 내보내고 싶은 함수의 앞에 export를 붙임.
    count++;
}

export function getCount() {
    return count;
}


 

EX6 버전부터 module import를 사용하기 위해서는 폴더 내에 'package.json'이 존재해야 함.


package.json
:
Node.js 프로젝트에서 사용하는 파일 중 하나. 

이 파일은 프로젝트에 필요한 의존성(dependencies)을 정의하고, 프로젝트의 이름, 버전, 저작권 정보 등을 포함함.
package.json 파일은 npm(Node Package Manager)에서 사용됨. 

npm은 Node.js에서 제공하는 패키지 관리 도구이며, package.json 파일을 읽어 프로젝트에 필요한 모듈을 설치하고 관리함.
package.json 파일은 직접 작성할 수도 있고, npm init 명령어를 사용하여 자동으로 생성할 수도 있음. 

일반적으로 Node.js 프로젝트를 시작할 때 package.json 파일을 생성하고, 이후 프로젝트에서 필요한 패키지를 추가하거나 
삭제할 때마다 이 파일을 수정함.

 

1. 설치를 위해 명령 프롬프트에 ' npm init -y ' 를 입력.

2. 정상적으로 생성이 되었음을 VS Code에서 확인.

3. package.json 파일에서 "type": "module", 을 추가.

 

위 내용 추가 시 'import문'의 사용이 가능해짐.