2023. 3. 15. 14:34ㆍ개인노트-인강
한 번에 끝내는 Node.js 웹 프로그래밍 초격차 패키지 백엔드 part 1
# Node.js 소개 01 JavaScript 생태계와 Node의 역사
- express.js : 2010년에 등장하여 Node.js 웹서버 프레임워크의 표준이 되었습니다.
- 바벨 & 웹팩 : 발전하는 javascript의 속도를 따라가지 못하는 브라우저 하위 호환성을 살리기 위해서 2014년에 바벨과 웹팩이 등장했습니다.
- 자바스크립트는 처음에는 웹앱을 만드는 데서 시작했지만, 지금은 react native 등을 통해 ios와 안드로이드 앱도 만들고 서버도 만듭니다. 이렇게 자바스크립트 하나의 언어로 풀스택 구현이 가능합니다.
- 코드의 핵심을 모든 곳에서 공유하기 때문에 코드의 재사용성을 극한으로 끌어올릴 수 있게 됩니다. 따라서 서버사이드 렌더링과 같은 고급 기술을 자유롭게 쓸 수 있게 됩니다.
# Node.js 소개 02 Node의 특징, 강점, 약점
- Node.js의 저자 라이언 달이 Node.js에 대한 최초의 프리젠테이션 자리에서 한 말 : IO needs to be done differently IO는 (지금까지와는) 다르게 되어야 한다.
- 이는 Node.js에서 무엇을 위해서 만들어졌는지를 알 수 있는 아주 핵심적인 문장입니다. IO가 Node.js에서 그만큼 중요한 부분을 차지하고 있다는 것입니다.
- 라이언이 주목한 JavaScript의 특징은 이벤트 루프의 비동기적인 성질이었습니다. JavaScript는 이벤트 루프를 활용해서 동작하도록 만들어졌는데 이 점이 IO바운드 프로그램의 가장 큰 문제인 요청하고 기다리기를 해결하는 열쇠로 본 것입니다.

한 줄, 한 줄 처리하는 방식이 일반적인 처리 방식. 이전 라인을 처리해야 다음 라인으로 넘어갈 수 있습니다.

라이언 달은 위처럼 바뀌어야 한다고 이야기합니다.
JavaScript에서 비동기 처리 방식은 위처럼 콜백을 사용하도록 되어있습니다. (api로 가져온 데이터 등)결과를 통해서 무언가를 할지에 대해서는 콜백으로 넣어주어야합니다. 이것이 JavaScript에서의 비동기 처리 방식입니다. 그리고 이 점이 Node.js의 제일 큰 특징이라고 볼 수 있습니다.
이 코드와 위에서의 고전적인 코드와의 가장 큰 차이점으로 볼 수 있는 점은 비동기 처리에서 queryDatabase가 응답이 오기 전에도 바로 다음줄(getSomethingFromAPI) 로 넘어갈 수 있다는 점입니다. 즉, queryDatabase 를 실행하고 바로 getSomethingFromAPI 도 실행하고 나서 정말로 결과가 돌아오면 안의 콜백 메소드의 몸체를 실행하게 됩니다.
고전적인 방식은 한 줄 한 줄 block되면서 여러가지 네트웍이나 IO를 기다리면서 진행을 했어야 했는데, 지금은 일단 다 요청을 보내버리고, 응답이 돌아올때마다 하나씩 대응을 하는 식으로 코드가 바뀐 것입니다. 이것은 JavaScript 자체가 이렇게 생긴 언어이기 때문에 자바스크립트 언어수준에서 이미 비동기 문제가 잘 해결되있는 것으로 볼 수 있습니다.
낭비되는 클락 수가 없고, 브라우저나 Node환경에서 이 무거운 일을 대신 처리해 주기 때문에 메인 스레드는 자신이 해야 될 일에만 집중해서 처리할 수 있습니다.

