node.js_1 [기본개념]

오미희·2022년 1월 8일
0

node.js

목록 보기
1/5

Node.js

👉 Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임.

  • nods.js는 서버 실행용으로 주로 사용됨
- [ 런타임 ] : 특정 언어로 만든 프로그램들을 실행할 수 있는 환경.
- [ 서버 ] : 네트워크를 통해 클라이언트 정보나 서비스를 제공하는 컴퓨터 또는 프로그램.
- [ 클라이언트 ] : 요청을 보내는 주체로, 주로 브라우저를 의미(모바일 앱, 다른 서버에 요청을 보내는 서버도 클라이언트가 될 수 있다.).

✅ 특성

✔ 이벤트기반

이벤트(ex 클릭 엔터 등...)가 발생할 때 사전에 짜여진 작업을 수행하는 것. 즉 특정 이벤트 발생 시 거기에 설정해둔 콜백함수를 호출.
  호출된 함수들은 순서대로 호출 스택에 들어가고 함수 실행이 완료되면 호출스택에서 마지막에 들어간 호출부터 지워진다.
즉 후입선출(LIFO : Last In First Out)

✔ 논블로킹 I/O

이전 작업이 완료되기 전에 다른 작업을 수행하는 것.
(즉 블로킹은 이전 작업이 모두 완료된 후에 다른 작업 수행 가능.)
노드는 I/O 작업을 백그라운드에 넘겨 동시에 처리

I/O란?
"주로 libuv가 지원하는 시스템 디스크나 네트워크와 상호작용하는 것"
즉 파일을 읽거나 파일쓰기 폴더만들기 등 파일시스템접근이나 네트워크를 통한 요청 
등이 이에 해당됨.
* libuv : 이벤트 루프를 기반으로 비동기 I/O를 지원하는 다중 플랫폼 C 라이브러리

논블로킹 방식으로 코드를 짜는 것은 작업 실행 성능을 높여준다.

논블로킹 기법

setTimeout(콜백,0)

function longRunningTask() {
	// 오래 걸리는 작업
	console.log('작업 완료');
};
console.log('시작');
setTimeout(longRunningTask,0);
console.log('다음작업');
// 위의 코드 실행시
// 시작 -> 다음작업 -> 작업완료
📌 논블로킹 예시
const fs = requir('fs');
fs.readFile('/file.md',(err,data) => {
    if(err) throw err;
    console.log(data);I/O
});
fs.unlinkSync('/file.md');
// 위 코드의 문제점은 I/O가 논블로킹 방식으로 이루어지기 때문에 앞에서 fs 파일이
// 다 읽혀지기도 전에 unlinkSync()가 실행되어 파일이 제거될 위험이 있다.
// 위의 코드는 아래와 같이 수정되어야 함.

const fs = require('fs');
fs.readFile('/file.md',(readFileErr,data) => {
    if(readFileErr) throw readFileErr;
    console.log(data);
    fs.unlink('/file.md',(funlinkErr) => {
    	if(unlinkErr) throw unlinkErr;
    })
})
node.js 표준 라이브러리의 모든 I/O 메서드는 논블로킹인 비동기 방식을 제공하고 콜백 함수를 받는다.

✔ 싱글스레드

🌞 이해를 돕는 아주 좋은 예시
점원이 한 손님의 주문을 받고 주방에 주문내역을 넘긴 뒤 다음 손님의 주문을 받습니다. 
요리가 끝나기 까지 기다리지 않고, 주문내역만 주방에 계속 전달하고, 주방에서 요리가
완료되면 완료된 순서대로 손님에게 서빙합니다. 요리의 특성(블로킹인지 논블로킹인지)에
따라 완료되는 순서가 달라질 수 있어, 주문의 들어온 순서와 서빙하는 순서가 일치하지 
않을 수 있습니다.
// 요리를 하는 시간이 오래 걸린다면(CPU가 많이 소모되는 작업) 주문이 많이 들어오면
// 버거울 수 있다.
즉 싱글스레드 == 점원 한 명


예외 )
스레드풀(Thread Pool) : 특정 동작 수행시 멀티 스레드로 실행
워커 스레드(Thead Pool) : 노드 12 버전이후 안정화된 기능, 멀티스레드 가능.

// 터미널에 node 입력후

▪ process

