TIL_171031 Express, npm

Express

Node.js환경에서 동작하는 web application frame work

왜 등장했나?

1
2
- 여러 종류의 요청을 구별하기 위해
- Node.js의 기본 API만으로는 부족하여 더 쉬운 방법(framework)탄생 -> Express

Route

  • 클라이언트의 다양한 요청에 따라 해당 요청에 맞는 response를 위해 응답하는 방식 (경로를 지정)
1
2
3
4
5
6
7
8
// 모듈 로드
const express = require('express');
// 모듈 호출, 및 할당
const app = express();
// 라우팅: "클라이언트가 get 메소드 요청을 루트에 날린다면 -> Hello World 를 보내라"
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Example app listening on port 3000!'));

body-parser

  • 클라이언트의 요청을 구성하는 페이로드는 리퀘스트 바디에 담겨서 온다
  • express 내장 메서드 use()와 함께 사용해서 미들웨어 파이프라인을 만든다.
  • next() 메서드를 통해 다음 파이프라인 또는 라우팅으로 넘긴다.

[참고] URI 에서 .../:<path>/ 는?

  • path의 일부를 파라메터화

다양한 응답을 위해 여러가지 메소드 제공

  • 필요한 메소드를 체이닝하고, 마지막에 .send()
  • render() 는 템플릿 엔진과 함께 사용

정적 파일 응답

  • 클라이언트에게 HTML, CSS, Javascript, img 등의 정적파일로 응답
  • express 내장 미들웨어인 static 사용
  • app.use(express.static(<dir>))
  • dir: 요청한 정적 파일이 저장된 위치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const express = require('express');
const bp = require('body-parser');
const app = express();
// 3. static file middleware
app.use(express.static('statics'));
// 1. routing: localhost:3000/
app.get('/', (req, res) => res.send('hello world'));
// 2. routing: localhost:3000/json
app.get('/json', (req, res) => res.send({ msg: 'json test' }));
// 0. port: 3000
app.listen(3000);

템플릿 엔진

  • 서버 코드에 html 텍스트를 혼합하여 사용하는 일이 없도록 하기 위해 탄생
  • html 파일에서 인터폴레이션 제공
  • 종류: jade, ejs, handlebars
1
2
3
4
5
/* handlebars 예제 */
app.get('/temp/:name', (req, res) => { // URL 마지막 문자를 파라메터화한다
const { name } = req.params; // 파라메터를 받아서 변수로 저장하고
res.render('temp.handlebars', { name }); // 템플릿에 넘겨서 렌더링한 html로 응답.

todos 실습

server 코드

1
2
3
4
5
6
7
8
9
10
// server.js
require('dotenv').config() // dotenv 패키지를 사용, .env 파일(환경변수)에서 설정 로드
const express = require('express')
const mongoose = require('mongoose')
const bodyParser = require('body-parser')
const app = express();
const port = process.env.PORT || 4500; // 환경변수 포트 OR 4500
// 라우터는 바깥에 빼놓음

개발환경 구축: server-side

[설치할 패키지]

  • express, body-parser, dotenv, mongoose

폴더 트리와 각각의 역할

  • models/todo.js - db컨트롤
  • routes/todos.js - 라우터
  • /.env - dotenv 환경변수(로컬서버의 포트, mLab mongoDB 접)
  • /server.js - 서버모듈
  • package.json - npm 설정파일("start": "nodemon server.js")

**[참고]

  • npm script 키워드 ‘start’는 예약어로 run 생략 가능

  • [dotenv]
    ‘.env’파일에는 기밀정보(개인정보)접근 방법을 담아놓고
    깃허브나 서버에 올라가 오픈되지 않도록 보관. dotenv로
    .env파일을 읽어올 수 있음

1
2
3
4
5
// .env
# port number
PORT=4500
# MongoDB URI & User/Password
MONGO_URI=mongodb://<dbuser>:<dbpassword>@ds241395.mlab.com:41395/mydb

개발환경 구축: client-side

서버가 있는 곳에 클라이언트에 필요한 파일을 작성(로컬 서버니까)

파일 시스템
왼쪽(src): 개발자
오른쪽(public): webpack이 변환 & 생성

  • ES6 –babel–> ES5
  • Sass –node-sass–> CSS
  • html —-> html
  • babel + node-sass => webpack

패키지 설치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"dependencies": {
"axios": "^0.17.0", // Promise를 지원하는 Ajax 라이브러리
"babel-polyfill": "^6.26.0",
"body-parser": "^1.18.2",
"dotenv": "^4.0.0",
"express": "^4.16.2",
"mongoose": "^4.12.5"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.0",
"webpack": "^3.8.1"
}
  • webpack.config.js 파일 수정
  • npm script 수정 "build": "webpack -w"

폴더 트리와 각각의 역할

webpack.config.js 에서 모듈 엔트리로 지정되어 있으므로, 경로와 파일명이 일치해야함

  • src/
    • js/
      • app.js
    • sass/
      • partial/
      • style.scss

axios 라이브러리 사용법

  • `axios.httpMethod.(‘uri’)
    .then()
    .catch()
  • payload 전송시 객체를 바로 전달해도 된다. JSON.stringify 불필요(!)

오늘의 느낀점

  • 서버운영까지해야 요즘엔 풀스택으로 인정받을 수 있다??? –> AWS, Docker를 공부하라
  • 그런날은 너무 아득한 이야기같다 :( Todo나 잘하고나서 이야기..