이러한 오프로딩방식이 Node가 빠른 속도와 매우 높은 확장성을 갖는 근본적인 이유입니다.
Node.js가 네트워크, 통신, 파일 읽어오기 등 과 같은 작업을 처리하는 동안 개발자는 비즈니스 로직등 더 중요한 부분에 집중할 수 있습니다.
비동기에 있어서는 무조건 싱글 스레드이기 때문에 비동기로 인한 동시성 문제도 걱정할 필요가 거의 없습니다.
얼마나 많은 요청이 들어오든 메인 스레드는 맡긴일만 하기 때문에 확장성도 매우 높습니다.
그리고 V8 자체도 매우 빠른 엔진입니다. 그래서 싱글 스레드에서의 블로킹만 안 일으킨다면 아주 빠른 퍼포먼스를 기대할 수 있게 됩니다.
## 한계점 및 극복방법
JavaScript로만 짰기 때문에 JavaScript만의 한계가 있습니다. 저수준 처리는 당연히 느릴수 밖에 없습니다. 예를 들어 이미지 파일 전체 버퍼를 돌면서 어떤 특정한 픽셀을 찾아낸다던지, 오디오 파일을 돌면서 2개의 오디오 파일을 합친다던지 하는 것들을 Node.js만 가지고 처리를 하려고 하면 굉장히 무겁고 필요이상으로 오래 걸리는 일이 됩니다.
Node.js에서 저수준 처리는 Node가 빠르게 처리하기 매우 어려운 부분입니다.
그래서 Node.js는 C와 WebAssembly 모듈을 바인딩해 사용하는 방법을 제공하고 있습니다.
C는 Node-gyp를 통해, WebAssembly는 Node 12 버전부터 제공되고 있습니다.
WebAssembly란? binary instruction format 일종의 브라우저를 위한 어셈블리라고 생각하면 됩니다.
JavaScript의 경우 스크립트 언어이기 때문에 결국 런타임에서는 예측할 수 없는 부분들이 생길 수 밖에 없기 때문에 완벽히 최적화를 할 수 없습니다. 하지만 WebAssembly를 사용하게 되면 최적화 효율을 많이 끌어올릴 수 있습니다. 그리고 이것을 Node.js에서도 제공합니다.
즉, Node.js의 대표적인 약점은 저수준 처리라고 볼 수 있습니다. 그러한 부분을 C와 WebAssembly를 통해서 해결을 할 수 있습니다.
## NPM
추가로 Node.js의 특징으로는 방대한 오픈소스 생태계입니다. npm이 바로 Node.js를 위한 패키지 매니저입니다.
npm에 올라오는 패키지 수만 봐도 160만개 이상입니다.
# Node.js 소개 03 Glitch로 설정 없이 바로 Node 웹서버 코딩해보기
본격적인 Node.js 코딩과 VSCode 셋업에 들어가기에 앞서서
특별한 셋업 없이도 Node 코딩을 체험해 볼 수 있는 방법을 알려드리도록 하겠습니다.
요즘은 웹 환경에서 바로 코드를 쓸 수 있는 환경이 나오고있습니다. codesendbox도 그 중 하나이고, Glitch라는 서비스도 있습니다.
Glitch라는 서비스는 Node 서버를 바로 띄울 수 있고, 코딩도 바로바로 할 수 있게 도와줍니다. 그래서 간단한 프로젝트를 만들 때 빠르게 뛰어들어서 시작하기가 아주 편리하다고 볼 수 있습니다.