process 객체는 현재 실행되는 노드 프로세스에 대한 정보 제공
process.version : 노드 버전 제공
process.arch : 프로세서 아키텍처 정보 제공
process.platform: 운영체제 플랫폼 정보 제공
process.pid : pid 제공
process.exePath: 노드의 경로 정보 제공
process.cpuUsage: 현재 cpu 사용량 정보 제공
process.env : 환경변수에 대한 정보 제공
process.nextTick : 이벤트 루프가 다른 콜백 함수들보다 nextTick()의 콜백 함수를 우선처리하도록 함.
// setImmediate setTimeout보다 먼저 실행됨.
// resolve된 Promise도 nextTick처럼 다른 콜백들보다 우선시됨

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

//출력순서
// nextTick -> promise -> timeout -> immediate 

process.exit : 실행중인 노드 프로세스 종료

* 이벤트루프
이벤트 발생 시 호출할 콜백 함수들을 관리하고, 호출된 콜백 함수의 실행순서를 결정하는
역할.

❕ 동기와 블로킹

❕ 비동기와 논블로킹

✅ NPM (=Node Package Manager)

✔ Package.json

설치된 패키지의 버전을 관리해주는 파일
> npm init // 터미널에 입력 package.json파일 생성
> npm install [패키지명] // 해당 패키지 설치해줌
> npm install --save-dev // 실제 배포시에는 사용x 개발시에만 사용하는 패키지

// package.json
// --save-dev 옵션과 설치된 모듈은 devDependencies에서 관리.
  "devDependencies": {
    "nodemon": "^2.0.15"
  }

> npm install -global rimraf // 전역설치한 것으로, 이는 package.json에 기록x

> npm install -global rimraf
// 리눅스나 맥의 rm -rf 명령어를 윈도우에서도 사용가능하게 해주는 패키지

npx
전역설치대신 사용
1. npm install --save-dev rimraf
2. npx rimraf [삭제할것]
// 위와 같이 사용시에 npx를 붙여 사용.

> npm uninstall [패키지명] // 사용하지 않는 패키지 삭제

npm에 존재하지 않는 패키지들은 npm install [저장소수주소] 이렇게 하여 설치 가능.

✔ express

JavaScript로 작성되고 Node.js 런타임 환경에서 구동되는 웹프레임워크

미들웨어 실행

app.use(미들웨어) // 모든 요청에서 해당 미들웨어 사용
app.use('/login',미들웨어) // /login을 통한 요청시에만 해당 미들웨어 사용
app.post('logout',미들웨어) // post메서드이면서 /login을 통한 요청시에만 해당 미들웨어 사용.

// 예시
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser')
// body-parser는 본문의 데이터를 해석하여 req.body객체로 전달해주는 기능을 하는 미들웨어.
// 이미지, 동영상, 파일등의 멀티파트 이미지는 해석x 멀티파트 데이터는 multer모듈 사용.
const cookieParser = require('cookie-parser');
// 요청을 통해 전달된 쿠기를 해석애 req.cookies 객체로 만듦.
const session = require('express-session');
require('dotenv').config();
const path = require('path');

const app = express();

app.set('port',proscess.env.PORT||3000);
// app.set(키,값)을 사용해서 데이터 저장. 데이터 가져올 때는 app.get(키)로 가져옴.

app.use(morgan('dev'));  // dev combined common short tiny 등
// dev 기준  [HTTP메서드] [주소] [HTTP상태코드] [응답속도] - [응답바이트]
app.use('/',express.static(path.json(__dirname,'public')));
// static 미들웨어는 정적인 파일들을 제공하는 라우터 역할.

// 아래의 두 줄이 body-parser사용을 위한 세팅 코드
app.use(express.json());
app.use(express.urlencoded({extended:false}));
// app.use(bodyParser.raw());   // 요청의 본문이 버퍼 데이터일때 추가 세팅
// app.use(bodyParser.text());  // 요청의 본문이 텍스트 데이터일때 추가 세팅

app.use(cookieParser(process.env.COOKIE_SECRET));
//app.use(cookieParser(비밀키))
/*
res.cookie('name','algml', {
    expires:new Date(Date.now() + 900000),
    httpOnly:true,
    secure:true
    // signed:true   // 쿠키를 만든 것 검증해줌. 
});
res.clearCookie('name','algml',{httpOnly:true,secure:true})

*/

//240page
app.use(session({
    resave:false,
    saveUninitialized:false,
    secret:process.env.COOKIE_SECRET,
    cookie:{
        httpOnly:true,
        secure:false,
    },
    name:'session-cookie',
}))

app.use((req,res,next) => {
    console.log('모든 요청에 실행');
    next();
})

출처

Node.js 교과서
node.js docs

profile
안녕하세요

0개의 댓글