1. NPM과 모듈
01. NPM 이해하기
NPM
- Node Package Manager : Node.js프로젝트를 관리하는 필수적인 도구
- 온라인 저장소 + 커맨드라인 도구
온라인 저장소
- 수많은 오픈소스 라이브러리와 도구들이 업로드됨
- 필요한 라이브러리 도구 손쉽게 검색 가능
- 거대한 생태계
커맨드라인 도구
- 프로젝트 관리를 위한 다양한 명령어 제공
- 저장소에서 라이브러리, 도구 설치
- 프로젝트 설정/관리
- 프로젝트 의존성 관리
NPM 사용해보기
- NPM 커맨드라인 도구의 사용법을 익히는 것.
- 프로젝트의 생성, 다양한 기능 사용하는 법 등
npm init
: 프로젝트의 디렉터리 생성 > package.json 파일 만들어주고, > 이는 Node.js 프로젝트 디렉토리가 됨.
package.json
: 프로젝트 관련 정보들이 저장되는 파일. 이 파일을 수정하거나 npm명령어를 사용하여 프로젝트 정보를 수정할 수 있음.
의존성 관리하기
- 프로젝트 내에서 사용하는 라이브러리를 관리하는 방법
- 프로젝트가 실행되기 위해 라이브러리에 의존하기 때문에 이러한 라이브러리들을 dependency(의존성)이라고 함.
라이브러리란?
- 특정 기능을 수행하는 코드의 묶음
- 복잡한 기능을 직접 작성하지 않고, 다른 사람이 구현한 것을 사용하는 방법
- Node.js에서는 패키지 라고도 부름.
npm install 명령어
npm install
명령어를 통해 프로젝트 의존성을 관리 가능
npm i
로 사용도 가능
- 의존성 추가, 의존성 내려받기, 개발용 의존성 추가, 전역 패키지 추가
프로젝트에 의존성 추가하기
npm install [package-name]
- 추가된 패키지는 package.json의 Dependencies안에 추가되며, node_modulese 디렉터리에 저장됨.
dependencies vs devDependencies
$npm install [package-name] --save-dev
- 개발용 의존성을 분리하여 관리 가능.
- 개발용 의존성 : 배포 전까지만 사용하는 의존성 (e.g. 유닛 테스트 라이브러리)
--save-dev옵션을 이용하면 개발용 의존성 추가 가능
- 개발용 의존성은 package.json 의 debDependencies에 추가됨
프로젝트에 의존성 내려받기
$npm install
- 기본적으로 node_modules 디렉터리는 코드 관리나 배포시에 업로드 하지 않음.
- 의존성이 많아지면 용량이 너무 커지고, 운영체제별로 실행되는 코드가 다른 경우가 존재하게됨.
- npm install을 아무 옵션 없이 사용하면, package.json에 정의된 dependencies와 devDependencies의 의존성을 node_modules디렉터리에 내려받음
$npm install --production
: 배포할 때에는 개발용 의존성을 같이 포함할 필요가 없음. package.json의 dependencies만 node_modules에 내려받음.
의존성 버전 표기법
npm install [package-name]@[versin]
으로 패키지 버전 지정 가능.
- 버전 표기법 참고
package-lock.json
- 프로젝트에 의존성을 추가하면 Package-lock.json 이라는 파일이 생성됨.
- 프로젝트에 의존성을 추가하면 자동으로 최신버전으로 추가가 되는데, 의존성 버전이 갑자기 변경되지 않도록 설치된 버전을 고정하는 역할을 함.
전역 패키지 추가
npm install [package-name] --gloabal
- 패키지를 전역 패키지 디렉터리에 내려받음
- 커맨드라인 도구들을 주로 전역 패키지로 추가해서 사용.
- e.g. express, pm2
로컬패키지 / 전역 패키지
- 로컬 패키지 : package.json에 선언되어있고, node_modules에 저장된 패키지.
- 전역 패키지 : npm install -g를 통해 내려받아, 전역 패키지 저장소에 저장된 패키지
전역 패키지도 프로젝트에서 사용할 수 있으나, 프로젝트의 의존성이 package.json 내에 명시적으로 선언되어 있는 것이 프로젝트 관리의 좋은 방향.
의존성 삭세
npm remove [package-name]
- package.json의 dependencies와 devDependencies에서 삭제하고 node_modules에서도 삭제
스크립트 실행하기
- 스크립트란 간단한 동작을 수행하는 코드.
npm run [script-name]
명령어로 실행 가능
npm script를 사용하는 이유
- npm script 내에서 의존성 패키지를 사용할 수 있음.
- 주요 스크립트 : run / test / start / stop
- run을 제외하고 사용할 수 있으 뿐, npm 내부적으로 코드를 제공해주는 것은 아님.
- 출처 : 엘리스 SW 엔지니어 트랙
02. NPM으로 프로젝트 생성하기
- cowsay npm 실습 완료
03. NPX
npx
- npm 패키지를 설치하지 않고 사용할 수 있게 해주는 도구
- 프로젝트에 추가하거나 전역 패키지로 추가하지 않고, npx를 이용하여 바로 실행할 수 있음
npx node@12 index.js
... npx를 사용하면 node.js의 특정 버전을 사용하여 js파일을 실행할 수 있음. 프로젝트의 Node.js버전 별 실행 환경을 확인할 때 유용
gist http://...
: gist는 Github에 등록된 간단한 코드. npx를 이용하면 gist 코드를 다운받지 않고 바로 실행 가능
04. Node.js의 모듈
모듈
- 프로젝트가 커지면 기능에 맞게 코드를 분리하는 것이 중요.
- 모듈은 코드를 분리하기 위한 방법.
- 패키지는 모듈의 모음
- npm패키지들은 많은 모듈을 포함하고 있는 모음
console
- log, warn, error 함수로 로그 레벨 표시
- time, timelog, timeEnd 함수로 시간 추적.
process
- arch, argv, env 등 실행 환경 및 변수 관련 값 제공
- abort, kill, exit 프로세스 동작 관련 함수 제공
fs
- readFile, writeFile 함수로 파일 읽기, 쓰기
- Sync 함수 제공, 동기 동작
- watch 파일 /디렉터리 변경 이벤트 감지.
http
- http 서버, 클라이언트 를 위해 사용
- createServer 함수로 서버 생성
- Request 함수로 http 요청 생성
05. 모듈의 작성과 사용
module.exports = {
name,
age,
nationality,
};
exports.name // 모듈을 오브젝트로 만들고, 각 key, value 지정해서 내보내기
// 함수형 모듈
module.exports = (name, age, nationality) => {
return {
name,
age,
nationality,
};
}
---
const student = require('./elice')('elice', 5, 'korea')
- 함수형 모듈은 load한 경우 바로 실행되지 않음.
- 필요한 시점에 load된 함수를 실행하여 모듈을 사용할 수 있음.
require
- export한 모듈은 require로 불러올 수 잇음.
- require 할 때 모듈 코드가 실행됨
- Node.js의 모듈은 첫 require시에 cache, 두번 실행하지 않음
- 모듈 코드를 여러 번 실행하기 위해선 함수 모듈로 작성
require-npm
const dayjs = require('dayjs');
console.log(dayjs());
- 의존성 패키지들은 require('package-name')으로 load할 수 있음.
- 패키지를 사용하려면 node_modules에 내려받아져 있어야 함.
직접 작성한 모듈
- 현재 파일가의 상대 디렉터리로 load
- 불러온 모듈 경로가 파일인경우, 해당 파일을 load
- 불러온 모듈 경로가 디렉터리인경우, 그 경로 안에 있는 index.js파일이 load됨.
require - json
- require로 json 파일도 load가능
- object로 자동 파싱
06. ES Moduls
ES Module
- ES6에 등장한 자바스크립트의 공식적인 모듈
- 자바스크립트는 모듈을 제공하지 않았고, Node.js는 독자적인 방식을 통해 모듈을 지원하고 있었음 (commonjs)
- ES Module의 등장으로 node.js에서는 두가지 모듈을 지원할 필요가 생김.
commonjs | ES Module |
---|
module.exports | export |
require | import |
2. 웹과 Express.js
01. 웹의 이해
- World Wide Web 인터넷 상에서 동작하는 모든 서비스
- 웹 브라우저로 접속해서 이용하는 서비스, 웹사이트 (본 수업 : 웹 = 웹사이트)
02. 웹 서비스 동작 방식
웹 서비스 동작 방식
- 웹 서비스는 기본적으로 HTTP요청 & 응답의 반복으로 이루어짐
- HTTP 요청(req) : 사용자가 어떤 데이터가 필요한지를 서버에게 알리는 역할
- HTTP 응답(res) : HTTP 요청에 해당하는 적절한 데이터를 전달하는 역할
- 출처 : 엘리스 SW 엔지니어트랙
정적 웹 / 동적 웹
- WEB 1.0 > 단방향 통신, 정적 웹
- WEB 2.0 > 양방향 통신, 동적 웹
동적 웹의 두 가지 구현 방법
- CSR (Client-Side Rendering) : 프론트엔드에서 사용자가 페이지에서 보는 동적인 부분을 대부분 처리하는 방식
- 사이트가 변하는 부분들을 프론트엔드에서 처리
- 프론트엔드 코드에 페이지 리소스들이 미리 정의되어있음.
- 서버와의 통신은 API통신을 이용
- 빠른 반응이지만 페이지의 내용은 API홏출이 완료된 후에 보여짐
- 복잡한 프로젝트 구성, 큰 개발 사이즈
- SSR (Server-Side Rendering): 백엔드에서 페이지 대부분의 영역을 처리해서 프론트엔드로 전달하는 방식
- 사이트가 변하는 부분을 백엔드에서 처리
- 백엔드에서 HTML파일을 작성해서 프론트엔드로 전달
- CSR에 비해 쉬운 구성, 작은 개발 사이즈
- 로딩이 완료되면 페이지와 데이터가 한번에 표시됨
- 상대적으로 사용자가 보기엔 로딩이 느려보임
- 페이지 이동할 때 마다 다시 로딩하기 때문에 페이지 깜빡임
03. 웹 프레임워크
웹 프레임워크
- 웹 + 프레임워크 : 웹 서비스에 필요한 기능을 제공해주는 다양한 도구들의 모음
- 웹 서비스를 구성하기 위해서는 매우 많은 기능 필요.
- 하나씩 직접 만들면 너무 큰 비용/시간 발생.
- 웹 서비스는 정형화된 부분이 많아, 프레임워크로 이를 간단하게 구현 가능.
- 필요한 부분만 집중해서 개발 가능
웹 프레임워크의 기본 구성 요소
-
HTTP 요청 처리 : 어떤 데이터를 필요로하는지, 어떤 사용자로부터 요청이 수신되었는지 확인 가능
-
HTTP 응답 처리 : 응답 데이터가 어떤 형식인지, 응답 상태가 정상적지 확인
-
라우팅: HTTP 요청을 분기하는 방법을 제공. HTTP요청 URL에 대항하는 알맞은 응답의 경로를 미리 설정
-
출처 : 엘리스SW엔지니어 트랙
-
HTML Templating :SSR을 구현하기 위한 방법을 제공, 미리 페이지의 뼈대를 작성 가능.
- Express.js : Node.js의 가장 유명한 웹 프레임워크
- 그 외에도 Koa.js, Nest.js, Hapi, Sials.js, Meteor.js등..
04. Express.js 시작하기
- Express.js는 가장 유명한 웹 프레임워크
- 필요에 따라 유연하게 구조 설정 가능
- 다양한 미들웨어를 통해 필요한 기능을 간단하게 추가 가능
- 모든 동작이 명시적으로 구성되기 때문에, 웹 프레임워크 동작 방식을 이해하기 가장 좋은 프레임워크
npm init
express-generator
$npm i -g express-generator
$express my-web
$cd my-web
$npm i
$npm start
express-generator
프로젝트 생성기
- 이 생성기는 프로젝트의 기본 구조를 자동으로 생성해줌
- 빠르게 프로젝트 시작하기 좋음
- 생성된 프로젝트는 npm start로 실행 가능
npx + express-generator
- express-generator는 프로젝트 생성 이후엔 사용되지 않기 때문에, npx를 사용하는 것도 좋은 방법.
05. Express.js의 구조
06. Expres.js의 동작 방식
app.js
- app.js 에서는 express로 생성되는 app객체 확인
- app 객체는 Express.js의 기능을 담은 객체
- Express.js의 모든 동작은 app 객체에 정의됨
app.use()
: middleware를 사용하기 위한 함수.
app.listen()
: http 서버를 생성해주는 함수 (express-generator를 사용하면 http.createServer를 사용하는데 app.listen 함수로 대체할 수 있음
app.locals
: app에서 사용할 공통 상수. Express.js에선 gloabal 변수를 선언하지 않고 이 값을 사용할 수 있음.
라우팅
-
app 라우팅 / Express.Router
-
app 라우팅
: app객체에 직접 get, post, put, delete함수를 사용하셔 http method로 라우팅 할 수 있음.
-
출처 : 엘리스 SW 엔지니어 트랙
-
Express.Router
: app라우팅을 통해서는 라우팅의 핵심인 그룹화를 지원하지 않음. Express.Router를 통해 라우팅 모듈화를 할 수 있음.
-
출처 : 엘리스 SW 엔지니어 트랙
-
작성된 라우터 모듈을 app에 use 함수로 연결하여 사용할 수 있음.
-
router객체에도 하위 라우터를 use함수로 연결하여 사용할 수 있음.
라우팅 - path parameter 사용
- pat파라미터를 이용하면 주소의 일부를 변수처럼 사용할 수 있음.
- e.g. /users/:id-/users/123, /users/456 등으로 접속했을 때 라우팅 적용
- /messages/:from-:to-/message/123-456 등으로 접속했을 때 라우팅 적용
Request Handler
- 라우팅에 적용되는 함수를 Request Handler라고 부름
- HTTP 요청과 응답을 다룰 수 있는 함수로, 설정된 라우팅 경로에 해당하는 요청이 들어오면 Request Handler 함수가 실행됨.
- Router나 app의 HTTP method함수의 가장 마지막 인자로 전달되는 함수
출처 : 엘리스 SW 엔지니어 트랙
Request Handler - Request 객체의 주요 값 및 함수
출처 : 엘리스 SW 엔지니어 트랙
Request Handler - Response 객체
- HTTP 응답을 처리하는 객체
- HTTP 응답의 데이터를 전송하거나, 응답 상태 및 헤더를 설정할 수 있음.
출처 : 엘리스 SW 엔지니어 트랙
Express.js는 app 객체를 시작으로 모든 동작이 이루어짐. app객체나 Express.Router를 사용하여 라우팅을 구현할 수 있음. Request Handler를 통해 HTTP요청과 응답을 처리할 수 있음.