에디터도 전부 준비가 되어 있는..바로 코딩을 할 수 있는 상태에 가깝습니다.
server.js안에 있는 코드들은 전부 삭제하고, 여기서 우리가 코딩을 하면 그 내용을 바로 확인할 수 있습니다.
먼저 예시로, 매우 간단한 http 서버를 만들어보겠습니다.
// http 모듈 사용
const http = require('http');
// 서버 객체 생성
const server = http.createServer((req, res) => {
res.statusCode = 200; // 응답이 왔을 때 돌려주어야할 응답
res.end('Hello!'); // response 끝내기(Hello!라는 텍스트를 보내면서..).
});
// server 물리기.
const PORT = 3000;
server.listen(PORT, () => {
console.log('The server is listening at port', PORT);
});
- require : 사용할 모듈을 입력합니다.
우리는 http라는 Node.js 기본 모듈 하나를 사용합니다.
이 http로 할 수 있는 것은 서버를 만드는 일입니다.
그리고 createServer로 만든 서버 객체가 포트에 물려있어야지 실제로 외부에서 들어오는 응답에 반응할 수 있습니다.
여기까지 기본 셋팅입니다.
이제 createServer 콜백 메소드에 요청이 들어왔을 때 어떤 응답을 돌려주어야 할지에 대해 작성합니다.
preview 버튼을 눌러 바로 실행하여 결과를 얻을 수 있습니다.

Terminal 은 어떤 머신에 접속한 상태입니다. 방금 우리가 만든 Node.js 어플리케이션이 돌고 있는 서버에 접속을 한 것입니다. 그것을 확인하는 방법은 terminal에 'ls' 을 입력하면 알 수 있습니다.

그리고 cat server.js 를 입력하면 우리가 server.js에 코딩한 내용을 확인할 수 있습니다.
preview를 새 창으로 preview를 보면 url 주소를 확인할 수 있습니다. 이것이 의미하는 바는 실제로 웹상에서 호스팅이 되고 있는 상황이라는 것 입니다.
이렇게 몇번의 클릭과 코딩으로 기본적으로 다 갖춘 Node 서버가 동작하고 있는 중입니다.
## 정리
Node.js 서버 프로토타이핑을 하고 싶다면 지금의 Glitch나 codesendbox 와 같은 서비스를 사용해서 바로 서버를 띄우는 것이 가능합니다. 실제로 이렇게 서빙이 되고 있기 때문에 우리가 아주 간단한 Node 서버 api를 만들게 된다면 이것을 바로 웹상에서 호스팅을하고 만든 앱을 물려볼 수도 있습니다. 물론 충분한 퍼포먼스가 안나올 수도 있습니다.
셋팅없이 연습용, 테스트용으로 바로 사용해보기에 아주 좋습니다.
# 든든한 개발 환경 설정하기 (VScode 설치하기)
Visual Studio Code를 이용해서 코드를 셋업하는 것 부터 시작해보겠습니다. 여기에 Node를 셋업하고 필요한 각종 설정들이 어떤 효과를 갖는지 그리고 어떻게 설정해야 좋은 효과를 낼 수 있는지 알아보겠습니다.
## code-server
code-server 를 사용하면 브라우저상에서도 VSCode를 사용할 수 있습니다.
Electron 기반 오픈소스인 VS Code를 Node.js 통해 Server를 올리고 크롬 브라우져에서 직접 VS Code 에디터를 사용할 수 있도록 만들어진 오픈소스가 vs code-server입니다.
즉, 크롬 기반의 웹브라우져가 있는 환경이라면 VS code를 사용할 수 있다는 뜻입니다.
# 든든한 개발 환경 설정하기 (NodeJS 설치와 Node 버전관리)
## Node.js 설치
Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임입니다.
로컬에서의 Node.js 버전과 서버에서의 Node.js 버전이 맞아야합니다.
## Node.js 버전관리
1. nvm : 노드 버전 매니저.
설치과정이 복잡하고 관리하면서 꼬일 문제가 발생할 수도 있기 때문에 그다지 추천하지 않습니다.
2. tj/n : 노드 버전 매니지먼트 tool.
매우 간단하고 쓸모가 많습니다.
cmd 창에서..
설치 : npm install -g n
실행 : n
실행하면 노드 버전 목록 나옴. 원하는 버전 선택.
최신의 노드버전 설치 : n latest
현재 노드 버전 확인 : node --version
주의사항 : $N_PREFIX 경로에 노드 버전들이 설치가 됩니다.
# 든든한 개발 환경 설정하기 (npm, 린터, 포매터)
## npm의 사용 방법
- 이 프로젝트가 npm이 관리하는 패키지라는 것을 알려주어야합니다. 그것을 알려주기 위해서는 package.json이라는 파일이 필요합니다. npm init -y 로 package.json 파일을 만듭니다.
- package.json에 기본으로 생성되는 속성들은 사실 패키지를 만드는 경우가 아니라면 당장 필요하지 않은 속성들입니다. 연습을 위한 프로젝트이기 때문에 사실상 scripts 속성만 제외하고는 다 지워도 무방합니다.

