Node JS Basic(2)
이번 시간에는 Node JS와 관련된 기초적인 개념에 대해서 좀 더 알아보겠습니다.
동적 페이지와 정적페이지 와의 차이
- 정적 페이지
미리 작성된 HTML, CSS, JavaScript 등의 정적 파일로 구성된 페이지입니다. 서버에 요청이 오면, 서버는 해당 파일을 그대로 클라이언트에게 전송합니다. 정적 페이지는 동일한 내용을 모든 사용자에게 제공하며, 서버 측에서 추가적인 데이터 처리가 필요하지 않습니다. 예들들어, 회사 소개 페이지, 블로그 게시물 ...
static 파일을 서빙 하기 위해서는 express.static 이라는 미들웨어를 설정해야 한다. 일반적으로 static files(hitml, css, images) 등은 public 폴더 안에 존재한다. (include any fron-end files in public directory within the project)
// static 파일들을 서버에서 전달하도록 미들웨어를 사용한다.
app.use(express.static("public"))
- 동적 페이지
요청에 따라 동적으로 내용이 생성되는 페이지입니다. 서버는 요청을 받으면 필요한 데이터를 처리하고, 그에 따라 콘텐츠를 동적으로 생성하여 클라이언트에게 제공합니다. 동적 페이지는 개별 사용자에게 맞춤화된 내용을 제공하거나 데이터베이스와의 상호작용이 필요한 기능을 수행할 수 있습니다. 예를 들어, 로그인 페이지나 쇼핑 카트와 같은 기능이 동적 페이지에 해당
Node.js에서 동적 페이지를 렌더링하기 위한 실용적인 방법
템플릿 엔진 사용: Express.js와 함께 많이 사용되는 템플릿 엔진인 EJS, Handlebars, Pug(Jade) 등을 사용하여 동적 페이지를 렌더링할 수 있습니다. 템플릿 엔진을 통해 HTML 템플릿 내에서 동적 데이터를 삽입하고, 반복문, 조건문 등을 사용하여 동적 콘텐츠를 생성할 수 있습니다.
클라이언트 측 JavaScript 사용: Node.js는 JavaScript 런타임 환경이므로, 클라이언트 측과 동일한 JavaScript 코드를 사용하여 동적 페이지를 생성할 수 있습니다. 클라이언트 측 JavaScript와 마찬가지로 데이터 요청 및 응답 처리, 이벤트 핸들링 등을 사용하여 동적 콘텐츠를 생성할 수 있습니다.
Node.js에서 서로 다른 페이지끼리 링킹하는 방법 (메인 화면에서 회원가입 화면으로 넘어가는 방법):
Express.js 라우팅: Express.js를 사용하여 서버 측에서 라우팅을 설정하여 페이지 간의 링크를 처리할 수 있습니다. 예를 들어, 메인 화면(/)에서 회원가입 화면(/signup)으로 이동하도록 라우트를 설정할 수 있습니다. 클라이언트 측에서 링크를 클릭하면, 해당 URL로 요청이 전송되고 서버는 해당 요청에 대한 라우팅을 수행하여 적절한 페이지를 렌더링하거나 리다이렉트합니다.
Node.js 아키텍처
Node.js는 자바스크립트 코드 실행에 필요한 런타임으로 V8 엔진을 사용하고, 자바스크립트 런타임에 필요한 이벤트 루프 및 운영체제 시스템 API를 사용하는 데는 libuv 라이브러리를 사용합니다. 언어 자체가 싱글 스레드이고, 이벤트 기반 아키텍처입니다. 따라서 자바스크립트 런타임인 Node.js도 자연스럽게 싱글 스레드로 구현되고 이벤트 기반 아키텍처를 구현했습니다.
싱글 스레드
자바스크립트 엔진(V8)은 자바스크립트를 실행하는 힙과 콜 스택을 갖고 있습니다. 그리고 싱글 스레드로 실행됩니다. 이때, 싱글 스레드라는 말은 콜 스택 하나만 있다는 뜻이고 이는 곧 한 번에 하나의 작업만 가능하다는 의미입니다.
function func1() {
console.log('1');
func2();
return;
}
function func2(){
console.log('2');
return;
}
위 코드를 보면 func1과 func2 함수 2개가 있습니다. 코드에서는 func1()만 실행하고 func1()에서는 1을 출력 후 func2()를 실행합니다.
이벤트 기반 아키텍처
Node.js는 싱글 스레드이기 때문에 한번에 하나의 작업만 가능합니다. 그렇다면 어떻게 하면 요청을 하나의 스레드로 동시에 처리할 수 있을까요? 예를들어, 하나의 작업만 가능하다면 0.1초가 걸리는 작업 요청이 동시에 100개가 들어오면 마지막 사람은 10초를 기다려야합니다. 따라서 이를 해결해 주는 방법이 이벤트 기반 아키텍처를 적용하는 것입니다. 콜 스택에 쌓인 작업을 다른 곳에서 처리한 다음 처리가 완료되었을 때 알림을 받으면 스레드가 하나라도 빠르게 처리할 수 있습니다.
console.log('1');
setTimeout(() => console.log(2), 1000);
console.log('3);
1
3
(1초 후)
2
자바스크립트 코드는 V8의 콜 스택에 쌓이고 I/O 처리가 필요하거나 시간이 올래걸리는 작업은 이벤트 루프로 보내게 됩니다. 이벤트 루프에서는 말 그대로 루프를 실행하면서 운영체제 또는 스레드 워커 I/O 처리를 맡기게 됩니다. 스레드 워커와 운영체제는 받은 요청에 대한 결과를 이벤트 루프로 돌려주고, 이벤트 루프에서는 결과값을 다시 콜 스택에 추가합니다.
결국, Node.js는 자바스크립트를 브라우저가 아닌 내 컴퓨터 즉, 로컬에서 사용할 수 있도록 해주는 런타임 환경이고 싱글 스레드와 이벤트 기반의 아키텍처를 사용합니다. 싱글 스레드는 한번에 하나의 작업만 가능하지만 이벤트 기반의 아키텍처를 적용함으로써 I/O작업이나 시간이 오래걸리는 작업은 운영체제나 스레드 워커에게 맡겨 처리하게 합니다. 그래서 요청을 동시에 처리할 수 있게 해줍니다.