웹 풀사이클 데브코스 TIL [Day 16] - Express Application Generator

JaeKyung Hwang·2023년 12월 8일
0
post-thumbnail

2023.12.08(금)

💻map을 이용한 간단한 api 실습

// Express module setting
const express = require('express')
const app = express()
const port = 8888
app.listen(port, () => console.log(`> Server is running on http://localhost:${port}/`))

// Data settings
let youtuber1 = {
    channelTitle : "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
    sub : "725만명",
    videoNum : "810개"
}

let youtuber2 = {
    channelTitle : "때껄룩ᴛᴀᴋᴇ ᴀ ʟᴏᴏᴋ",
    sub : "158만명",
    videoNum : "321개"
}

let youtuber3 = {
    channelTitle : "Sungha Jung",
    sub : "713만명",
    videoNum : "1.4천개"
}

let map = new Map()
map.set(1, youtuber1)
map.set(2, youtuber2)
map.set(3, youtuber3)

// REST API 설계
app.get('/youtubers/:id', (req, res) => {
    let {id} = req.params   // 문자열
    id = parseInt(id)       // 숫자로 변환
    res.json(map.get(id) || {message : "유튜버 정보를 찾을 수 없습니다."})   // 단축 평가
})

+) 유용한 크롬 확장 프로그램 : JSON Viewer

  • JSON data를 가독성 좋게 볼 수 있고 언제든지 RAW data와 toggle 가능
  • JSON data 위에 timestamp와 url을 함께 보여줌
  • folding 기능 존재
  • 다양한 테마 존재 (설정 창에서 확인 가능)

🚀Express Application Generator

저번에 혼자 공식 문서를 보며 express에서 쓸 수 있는 기능 위주로 정리를 해뒀었는데 이번에는 강사님과 Express application generator인 express-generator를 함께 설치하고 둘러보았다.

웹 애플리케이션의 기본 구조를 생성해주는 유용한 도구🛠️

⚙️Setting

  • install : npm install -g express-generator

  • launch : express [options] [dir]

    • dir을 지정한 경우 해당 dir로 이동 : cd dir
    • directory structure
      .
      ├── app.js
      ├── bin
      │   └── www
      ├── package.json
      ├── public
      │   ├── images
      │   ├── javascripts
      │   └── stylesheets
      │       └── style.css
      ├── routes
      │   ├── index.js
      │   └── users.js
      └── views
          ├── error.jade
          ├── index.jade
          └── layout.jade
      
      7 directories, 9 files
  • install dependencies : npm install

    • package.json에 들어 있는 dependency들을 설치
  • run the app : npm start

    • package.json을 보면 scripts에 start 명령어가 등록되어 있음
      {
        "name": "express-generator",
        "version": "0.0.0",
        "private": true,
        "scripts": {
          "start": "node ./bin/www"
        },
        "dependencies": {
          "cookie-parser": "~1.4.4",
          "debug": "~2.6.9",
          "express": "~4.16.1",
          "http-errors": "~1.6.3",
          "jade": "~1.11.0",
          "morgan": "~1.9.1"
        }
      }
  • terminate the app : Ctrl/⌘ + C

    • 단축키로 종료가 안되는 경우

      • window 명령어

        netstat -a // 사용 중인 포트를 확인
        taskkill /f /pid // pid 번호로 해당 포트 서버 종료

      • mac 명령어

        lsof -i :[포트번호] // 해당 로컬호스트 포트의 PID를 찾기 ex) lsof -i :8080
        kill -9 [PID번호] // PID 번호로 해당 포트 서버를 종료 ex) kill -9 53665

🕵️Skeleton File 분석