- scripts 필드는 우리가 npm을 사용하면서 자주 사용하게되는 혹은 프로젝트를 관리하면서 자주 사용하게 되는 스크립트들을 간단하게 호출할 수 있도록 만들어 둔 필드입니다. 호출 방법 : npm run [scripts에 있는 키의 이름을 입력] 호출 예시 : npm run test
## 린터, 포매터(Formatting, Linting)
Node 프로젝트를 진행하다 보면은 여러가지 문제가 발생하기 쉽습니다. 예를 들어 포맷팅이 잘못될 수도 있고, 여러 사람이 작업을 하다 보면 엉망인 포멧의 코드가 계속 들어올 수도 있고, 혹은 test가 잘 되지 않은 코드들이 들어올 수도 있습니다. 이런 문제들을 린터, 포메터를 사용해서 어느정도 해소할 수도 있습니다.
Node 런타임에게 우리의 코드가 넘어가기 전에, 사용자들이 우리의 서비스들을 사용하기 전에, 최대한 문제들을 잡아줄 수 있도록, 환경을 구성하는게 필요하다고 볼 수 있습니다.
Formatting, Linting은 미세한 차이가 있습니다.
Formatting : 미적인 부분(세미콜론이 붙어있는지..)
Linting : 잘 지키면 좋은 것들(혹시 에러가 날 수도 있는 부분..)
### Formatting : Prettier
설치 : npm install --save-dev prettier

package.json의 제일 중요한 역할은 메타데이터를 표현하는 것도 있지만, 이 패키지가 사용하는 의존성들을 나열하는 것도 큰 의미가 있습니다.
### package-lock.json
첫 라이브러리를 설치하고 나면 새로운 파일이 하나 생깁니다. package-lock.json
- package-lock.json는 실제로 설치된 package들이 어떤것인지 알려주는 파일입니다.
- 버전관리를 한다면 이 package-lock.json 도 함께 올려주는 것이 좋습니다. package.json 에 있는 버전과 실제로 로컬환경에 설치된 버전이 다를 수도 있기 때문입니다.
- package-lock.json 에는 실제로 설치된 버전이 표시됩니다. npm에서도 이 파일을 보고 해당 버전을 설치하려고 하기 때문에 항상 이 lock 파일을 commit해주어야 여러 사람들간에 패키지 버전이 안 맞는 문제가 안 생길수 있습니다.
### node_modules
- node_modules 밑에 들어있는 디렉토리들은 우리 프로젝트가 의존하고 있는 패키지들 이라고 볼 수 있습니다.
- .bin 밑에 있는 파일들은 우리가 실행할 수 있는 바이너리 파일들이라고 보면 됩니다.


### prettier를 이용한 포매팅
이제 prettier를 통해서 포매팅을 어떻게 하는지 알아보겠습니다.
먼저, VSCode 확장에서 Prettier 플러그인을 꼭 설치해야 합니다.
그리고 prettier를 사용하려면 prettier에서 필요한 설정파일을 몇 개 만들어야 합니다.
1. .prettierrc 파일 생성
2. .prettierrc 에 포맷팅 정보 작성
3. VSCode에게 이 prettier를 통해서 포맷팅을 하라고 알려줘야 함. .vscode 폴더 생성. 하위 파일로 settings.json 생성
settings.json : VSCode가 보는 로컬 세팅을 모아두는 곳. 이 프로젝트에만 적용되는 세팅들을 모아두는 곳.

