-
Nodejs MVC patter SettingShare/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 = (req, res) => 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: { term: searchingBy }
} = req;
이런표현
=> 비구조화 할당
참고
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