📁app.js

  • middleware를 등록하기 위한 module들을 import
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();
  • express에서는 static template files를 사용할 수 있는 template engine(PugMustache, and EJS)을 사용할 수 있음
  • app.set(name, value)
    • 특정 name에 원하는 value를 마음대로 설정할 수 있음
    • 다만 일부 name의 경우에는 이미 서버의 동작을 구성하는 데에 사용되고 있음 (app settings table)
      • 기본적으로 viewsview engine property를 set up하고 있음
        PropertyTypeDescriptionDefault
        viewsString or Arrayapplication의 views를 위한 directory 또는 directory array.
        array일 경우 express는 array 순서대로 views를 look up함.
        process.cwd() + '/views'
        view engineString확장자를 생략했을 때의 default engine extension.
        NOTE: Sub-apps will inherit the value of this setting.
        N/A (undefined)
  • app.use([path,] callback [, callback...])로 middleware 함수들을 사용 가능
    • path는 default로 '/' (root path)이기 때문에 설정해주지 않으면 모든 request에 대해 invoke됨
    • Error-handling middleware로 사용하려면 반드시 인수로 (req, res, next)가 아닌 (err, req, res, next)를 사용
  • express.static()으로 public 폴더를 static files(images, javascripts, stylesheets)을 제공할 directory로 설정
    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'pug');
    
    app.use(logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
  • 앞서 import했던 route-handling code를 request handling chain에 추가
    app.use('/', indexRouter);
    app.use('/users', usersRouter);
  • error handler 설정 & app.js export
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      next(createError(404));
    });
    
    // error handler
    app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
    
      // render the error page
      res.status(err.status || 500);
      res.render('error');
    });
    
    module.exports = app;

📂bin/www

  • npm start 명령 시 실제로 실행되는 파일

  • module import

    var app = require('../app');
    var debug = require('debug')('express-generator:server');
    var http = require('http');
  • port 설정

    var port = normalizePort(process.env.PORT || '3000');
    app.set('port', port);
  • HTTP server 생성

    var server = http.createServer(app);
  • 해당 port로 listen을 하기 시작 & event-handling

    server.listen(port);
    server.on('error', onError);
    server.on('listening', onListening);

🗂️routes

  • Router middleware를 사용하여 모듈화한 코드들이 모여 있는 폴더
  • index.js
    • [res.render(view [, locals] [, callback])](https://expressjs.com/en/5x/api.html#res.render) : view를 render해서 client에게 보냄

    • res.render('index', { title: 'Express' });

      • index : 확장자가 없지만 app.js에서 view engine, 즉 default engine extension을 ‘pug’로 설정했기 때문에 views/index.pug를 가리킴
      • { title: 'Express' } : views/index.pug에서 받는 ‘title’ 변수 값
      var express = require('express');
      var router = express.Router();
      
      /* GET home page. */
      router.get('/', function(req, res, next) {
        res.render('index', { title: 'Express' });
      });
      
      module.exports = router;
  • users.js
    var express = require('express');
    var router = express.Router();
    
    /* GET users listing. */
    router.get('/', function(req, res, next) {
      res.send('respond with a resource');
    });
    
    module.exports = router;

📌 코드 분석을 통해 알 수 있는 것

  • port number를 변경하고 싶을 때
    • bin/www에서 var port = normalizePort(process.env.PORT || '3000');부분 직접 수정
    • node의 환경 변수 process.env.PORT 이용
  • router를 추가하고 싶을 때
    1. routes 폴더에 router module router-name.js 추가하고 code 작성
    2. app.js에 해당 파일을 var newRouter = require('./routes/router-name');으로 import
    3. 원하는 path에 app.use('/router-path', newRouter);로 request handling chain에 추가

📌 추가적으로 수정하면 좋을 것 같은 부분

  • app.jsapp.set('view engine', 'pug');을 우리가 자주 사용하는 html로 변경
app.set('view engine', 'html');
  • bin/wwwserver.listen(port);callback 함수 사용하기
server.listen(port, () => console.log(`> Server is running on http://localhost:${port}/`))

Express에서 static files를 views 폴더와 public 폴더로 나눠서 관리하고 있다. 이에 대해 좀 더 생각해봤는데 html도 static file이기는 하지만 server에 의해 render될 template file이기 때문에 images, javascripts, css와는 달리 views에 저장하는 것이 용도에 맞는 것 같다. 그래서 express의 default engine extension을 html로 변경하는 것이 좋을 것 같다는 생각이 들어서 📌추가적으로 수정하면 좋을 것 같은 부분에 적어두었다.

profile
이것저것 관심 많은 개발자👩‍💻

0개의 댓글