4. settings.json에 prettier 연결.

5. 세미콜론을 작성하고 저장하면 세미콜론이 자동으로 삭제 되는 것을 확인할 수 있습니다.
# 든든한 개발 환경 설정하기 (ESLint)
Linting의 역할을 하는 가장 많이 사용되는 플러그인은 ESLint입니다. (패키지이자 플러그인)
## 설치
설치 : npm install --save-dev eslint
## 설정
설정 : .eslintrc.js 파일을 root에 만든 후 module.exports = {} 를 입력하면 기본적인 세팅 완성.
## 참고
참고 : Node 모듈 밑에 설된 ESLint이기 때문에 VSCode에서 바로 허락해주지 않는 문제가 있습니다.


## Rule 설정
(var를 쓰지 않는다, 싱글쿼터를 쓴다 등) 하나하나 일일이 룰들을 적용할 수도 있지만, 굳이 그렇게 하지 않아도 이미 많은 룰들을 한꺼번에 정의해서 베스트 practice에 맞게 정리해 둔 플러그인들이 많이 있습니다. 이런것들을 사용하면 매우 편리합니다.
ESLint를 사용할 때 주로 사용하는 플러그인 중 하나인 Airbnb에서 내놓은 플러그인을 사용해보겠습니다.
https://github.com/airbnb/javascript
설치 : npm install --save-dev eslint-config-airbnb-base eslint-plugin-import
eslint-config-airbnb-base : 에어비엔비 플러그인
eslint-plugin-import : 패키지가 필요로 하는 의존성.
## 활용
.eslintrc.js 에서 패키지 추가.
module.exports = {
extends: ['airbnb-base'],
}
## prettier와 ESLint 충돌 막기
설치 : npm install --save-dev eslint-config-prettier
.eslintrc.js 에서 패키지 추가.
module.exports = {
extends: ['airbnb-base', 'prettier'],
}
이렇게 하면 ESLint가 prettier가 고친것에 대해서 에러를 내지 않도록 해주는 것이 이 플러그인의 역할입니다.
중요한점은 위처럼 extends에 추가할 때 prettier가 airbnb-base 뒤에 와야 합니다.
## 특정 라인 ESLint 동작 막기


/* eslint-disable-next-line */
하지만 위처럼하면 모든 rule에 대해서 적용되지 않습니다. no console rule만 끄고 싶다면. 아래처럼 작성.
/* eslint-disable-next-line no-console */
## 추가 node 전용 플러그인 설치
설치 : npm install --save-dev eslint-plugin-node
추가 : .eslintrc.js 에 'plugin:node/recommended' 추가
module.exports = {
extends: ['airbnb-base', 'plugin:node/recommended', 'prettier'],
}

