1. pipe() 함수
- 버퍼(Buffer)는 메모리에 일부 공간을 나타내며, 바이트 단위의 정수 형태의 배열로 데이터를 저장하는 역할을 합니다. 주로 파일이나 네트워크와 같은 데이터 소스에서 읽거나 쓸 때 사용되며, 데이터를 일부분씩 처리하고 안정적인 전송을 위해 활용됩니다.
const buf = Buffer.from('Hi')
// HI라는 글자를 버퍼에 저장
// 이 객체는 일반적으로 힙(heap) 메모리에 저장됩니다.
console.log(buf)
//<Buffer 48 69> 변수에 담긴 값을 16진수로 출력
console.log(buf.length)
console.log(buf[0]) //첫글자의 아스키코드 72
console.log(buf[1]) //두번째 글자의 아스키코드 105
console.log(buf.toString()) //
console.log('-------------------')
const buf2 = Buffer.alloc(2) // alloc쓰면 메모리를 직접 할당시키는것.빈값이지만 메모리를 가짐
buf2[0]=72
buf2[1]=105
console.log(buf2.toString())
- 스트림(Stream)은 데이터의 흐름을 나타내며, 읽기 스트림과 쓰기 스트림으로 나뉩니다. 이를 통해 데이터를 조금씩 읽거나 쓰는 방식으로 메모리를 효율적으로 사용할 수 있습니다. 파일이나 네트워크에서 데이터를 효과적으로 처리하는 데에 사용되며, 데이터의 흐름을 통해 차례로 처리되어야 하는 상황에서 유용하게 활용됩니다.
const fs = require('fs')
const beforeMem = process.memoryUsage().rss
// 메모리 사용량 확인, 사용량을 프로퍼티로 저장해서 숫자로 출력
console.log(beforeMem)
// 21958656
fs.readFile('./file.txt',(_,data) => {
// (_,data): 첫 번째 인자는 에러를 나타내며, 두 번째 인자는 파일의 내용을 나타냅니다.
// 여기서는 에러를 무시하기 위해 언더스코어 _를 사용하고, 파일의 내용은 data 매개변수에 전달됩니다.
fs.writeFile('./file2.txt',data,()=>{
console.log('파일 저장 완료')
}) // 읽어온 내용을 file2에 씁니다.
const afterMem = process.memoryUsage().rss // 파일 새로 쓴 후 메모리 사용량 확인
const diff = afterMem - beforeMem // 사용한 메모리 양 diff 변수에 저장
const consumed = diff/1024/1024 //byte를 메가바이트로 변환
console.log(diff)
console.log(`메모리: ${consumed}MB 추가 사용함`)
})
`pipe()`는 스트림에서 사용되는 메서드로, 스트림을 연결하고 데이터를 한 스트림에서 다른 스트림으로 자동으로 전달하는 기능을 제공합니다. 이를 통해 데이터를 효율적으로 처리하고 복사하지 않고도 스트림 간에 데이터를 전달할 수 있도록 도와줍니다. 주로 파일 읽기, 쓰기, 네트워크 통신 등에서 유용하게 활용되며, 데이터의 흐름을 자동으로 연결하여 처리할 때 매우 효과적입니다.
const fs = require('fs')
const zlib = require('zlib')
const readStream = fs.createReadStream('./file.txt')
const zlibStream = zlib.createGzip();
const writeStream = fs.createWriteStream('./file2.txt.gz')
const piping = readStream.pipe(zlibStream).pipe(writeStream)
// './file.txt'을 읽어온 후, 압축시킨 다음 그 내용을 './file2.txt.gz'전달
piping.on('finish',() => {
console.log('끝')
})
2. http 모듈
http 모듈은 Node.js에서 제공하는 기본 모듈 중 하나로, HTTP 프로토콜을 통해 서버와 클라이언트 간의 통신을 가능케 하는 기능을 제공합니다. HTTP 모듈을 사용하면 웹 서버를 만들고, HTTP 요청을 받아들이고, HTTP 응답을 생성할 수 있습니다. createServer를 통해 웹서버 생성하고, req는 사용자가 보낼 정보, res는 서버가 사용자에게 보낼 정보를 의미합니다.
console.log('http 모듈 테스트')
console.log('노드몬 실행 중')
const http = require('http')
const fs = require('fs')
const server = http.createServer((req, res) => {
console.log('서버가 동작중')
console.log(req.headers) // headers로부터 가져온 정보가 terminal에 뜸
console.log(req.method) // post 혹은 get
console.log(req.url) // http://localhost:8080 뒤 url 알려줌
const url = req.url
res.setHeader('Content-Type','text/html')
// res: 서버의 응답. 앞으로 받을 값이 html인지 이미지인지 알려줘야함
if(url === '/'){
fs.createReadStream('./html/index.html').pipe(res)
// index.html읽어서 res에 전달
}else if(url === '/mypage'){
fs.createReadStream('./html/mypage.html').pipe(res)
// mypage.html읽어서 res에 전달
}else{
fs.createReadStream('./html/not-found.html').pipe(res)
}
})
server.listen(8080) // 포트번호 입력(아무거나), 엑세스 허용, localhost:8080를 크롬에 입력
*** Express 프레임 워크와 http모듈 비교
1. 수준의 차이
- `http`: 낮은 수준의 HTTP 프로토콜 다룸, 모든 것을 수동으로 다뤄야 함.
- `Express`: 높은 수준의 추상화로 개발자에게 편의성 제공, 라우팅과 미들웨어 지원.
2. 라우팅 및 핸들링
- `http`: 라우팅을 직접 구현해야 함.
- `Express`: 강력한 라우팅 기능으로 URL에 따라 다른 핸들러 지정 가능.
3. 미들웨어
- `http`: 미들웨어를 직접 구현해야 함.
- `Express`: 미들웨어를 활용하여 요청과 응답 중간에 다양한 작업 수행 가능.
4. 유연성과 생산성
- `http`: 모든 것을 수동으로 다루어야 하므로 번거로움.
- `Express`: 더 적은 코드로 더 많은 일을 할 수 있어 생산성과 유연성이 향상됨.
`http` 모듈은 웹 서버를 구축하기 위한 기본 도구를 제공하며, `Express`는 이러한 도구 위에 높은 수준의 추상화를 제공하여 개발자에게 편의성과 유연성을 제공합니다.
3. 템플릿 엔진
웹 어플리케이션에서 동적으로 html을 생성하는데 사용되는 도구 및 라이브러리입니다. html 페이지 내에서 데이터를 동적으로 삽입하고 조작하는데 도움이 되며 주로 웹 어플리케이션에서 뷰 부분을 생성하는데 사용됩니다.
- 템플릿 엔진으로 알려진 도구들은 EJS, Pug, HandleBars, Nunjucks 등이 있습니다.
그 중 JavaScript 코드를 HTML에 삽입하여 사용하는 방식을 채택하는 EJS를 사용해보겠습니다.
(EJS 공식 홈페이지 : https://ejs.co/)
설치: npm i ejs
HTML 확장자는 ejs로 변경해준다.
[index.ejs]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>환영합니다</title>
</head>
<body>
<h2>NodeJS로 만든 첫번째 문서</h2>
<p>반갑습니다 <%=name%></p>
<!-- 해당 ejs파일이 html로 변환되면서 <%=name%>이 변수안의 값으로 바뀌어 표현됨 -->
</body>
</html>
[mypage.ejs]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>마이페이지</title>
</head>
<body>
<h2>마이페이지</h2>
<p>제가 익힌 기술은</p>
<ul>
<%
skills.forEach(skill => {
%>
<li><%=skill.name%></li>
<!-- li를 쓰기 위해서 이렇게... -->
<%
})
%>
</ul>
</body>
</html>
<%= name%>
EJS에서 변수를 출력하는 방법 중 하나로, 해당 변수의 값을 HTML 문서에 출력할 때 사용.
<% ~ %> : 해당 내용을 삽입하는 기호
= : 출력(print)의 기호
const http = require('http')
const fs = require('fs')
const ejs = require('ejs')
const name = '김사과'
const userid = 'apple'
const skills = [{name:'HTML'},{name:'CSS'},{name:'JavaScript'},{name:'Nodejs'},{name:'Python'}]
const server = http.createServer((req,res)=>{
const url = req.url
res.setHeader('Content-Type','text/html')
if(url === '/'){
// 아무것도 없으면 index.html을 보통 찾음
ejs.renderFile('./template/index.ejs',{name:name})
// 파일을 읽으면서 index.ejs찾고 키name에 변수name넣은 애를 index.ejs에 넣어주는 랜더링함
.then((data)=> res.end(data))
// 랜더링한 데이터를 응답으로 보내줌
// 결과가 html로 변환되어 날라감
}else if(url === '/mypage'){
ejs.renderFile('./template/mypage.ejs',{skills:skills})
.then((data)=> res.end(data))
}else{
ejs.renderFile('./template/not-found.ejs',{userid:userid, name:name})
.then((data)=> res.end(data))
}
})
server.listen(8080)