[SeSAC X 코딩온] 웹개발자 풀스택 과정 6주차 회고 (3)-1 | 간단한 blog 만들기 실습 - 프로젝트 생성 ~ 라우팅

옹잉·2024년 2월 2일
0

💡 2/2 blog 만들기 실습 (express, ejs, multer 총 정리)

이전 시간에 실습 과제로 내주셨던 회원가입 GET, POST 실습 풀이를 오전에 잠깐 한 후
이번주 배운 내용 정리 겸 blog 만들기 실습을 했다.

📍 이전 실습 해설

리셋 버튼을 함수로 구현했는데 내장 되어있는 기능이 있다는 것을 새로 알게됐다.

	// 리셋 버튼 만드는 세 가지 방법

	  <!-- 1. onclick에 함수 직접 생성 -->
      <button type="button" onclick="clickReset()">리셋</button>
			<script>
      function clickReset() {
        const input = document.querySelectorAll("input");
        input.forEach((input) => {
          if (input.value !== "") input.value = "";
        });
      }
    </script>

      <!-- 2. 리셋 기능 제공하는 type 속성 -->
	  <button type="reset">리셋</button>

	  <!-- 3. 리셋 기능 제공하는 내장함수 -->
      <button onclick="reset()">리셋</button>		

서버에서 받아온 데이터를 ejs로 <img src="/<%= %>"> 경로 지정할 때 꼭!! 앞에 '/(slash)' 써주기

ex)
	<!-- src에 파일 경로설정 해줄 때, 앞에 꼭! / 쓰기 (ejs로 데이터 받아와서 뿌릴 때)-->
    <img class="profile" src="/<%= imgSrc%>" alt="프로필 이미지" width="200" height="200" />



📍 간단한 blog 만들기 실습 - 프로젝트 생성부터 라우팅 정리

프로젝트 생성부터 차근차근 어떤 내용을 하는지 알려주셔서 그동안 잘 모르고 썼던 것들을 정리할 수 있어서 정말 너무 좋았다!!

1. 프로젝트 생성 후 모듈 설치

  • 프로젝트 생성 : npm init -y

  • 사용할 모듈 설치 : npm i(install) express ejs multer

(.gitignore 없으면 추가 해주기 => node_modules 용량 너무 큼)


2. 기본 폴더 구조 생성

(파일이나 폴더 이름을 꼭 똑같이 지정할 필요는 없지만 대개 많이 사용하는 이름이다.)

초반에는

  • 서버 파일인 app.js
  • 페이지 모아둘 views 폴더
  • 기본 페이지가 될 views/index.ejs
  • static폴더로 지정할 public 폴더 (CSS, 프론트 JS, 이미지, 동영상 등 담을 폴더)

정도 만들고 시작하면 된다!

간단한 blog 만들기 실습 최종 폴더 구조

C:.
app.js // 서버 파일 (node app.js 로 실행)
│ package-lock.json
package.json

├─node_modules
├─public // static 폴더로 지정
│    └─css
│            normal.css

├─uploads // <input type="file">로 선택한 파일 업로드 되는 폴더
└─views // 프론트 단에 보여질 파일 (html)
       │ 404.ejs
       │ content.ejs
       │ index.ejs
       │ writeContent.ejs
       │
       └─include // ejs <%- include()%>에 넣을 파일 모음(컴포넌트라고 보면 될 듯)
                   head.ejs
                   header.ejs


처음부터 이렇게 완성한건 아니고 코드 작성 하면서 필요한 파일이나 폴더 추가함

[TIP] 트리구조 출력 명령어
CMD를 켜고,
npm init -y를 한 위치에서 tree /f 입력 -> /f : 파일까지 보여주는 옵션


3. app.js에 모듈 호출 및 미들웨어 설정

1. 사용할 모듈 호출

const express = require("express"); //express 호출
const multer = require("multer"); // multer 호출
const path = require("path"); // multer에서 쓸 path 내장 모듈 호출

const app = express(); // express를 app으로 사용
const PORT = 8080; // 열어줄 포트 번호

  /* 미들웨어 설정 및 라우팅 코드 작성 */

// ## 포트 열기
// app.listen(포트, 포트 열릴 때 동작할 함수)
app.listen(PORT, () => {
  console.log(`http://localhost:${PORT}`);
});

2. 미들웨어 설정

- 미들웨어란?
요청(req)과 응답(res) 사이에서 중간다리 역할을 하는 SW

- ex1) req의 body를 서버에서 읽을 수 있도록 도와주는 "body-parser"
- ex2) req의 file에서 보내는 파일 정보를 확인할 수 있도록 도와주는 "multer"
- ex3) static 파일 설정을 도와주는 app.use(express.static(~~~))