# 든든한 개발 환경 설정하기 (TypeScript)
- JavaScript는 동적으로 타입이 정의되는 언어입니다. 즉, 실행시간에 가서야만 변수의 타입을 알게 될 것이라는 뜻입니다.
- JavaScript는 컴파일이라는 과정을 거치지 않기 때문에, 어떤 타입으로 이 변수가 활용 될지를 미리 알 수가 없기 때문에 미리 에러가 나지 않습니다. 그래서 실행하고 나서야 에러가 발생한다는 것을 알게되는 불상사가 벌어집니다.
- 그래서 JavaScript에서 타입체킹이 필요합니다. 여러도구가 있지만 가장 인기가 있는 것은 TypeScript입니다.
- TypeScript는 기본적으로 JavaScript로 컴파일되는 언어입니다. 정확히는 트랜스파일된다고 표현할 수 있습니다.
설치 : npm install --save-dev typescript
js파일에서 타입 체킹을 하려면 '// @ts-check' 라인을 추가합니다.
main.js
// @ts-check
// Formatting, Linting, Type Checking
// Formatting: Prettier
// Linting: ESLint
const someString = 'Hello'
const result = Math.log(someString) // error: 'string' 형식의 인수는 'number' 형식의 매개 변수에 할당될 수 없습니다.
console.log(result)
# 든든한 개발 환경 설정하기 (node 환경에서 TypeScript 도움받기)
- TypeScript가 node 환경에서도 동작하게 하려면 TypeNode라는 패키지를 설치해주어야 합니다.
설치 : npm install --save-dev @types/node - 이 패키지에 들어있는 정보는 Node에서 주로사용되는 객체들에 대한 타입 정보들이 들어있습니다.
- VSCode가 타입스크립트 바이너리를 이용해서 타입체킹을 도와줍니다.
예시 코드
// @ts-check
// Formatting, Linting, Type Checking
// Formatting: Prettier
// Linting: ESLint
// Type checking: TypeScript
// 간단하게 서버를 짜보겠습니다.
// 우선 http서버를 짜보겠습니다. 필요한 것은 require('http')
const http = require('http') // http 모듈을 가져옵니다.
const server = http.createServer((req, res) => {
// createServer에 콜백을 넘겨줍니다.
res.statusCode = 200
res.end('Hello!') // 돌려줄 값
})
const PORT = 4000
server.listen(PORT, () => {
// 4000번 포트에 대해서 listen을 합니다.
console.log(`The server is listening at port: ${PORT}.`)
})
cmd 창에서 node main.js 실행.
아래처럼 오타를 발생시키면?
// ...
const server = http.createServer((req, res) => {
// createServer에 콜백을 넘겨줍니다.
res.statuscode = 200 // C를 c로 바꾸면 에러로 잡아줍니다. // 'statuscode' 속성이 'ServerResponse<IncomingMessage> & { req: IncomingMessage; }' 형식에 없습니다. 'statusCode'을(를) 사용하시겠습니까?
res.end('Hello!') // 돌려줄 값
})
// ...
# 든든한 개발 환경 설정하기 (TypeScript와 jsconfig)
타입스크립트의 설정파일에 대해서 알아보겠습니다.
본격적으로 타입스크립트를 사용해서 프로젝트를 진행한다면, 타입스크립트 설정이 필요합니다.
tsconfig파일에 프로젝트 설정을 넣게 됩니다.
하지만 우리는 자바스크립트로 진행하면서 타입스크립트의 타입 체킹만 도움을 받을 거라서 약간 다른 config파일을 사용하겠습니다. 파일이름은 jsconfig.json
jsconfig.json
{
"compilerOptions": {
"strict": true
},
"include": ["src/**/*"]
}
jsconfig.json의 레퍼런스 확인 사이트 : https://code.visualstudio.com/docs/languages/jsconfig
# 든든한 개발 환경 설정하기 (환경설정 종합)
VSCode JavaScript Development Setup
Formatting | Linting | Type checking | |
Package | prettier | eslint | typescript |
Additional dependencies | eslint-config-airbnb-base eslint-config-prettier eslint-plugin-import eslint-plugin-node |
@types/node | |
Config file | .prettierrc | .eslintrc.js | jsconfig.json |
VSCode extensions | O | O | X |
'개인노트-인강' 카테고리의 다른 글
개인노트 정리 Node.js 백엔드 part 1-3 (0) | 2023.03.21 |
---|---|
개인노트 정리 Node.js 백엔드 part 1-2 (0) | 2023.03.20 |
개인노트 nomad ES6의 정석 #14 ES2021 & ES2022 (0) | 2023.03.08 |
개인노트 nomad ES6의 정석 #13 ES2020 (0) | 2023.03.02 |
개인노트 nomad ES6의 정석 #12 Generators and Maps (0) | 2023.02.26 |