ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nodejs MVC patter Setting
    Share/Nodejs 2020. 11. 16. 22:17

    니꼬 쌤의 wetube를 바탕으로 정리하였습니다.

    #2.1 ~ #2.25 

     

     

    Tech Stack >

     

    nodejs

    babelrc 

    es6 

     

     

    Task 1.    틀잡기 

     

    초반 틀을 잡으려면 app.js  나 init.js  를 구성하고 

    router 와 routes (url) 부터 세팅을 하면 훨씬 틀이 빨리 잡혀간다. 

     

    routes.js 

    • 내가 사용할 모든 url 정리 
    • 추후 url 하나씩 지워가며 mvc 패턴을 따라 설계 및 개발하면 에러 찾기도 쉽고 용이하다 
    // Global
    const HOME = "/";
    const JOIN = "/join";
    const LOGIN = "/login";
    const LOGOUT = "/logout";
    const SEARCH = "/search";
    
    // Users
    
    const USERS = "/users";
    const USER_DETAIL = "/:id";
    const EDIT_PROFILE = "/edit-profile";
    const CHANGE_PASSWORD = "/change-password";
    
    // Videos
    
    const VIDEOS = "/videos";
    const UPLOAD = "/upload";
    const VIDEO_DETAIL = "/:id";
    const EDIT_VIDEO = "/:id/edit";
    const DELETE_VIDEO = "/:id/delete";
    
    //js object 
    
    const routes = {
      home: HOME,
      join: JOIN,
      login: LOGIN,
      logout: LOGOUT,
      search: SEARCH,
      users: USERS,
      userDetail: id => {
        if (id) {
          return `/users/${id}`;
        } else {
          return USER_DETAIL;
        }
      },
      editProfile: EDIT_PROFILE,
      changePassword: CHANGE_PASSWORD,
      videos: VIDEOS,
      upload: UPLOAD,
      videoDetail: id => {
        if (id) {
          return `/videos/${id}`;
        } else {
          return VIDEO_DETAIL;
        }
      },
      editVideo: EDIT_VIDEO,
      deleteVideo: DELETE_VIDEO
    };
    
    export default routes;

     

    app.js 

     

    • 중앙 본사 역할 
    •  app.js 는  init.js 와 분리하여 사용할 수 있다. 
    • 입맛에 맞게 알아서 하면 될듯. 
    • 중요한 것은 app.use 및 app.set (뷰) 및 파일 입출력 관련 코드 관리 
    import express from "express";
    
    import morgan from "morgan";
    import helmet from "helmet";
    import cookieParser from "cookie-parser";
    import bodyParser from "body-parser";
    
    import {localsMiddleware} from "./middlewares";
    import routes from "./routes";  //URL 
    
    //라우터 
    import userRouter from "./routers/userRouter" //끝이 파일이름 
    import videoRouter from "./routers/videoRouter" //끝이 파일이름 
    import globalRouter from "./routers/globalRouter" //끝이 파일이름 
    
    
    
    const app = express();
    
    
    app.use(helmet());
    app.set("view engine", "pug");
    app.use(cookieParser());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(morgan("dev"));
    app.use(localsMiddleware);
    
    app.use(routes.home, globalRouter);
    app.use(routes.users, userRouter);
    app.use(routes.videos, videoRouter);
    
    export default app;

     

     

    Task 2. 라우터 / 컨트롤러 분리 

     

    • controller 와 router 를 분리 하는 것은 정말 유용
    • 분리 해서도 js 객체화하여 코드 관리를 하면 가독성도 좋고 유지보수도 베리 굳 

     

    Global Router 만 일부 살펴보면 

     

    import express from "express";
    import routes from "../routes";
    
    import { home, search } from "../controllers/videoController";
    import {
        getJoin,
        getLogin,
        postJoin,
        postLogin,
        logout,
      } from "../controllers/userController";
    
    
    const globalRouter = express.Router();
    
    
    globalRouter.get(routes.join, getJoin);
    globalRouter.post(routes.join, postJoin);
    
    globalRouter.get(routes.login, getLogin);
    globalRouter.post(routes.login, postLogin);
    
    
    globalRouter.get(routes.home, home);
    globalRouter.get(routes.search, search);
    
    
    globalRouter.get(routes.logout, logout);
    
    
    
    export default globalRouter;
    • routes 에서 url을 객체화 하여 가져옴 
    • 컨트롤로에서 함수를 가져옴 
    • 라우터 에서는 정말 그야말로 " 라우팅 " 만 하겠다!!!!! 라는 것. 

    그렇다면, 위에서 사용된 컨트롤러인 " videoController" 와 "userController" 에 가보자 

     

    //videoController 

    import { videos } from "../db";
    import routes from "../routes";
    
    
    export const home = (req, res) => {
      res.render("home", { pageTitle: "Home", videos });
    };
    
    
    
    export const search = (req, res) => {
        const {
          query: { term: searchingBy }
        } = req;
        
        console.log(req.query.term);
        
        res.render("search", { pageTitle: "Search", searchingBy, videos });
      };
    
      
    
      
    
      export const getUpload = (req, res) =>
      res.render("upload", { pageTitle: "Upload" });
    
      export const postUpload = (req, res) => {
        const {
          body: { file, title, description }
        } = req;
        // To Do: Upload and save video
        res.redirect(routes.videoDetail(324393));
      };
      
    export const videoDetail = (req, res) =>
      res.render("videoDetail", { pageTitle: "Video Detail" });
    
    export const editVideo = (req, res) =>
      res.render("editVideo", { pageTitle: "Edit Video" });
    
    export const deleteVideo = (req, res) =>
      res.render("deleteVideo", { pageTitle: "Delete Video" });

    함수별로 export 되어있음을 확인 

     

    //userController 

    import routes from "../routes";
    
    export const getJoin = (req, res) => {
      res.render("join", { pageTitle: "Join" });
    };
    export const postJoin = (req, res) => {
      const {
        body: { name, email, password, password2 }
      } = req;
      if (password !== password2) {
        res.status(400);
        res.render("join", { pageTitle: "Join" });
      } else {
        // To Do: Register User
        // To Do: Log user in
        res.redirect(routes.home);
      }
    };
    
    
    export const getLogin = (req, res) =>
      res.render("login", { pageTitle: "Log In" });
    export const postLogin = (req, res) => {
      res.redirect(routes.home);
    };
    
    export const logout = (req, res) => {
        // To Do: Process Log Out
        res.redirect(routes.home);
      };
      
    export const userDetail = (req, res) => res.render("userDetail");
    export const editProfile = (req, res) => res.render("editProfile");
    export const changePassword = (req, res) => res.render("changePassword");

     

    이렇게만 해도 왠만한  "구조/틀" 을 다 잡은 것이다.

     

    그렇다면 이제 실제 화면에 뿌려지는 것을 보기 위해 뷰(veiw) 를 해보자 

     

     

     

     

    Task3. 뷰 세분화 

     

    pug 사용 

    • routes.js 를 애초에 (Task1)에서 작업했기에, 이를 활용하여 빠짐없이 뷰 페이지를 생성한다
    • view는 
      layout / mixins / partials 을 사용 
    • 이부분은 내용 추후 정리 or 스킵 

     

     

     

     

    Task4. middleware 관리 (feat. locals) 

     

     

    import routes from "./routes";
    
    export const localsMiddleware = (req, res, next) => {
      res.locals.siteName = "SuperBaik ";
      res.locals.routes = routes;
      res.locals.user = {
        isAuthenticated: true,
        id: 1
      };
    
    
      next();
      
    };
    

     

    Task5. url 에 따른 id 값 확인 ( 모든 링크 최종확인 ) 

     

     

     

     

     

     

    느낀점 & 아리까리 사항 

     

    1. middleware 관리 와 app.use 는 express 의 표준? 이라고 보고 따르면 되는것인지.  

     

    2. 콜백함수에서 res.render 나 res.send 혹은 res.locals 등 때에 따라 다르게 지원을 하는데 어떻게 이걸 알고 vscode는 지원하는지? 

     

    3. middelware local이 개념이 매우 중요하다.  view에서도 routes를 쓸수있게 해준다.  

    이는 app.use로 계속 실행되고있기 때문인가? 

     

    4.export const home = (reqres=> res.render("home", { pageTitle: "home" });

     

     

    =>

    render 함수가  두번째 파라미터로 객체를 반환 

    pageTitle 은 key 

    "home" 은 value 

     

    근데 view에서는 왜 변수로 key를 인식 

    (templete 엔진이 할일 할) 

    var title= {
    	key : value 
    }
    
    res.render("/index", title) ; 
    
    //이것과 같은 개념. 이해하겠지 ? 

     

     

    이런식으로 객체(=pageTitle)  날려줄 때 pageTitle은 내부적으로 공유되는 전역변수와도 같은건가? 어떤 원리인지.

     

    5. ES6 왜 굳이 쓰는가? 이런 표현이 더 효율적인 이유라도 ? 

     

     

    const {

          query: { termsearchingBy }

        } = req;

     

    이런표현

     

    => 비구조화 할당 

     

    참고 

     

    sanghaklee.tistory.com/54

     

    [ECMAScript6 / ES6] 아름다운 JavaScript를 위한 ES6

    Introduction ECMAScript5는 2009.12에 나왔다. 지금은 2017년이고 ECMAScript8이 가장 최신 버전이다. 그럼에도, 아직 많은 JavaScript 문법은 ES5로 코딩되고 있다. ES6 이상으로 넘어가기 위한 몇 가지 걸림..

    sanghaklee.tistory.com

    6. req.query.term 라는 것은 어떻게 추적할 수 있을까 ? 

     

    => 그종류들에 대해서 좀더 살펴보자 추후 지속적으로 

     

     

    7. userRouter.get(routes.userDetail(), userDetail);

    어찌알고 함수로 썼을까 , id 는 함수로 관리하네?

     

    'Share > Nodejs' 카테고리의 다른 글

    webpack , scss, config파일 설정  (0) 2020.11.22
    Basic CRUD with express + mongodb  (0) 2020.11.18
    git 사용 요약  (0) 2020.11.16
    Nodejs Mysql 연동  (0) 2020.11.12
    #4. node-auction  (0) 2020.01.24

    댓글

실험중인 삶, Life is not a race