미들웨어 1. views 설정 (set() 이용)

/* 
    - view란?
      클라이언트에게 제공되는 화면(프론트 단 html)
      view 설정
      1. html을 보여주기 위해서 어떤 엔진을 쓸건지 (view enginge)
      2. html 파일들을 어디에 모아둘건지(views 폴더 설정)
    - view engine (ejs)
      서버에서 보낸 js 변수를 클라이언트 사용할 수 있도록 도움
      ex) ejs, pug, nunjucks, ... 등이 있지만 html과 가장 유사한 것은 ejs
*/

app.set("view engine", "ejs");
app.set("views", "./views");

미들웨어 2. static 폴더 설정

/* 
  - static 폴더란?
   외부(브라우저)에서 접근 가능한 폴더
   프론트 js, css, 이미지, 동영상 등
*/

app.use("/static", express.static(__dirname + "/public"));
app.use("/uploads", express.static(__dirname + "/uploads"));

미들웨어 3. body-parser 설정 (express 내장 모듈 -> npm i 안함)

/* 
    - req.body 기본적으로 undefined
      body-parser가 req.body를 서버측에서 사용할 수 있도록 파싱(parsing)해줌
*/

// true: queryString 모듈 사용, false: qs 모듈 사용
// 둘 다 비슷하지만 qs 모듈이 보안상 좀 더 좋다고 알려짐

app.use(express.urlencoded({ extended: false }));
app.use(express.json()); // 요청 body에서 json 정보만 가지고 오도록 설정

미들웨어 4. multer 설정
( <input type="file">일 때만 사용, 파일 업로드 안하면 사용안해도 됨! )

/* 
    - req.body <input type="file">의 정보는 String
    실제 파일을 업로드 하고, 파일 정보를 확인하기 위해서 사용

    < multer 사용 시 파일이 저장되는 디렉토리의 경로 지정하는 두 가지 방법 >
    	1. dest : 디렉토리 없을 시 자동 생성, 파일 이름도 자동 생성
        2. storage : 파일 이름 custom 가능, 디렉토리 미리 생성해야함
*/  

const uploadDetail = multer({
  storage: multer.diskStorage({
    destination: (req, file, done) => {
      done(null, "uploads/");
    },
    filename: (req, file, done) => {
     	 /*
            path 내장 함수들
            extname(파일명) : 확장자 추출
            basename(파일명, 확장자) : 확장자를 제외한 파일명 추출
            basename(경로명) : (확장자 포함된) 파일명 추출
         */
      const ext = path.extname(file.originalname);
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { files: 5 * 1024 * 1024 },
});

🤔 왜 multer에서 저장할 파일명 설정할 때 path.basename()의 두 번째 인자로 확장자를 넣어줄까?

path.basename(path [, ext])
: 파일의 이름만 표시하고 싶다면 basename의 두 번째 인자로 파일의 확장자(ext)를 넣어준다.
=> return: 'path'
cf) path.basename(path) => return 'path.ext'


여기까지 했다면 일단 기본 셋팅은 어느정도 된 상태라고 볼 수 있다.
이후 부터는 구현 단계로 프론트 단에서 보일 view 페이지와 라우팅 작업을 해주면 된다!


4. app.js에 라우팅 (맛보기)

  • 라우팅이란?
    특정 url로 특정 method에 대한 요청 처리

    • url: 사용자가 정한 url

    • method: get, post, put, patch, delete
      CRUD를 위한 것 (CRUD: 데이터를 create, read, update, delete)
         1. GET: 'R'ead, localhost:8080/sesac
           브라우저의 url에 주소를 입력하는 것은 모두 get 요청!

           ex) localhost:8080/sesac의 화면을 보기 위해서는
           /sesac의 get 요청에 대한 res(응답) 처리가 되어야 볼 수 있다.
           res.send(), res.end(), res.write(), res.render(), ...
           (이 중 res.write()는 응답이 끝나지 않음. 끝나는 처리 따로 해줘야함)

      1. POST: 'C'reate 새로운 정보를 '입력', '추가'할 때

      2. PUT(전체) & PATCH(일부): 'U'pdate 수정 관련 메소드

      3. DELETE: 'D'elete

index.ejs 라우팅

app.get("/", (req, res) => {
  // res.render("렌더할 view 파일명"[, {뿌려줄 data가 담긴 객체}])
  res.render("index", {
    user: userId,
    contentData: tempDB, //[{}, {}] - 임시 DB
  });
});



구현 관련 내용은 2편에!!
profile
틀리더라도 🌸🌈🌷예쁘게 지적해주세요💕❣️

0개의 댓글