Roxy100 / wetube-reloaded

LSGTube (Wetube app Clone) built Using NodeJS, Express, Mongo and ES6 ๐Ÿ’—

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

wetube-reloaded

Wetube Clone built using NodeJS, Express, Mongo and ES6 ๐Ÿ’—

dev script

nodemon์„ ์‹คํ–‰์‹œํ‚ค๊ณ  ํŒŒ์ผ์ด ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ด์ฃผ๋Š” nodemon์€ babel-node src/server.js๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ.

dependencies & devDependencies

dependencies -> ํ”„๋กœ์ ํŠธ๊ฐ€ ๋Œ์•„๊ฐ€๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ package๋“ค

  • ์ „์ œ node_modules ํด๋”๋Š” ๊ณต์œ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ๊ทธ๋ž˜์„œ ์œ ์ €๊ฐ€ package.json์ด ์žˆ๋Š” ์ƒํƒœ์—์„œ npm i๋งŒ ํ•˜๋ฉด express๊ฐ€ ์„ค์น˜๋จ.
  • npm์ด dependencies, devDependencies๋ฅผ ์ฐพ์•„์„œ ๋ชจ๋“  ๊ฑธ ์ž๋™์œผ๋กœ ์„ค์น˜ํ•ด์คŒ.

devDependencies -> ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐœ๋ฐœํ•  ๋•Œ ํ•„์š”ํ•œ ๊ฒƒ๋“ค.

  • ex.nodemon (ํŒŒ์ผ์„ ๋ณด๊ณ  ์žˆ๋‹ค๊ฐ€ ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋ฉด commend๋ฅผ ์žฌ์‹œ์ž‘ํ•ด์คŒ.)
  • ex.babel (server.js๋ฅผ babel-node๋กœ ๋Œ๋ฆฌ๊ฒŒ๋” ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ์—ญํ• . babel-node๊ฐ€ ์„œ๋ฒ„๋ฅผ ์ž‘๋™ํ•ด์„œ babel์ด ์„น์‹œํ•œ JavaScript๋ฅผ ์ดํ•ดํ•˜๊ณ , ํ‰๋ฒ”ํ•œ node.js๋ฐฉ์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ node.js ์„œ๋ฒ„๋ฅผ ์ž‘๋™์‹œํ‚ค๋Š” ์—ญํ• .)
  • babel-node๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, bable.config.jsonํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. babel์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ plugin(์ตœ์‹  javascript๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ)์„ ๋„ฃ์€ ๊ฒƒ.


Server

  • ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ณ  requests๋ฅผ listenํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค!!!!! ex. port4000์„ listeningํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋ณด๋ฉด cannot GET / (root page) --- ์„œ๋ฒ„์— ๋˜‘๋˜‘ ๋ฌธ(routes) ๋‘๋“œ๋ฆฌ๋Š” ์ค‘~ ---

  • URL(route)๋ฅผ ํ†ตํ•ด์„œ requests๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ.

GET request์˜ ๋œป --> ๋ธŒ๋ผ์šฐ์ €๊ฐ€ nico ์„œ๋ฒ„๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ์„œ๋ฒ„๊ฐ€ response๋ฅผ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ. (์šฐ๋ฆฌ๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ์š”์ฒญํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๋ฅผ ๋ฐ›์€ ๊ฒƒ์ด๋‹ค.)

๋ธŒ๋ผ์šฐ์ €๋Š” ์„œ๋ฒ„์—๊ฒŒ ํŽ˜์ด์ง€๋ฅผ requestํ•˜๋Š” ๊ฒƒ!

const handleHome = () => console.log("home");
app.get("/", handleHome);

-> ์„œ๋ฒ„๊ฐ€ ์ด request๋ฅผ ๋ฐ›์•„๋“ค์ด๊ณ , ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ "๊ทธ๋ž˜, ํ™ˆํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ๊ฐ€๋„ ์ข‹์•„!"๋ผ๊ณ  ํ•˜๊ณ , ๋ˆ„๊ตฐ๊ฐ€ ํ™ˆํŽ˜์ด์ง€์— ์˜ค๋ ค๊ณ  ํ•˜๋ฉด ์„œ๋ฒ„๋Š” handleHome ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.


Router

: mini application

๋„๋ฉ”์ธ ๋ณ„๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ํ•„์š”~

๋ผ์šฐํ„ฐ๋Š” ์ž‘์—…์ค‘์ธ ์ฃผ์ œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ URL์„ ๊ทธ๋ฃนํ™”ํ•ด์ค€๋‹ค.

url์ด ์–ด๋–ป๊ฒŒ ์‹œ์ž‘ํ•˜๋Š”์ง€์— ๋”ธ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•.

router๊ฐ€ ์—†์œผ๋ฉด url์„ ๊ฐœ๋ณ„๋กœ ๊ธธ๊ฒŒ ๊ธธ๊ฒŒ ๋Š˜์—ฌ์„œ ์“ฐ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ฝ”๋”ฉ์„ ํ•ด์•ผ ํ•˜๋Š”๋ฐ ๊ทธ๊ฒƒ์€ ๋งค์šฐ ๋น„ํšจ์œจ์ ์ด๋‹ค.

global Router
  • / -> Home
  • /join -> Join
  • /login -> Login
  • /search -> Search
user Router
  • /users/:id -> See User
  • /users/logout -> Log Out
  • /users/edit -> Edit My Profile
  • /users/delete -> Delete(Remove) My Profile
video Router
  • /videos/:id -> See Video
  • /videos/:id/edit -> Edit Video
  • /videos/:id/delete -> Delete(Remove) Video
  • /videos/upload -> Upload Video
more info...
  • importํ•  ๋•Œ ๊ฒฝ๋กœ์„ค์ • ์‹œ "../" : ์ง€๊ธˆ ์žˆ๋Š” ํด๋”์—์„œ ๋ฒ—์–ด๋‚˜๋Š” ๊ฑธ ์˜๋ฏธํ•จ. "./" : ์ง€๊ธˆ์˜ ์žฅ์†Œ๋ฅผ ์˜๋ฏธํ•จ.
  • export default ํ•  1๊ฐœ์˜ ๊ฒฝ์šฐ๋Š” 'export default ๊ฒฝ๋กœ';
  • export default ํ•  ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฒฝ์šฐ๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ•ด๋‹นํ•˜๋Š” ์ฝ”๋“œ ์•ž์ชฝ์— export๋ฅผ ๋„ฃ๋Š”๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ์„ importํ•  ๋•Œ object{}๋ฅผ ์“ด๋‹ค.

Router Parameter

  • ":id" -> id = ๋ณ€์ˆ˜, parameter(์ˆซ์ž ๊ฐ™์€ url์„ ๊ฐ€์ง€๋Š” ๊ฑธ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• ) -> : = ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€์ˆ˜๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ญํ• . express๋Š” request object์— ์ด parameter๋ฅผ ๋ณด๋‚ด์ค€๋‹ค.
    videoRouter.get("/upload", upload);
    videoRouter.get("/:id", see);
    videoRouter.get("/:id/edit", edit);
    


Pug

pug๋ผ๋Š” ์œ ์ €๊ฐ€ ๋ณด์—ฌ์ค„ html๋กœ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ํŒŒ์ผ์ด๋‹ค.

  • ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์ค„ ๊ฒƒ!

    app.set("view engine", "pug");
    app.set("views", process.cwd() + "/src/views")
    

pug๋ผ๋Š” ํ…œํ”Œ๋ฆฟ์— ์–ด๋Š javascript code๋ผ๋„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค. ex. footer.pug

๊ทธ javascript code๋ฅผ ์‹คํ–‰ํ•ด์„œ ๊ทธ๊ฑธ ์œ ์ €์—๊ฒŒ ์ œ๊ณตํ•ด์ฃผ๋Š” ์—ญํ• ์„ '๋ Œ๋”๋ง'์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๋ Œ๋”๋งํ•  ๋•Œ ๋ณด๋‚ด๋Š” ์ธ์ˆ˜๋Š” 2๊ฐ€์ง€์ธ๋ฐ, render("view์˜ ์ด๋ฆ„", {ํ…œํ”Œ๋ฆฟ์— ๋ณด๋‚ผ ๋ณ€์ˆ˜} )

  • ๊น”๋”ํ•œ html์„ ์ž‘์„ฑํ•˜๋„๋ก ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์šฐ๋ฆฌ์˜ html์— javascript๋ฅผ ํฌํ•จ์‹œ์ผœ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

pug์˜ ๋ณ€์ˆ˜๋ฅผ ์ ์„ ๋•Œ๋Š” #{} ์ด๋ผ๊ณ  ์“ด๋‹ค.

includes(ํŒŒ์ผํฌํ•จ)

  • ๋ฐ˜๋ณตํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ณ  partialsํด๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ํŒŒ์ผ๋กœ ๋ชจ๋“  ํ…œํ”Œ๋ฆฟ์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ex. include partials/footer.pug

inheritance(์ƒ์†) with extends and block

  • base.pug ๊ธฐ๋ณธ ๋ฒ ์ด์Šค์— ๋”ฐ๋ผ home, watch, edit์€ extends(ํ™•์žฅ) ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž„. ex. extends base.pug

  • base.pug์— content๋ฅผ ์œ„ํ•œ ๊ณต๊ฐ„์ด ๋งˆ๋ จ๋˜์–ด์•ผ ํ•จ. ex. block content block: ์ฐฝ๋ฌธ ๋˜๋Š” ๋ฌธ ์ด๋ผ ์ƒ๊ฐํ•˜์ž.


MVP styles (Minimal Viable Product.css)

https://andybrewer.github.io/mvp/ ์‚ฌ์šฉํ•ด์„œ base.pug์— ๋„ฃ๋Š”๋‹ค.

  • ๊ฝค ๊ดœ์ฐฎ์€ ์Šคํƒ€์ผ๋“ค์„ HTML ํƒœ๊ทธ์— ์ž…ํžˆ๋Š” ์—ญํ• ์„ ํ•จ.

Conditionals & Iteration & Mixin

  • Conditional : ์กฐ๊ฑด๋ฌธ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ
  • Iteration: list์˜ ๋ชจ๋“  element๋“ค์„ HTML์— ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ. -> array์˜ ๋ชจ๋“  element์— ๋Œ€ํ•ด ํŠน์ • ํ–‰๋™์„ ์ทจํ•  ๋•Œ ์‚ฌ์šฉํ•จ.
  • mixin: ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์ง€๋งŒ ๊ฐ™์€ ํ˜•ํƒœ์˜ HTML์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ.
    • footer.pug๋Š” partial๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ์™€ ๊ฐ™์ง€๋งŒ, ์ด ๋ถ€๋ถ„์€ ๋ณด์—ฌ์ฃผ๋Š” ์šฉ๋„๋กœ ์“ฐ์ผ ๋ฟ์ด๋‹ค.
    • video.pug๋Š” mixin์„ ์‚ฌ์šฉํ•˜์—ฌ, ๋ณด์—ฌ์ค„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๊นŒ์ง€ ์ถ”๊ฐ€ํ•œ ์ด์œ ์ด๋‹ค. '+' ์‚ฌ์šฉ! -> ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ผ์ข…์˜ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ Html block์ด๋ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Html์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ.
  • partial์™€ mixin์€ template์— include ํ•ด์ค˜์•ผํ•œ๋‹ค.


GET & POST

  • GET : ๊ฐ€์ ธ์˜จ๋‹ค!
  • POST : ์ˆ˜ํ–‰ํ•œ๋‹ค!
  • redirect : ๋‹ค์‹œ๋ณด๋‚ด๋‹ค
  • parameter : ๋งค๊ฐœ๋ณ€์ˆ˜
  • express๋Š” form์œผ๋กœ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์ง€ ๋ชปํ•œ๋‹ค.
  • input์— name์„ค์ •์„ ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์ „์†ก๋˜์ง€ ์•Š๋Š”๋‹ค!!!

MongoDB & Mongoose

  1. wsl ํ„ฐ๋ฏธ๋„์„ ์—ฐ๋‹ค.

  2. 'sudo apt update'์„ ์ž…๋ ฅํ•˜๊ณ ,

  3. 'sudo apt-get install mongodb'์„ ์ž…๋ ฅํ•˜๊ณ  ์„ค์น˜ํ•œ๋‹ค.

  4. 'mongod --version'์„ ์ž…๋ ฅํ•˜๊ณ  ์„ค์น˜๊ฐ€ ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

  5. ๋ฐ˜๋“œ์‹œ ๋ชฝ๊ณ ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„œ๋น„์Šค ์‹œ์ž‘!

    sudo service mongodb start

  6. ๋ชฝ๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ

    mongo

  7. ๋‚ด๊ฐ€ ๊ฐ€์ง„ db ๋ณด๊ธฐ

    show dbs

  8. ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ db ํ™•์ธ

    db

  9. ์‚ฌ์šฉํ•  db ์„ ํƒํ•˜๊ธฐ

    use dbName (ํ˜„์žฌ ์ˆ˜์—…์—์„œ๋Š” use wetube)

  10. db ์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ

    show collections

  11. db ์ปฌ๋ ‰์…˜ ์•ˆ์— documents ๋ณด๊ธฐ

    db.collectionName.find() (ํ˜„์žฌ ์ˆ˜์—…์—์„œ๋Š” db.videos.find())

  12. db ์ปฌ๋ ‰์…˜ ์•ˆ์— documents ๋ชจ๋‘ ์ œ๊ฑฐํ•˜๊ธฐ

    db.collectionName.remove({}) (ํ˜„์žฌ ์ˆ˜์—…์—์„œ๋Š” db.videos.remove({}))

  13. ๋‹ค ์‚ฌ์šฉํ–ˆ์œผ๋ฉด ์„œ๋น„์Šค๋ฅผ ์ข…๋ฃŒ!

    sudo service mongodb stop

  14. ์ง€๊ธˆ ์„œ๋น„์Šค๊ฐ€ ์‹คํ–‰์ค‘์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

    sudo service mongodb status

    • ([OK] or not [Fail])
  • CRUD -> Create / Read / Update / Delete

Callback์‹ vs Promise์‹

  • Callback์‹์œผ๋กœ ํ•˜๋ฉด,
console.log("start")   // ์ฒซ๋ฒˆ์งธ ์ˆœ์„œ,
Video.find({}, (error, videos) => {
  if(error) {
    return res.render("server-error")
  }
  return res.render("home", { pageTitle: "Home", videos });
});  // ์„ธ๋ฒˆ์งธ ์ˆœ์„œ
console.log("finished")   // ๋‘๋ฒˆ์งธ ์ˆœ์„œ,
  • Promise์‹์œผ๋กœ ํ•˜๋ฉด,
export const home = async (req, res) => {
  try {
    const videos = await Video.find({});  // await์‚ฌ์šฉ ๋•Œ๋ฌธ์— ์ด ์ฝ”๋“œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ์‹คํ–‰๋จ.
    return res.render("home", { pageTitle: "Home", videos });
  } catch {
    return res.render("server-error");
  }
};

-> await์‚ฌ์šฉ์‹œ ํ•ด๋‹นํ•จ์ˆ˜๊ฐ€ async์ผ ๋•Œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

return & render

  1. return์˜ ์—ญํ•  : ๋ณธ์งˆ์ ์ธ return์˜ ์—ญํ• ๋ณด๋‹ค๋Š” function์„ ๋งˆ๋ฌด๋ฆฌ์ง“๋Š” ์—ญํ• ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Œ.
  • ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ return์ด ์—†์–ด๋„ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด return์„ ์‚ฌ์šฉ.
  1. renderํ•œ ๊ฒƒ์€ ๋‹ค์‹œ renderํ•  ์ˆ˜ ์—†๋‹ค.
  • redirect(). sendStatus(). end() ๋“ฑ๋“ฑ ํฌํ•จ (express์—์„œ ์˜ค๋ฅ˜ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ)

More...

  • Model.findByIdAndUpdate()๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ์™€ ์ˆ˜์ •์„ ํ•œ๋ฐฉ์—~

  • Model.exists(id๋ฅผ ์ ์šฉํ•˜๋Š” ์ฝ”๋“œ) --- ex.Video.exists({_id: id})

  • ์ƒ์„ฑ์ด๋‚˜ ์—…๋ฐ์ดํŠธ ์ „ ์ž‘๋™ํ•ด์•ผ ํ•  function์˜ ํ•„์š”์„ฑ => Mongoose์˜ Middleware๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

  • Model.findOneAndDelete() >> Model.findOneAndRemove() delete๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ!

  • ์œ„ ํ‘œํ˜„์„ ์ค„์ธ ๊ฒƒ์ด : Model.findByIdAndDelete()

  • ์ •๊ทœ์‹ ํ‘œํ˜„ regular expression

    $regex: new RegExp(`keyword`, "i")  -> keyword ๋‹จ์–ดํฌํ•จ.
    $regex: new RegExp(`^${keyword}`, "i")  -> keyword๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ๋งŒ.
    $regex: new RegExp(`${keyword}$`, "i")  -> keyword๋กœ ๋๋‚˜๋Š” ๊ฒƒ๋งŒ.
    
  • req.params : video link๋ฅผ ํด๋ฆญํ•˜๋ฉด url์— id๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

  • req.body : form์„ ๋ณด๋‚ด๋ฉด ๊ทธ ๋‚ด์šฉ์„ req.body๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

  • req.query : search ํ™”๋ฉด์—์„œ keyword๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, URL์— ์žˆ๋Š” ๋ชจ๋“  ์ •๋ณด๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


์ƒํƒœ์ฝ”๋“œ Status Code

[์ƒํƒœ์ฝ”๋“œ] https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

  • 200(OK): ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ–ˆ๋‹ค๋Š” ๋œป์ด๋‹ค. ์ด๋Š” ์ฃผ๋กœ ์„œ๋ฒ„๊ฐ€ ์š”์ฒญํ•œ ํŽ˜์ด์ง€๋ฅผ ์ œ๊ณตํ–ˆ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์“ฐ์ธ๋‹ค.
  • 400(Bad Request): ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์˜ ๊ตฌ๋ฌธ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•  ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๋•Œ ์ฃผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค.
  • 404(Not Found): ์„œ๋ฒ„๊ฐ€ ์š”์ฒญํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์„ ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค. ์„œ๋ฒ„์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์žˆ์„ ๊ฒฝ์šฐ ์„œ๋ฒ„๋Š” ์ด ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์„ธ์…˜๊ณผ ์ฟ ํ‚ค Sessions and Cookies

  • Cookie ์ฟ ํ‚ค :
    1. ์ •๋ณด๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฐฉ๋ฒ•!
    2. ์„ธ์…˜ ID๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฒŒ์ฒด!
    3. ์„œ๋ฒ„๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๋Š” ์ •๋ณด. ์„ธ์…˜ id๋ฅผ ๋„ฃ์„ ๊ณณ. Only ๋ธŒ๋ผ์šฐ์ €!!!
    4. ์ฟ ํ‚ค๋Š” ์ธ์ฆ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    5. ์ฟ ํ‚ค๋Š” ๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ์ œํ•œ์ด ๋˜๊ณ , ์œ ํšจ๊ธฐ๊ฐ„์ด ์žˆ๋‹ค.
  • Session ID ์„ธ์…˜ ID:
    1. ์ฟ ํ‚ค์— ์ €์žฅ๋œ๋‹ค.
    2. ์„œ๋ฒ„(์„ธ์…˜DB)์—๋„ ์ €์žฅ๋œ๋‹ค.
    3. ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ์œ ์ €๋“ค์˜ ๋ชจ๋“  ์„ธ์…˜ ID๋ฅผ ์„ธ์…˜DB์— ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.
    4. ์ฆ‰, ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค, ์„œ๋ฒ„๋Š” ์ฟ ํ‚ค๋ฅผ ๋ฐ›์•„์„œ, ์„ธ์…˜ID๋ฅผ ๋ณด๊ณ  ์„ธ์…˜ ID์™€ ์ผ์น˜ํ•˜๋Š” ์œ ์ €๋ฅผ ์ฐพ์•„์•ผ ํ•˜๊ณ , ์ฟ ํ‚ค์•ˆ์˜ ์„ธ์…˜ID์™€ ์œ ์ €๊ฐ€ ์ผ์น˜ํ•˜๊ฒŒ ๋œ๋‹ค.
    5. ์„ธ์…˜์—์„ , ์„ธ์…˜ID๋งŒ ์ฃผ๋ฉด ๋œ๋‹ค. ์„ธ์…˜์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด๋Š” ์„ธ์…˜DB์— ์ €์žฅ๋˜์–ด์žˆ๋‹ค.
    6. ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋ฉด, ์„œ๋ฒ„๋Š” ์„ธ์…˜ID๋ฅผ DB์—์„œ ์ฐพ์œผ๋ฉด ๋œ๋‹ค!!!
  • Token ํ† ํฐ :
    1. ์„œ๋ฒ„๊ฐ€ ๊ธฐ์–ตํ•˜๋Š” ์ด์ƒํ•˜๊ฒŒ ์ƒ๊ธด String!
    2. ID ์นด๋“œ ์ฒ˜๋Ÿผ ์„œ๋ฒ„์—๊ฒŒ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค.
  • JWT :
    1. ์ •๋ณด๋ฅผ ๊ฐ–๊ณ ์žˆ๋Š” ํ† ํฐ ํ˜•์‹. ex. QR ์ฒดํฌ์ธ.
    2. ์•”ํ˜ธํ™” ๋˜์ง€ ์•Š์•„์„œ ๋ˆ„๊ตฌ๋‚˜ ์—ด์–ด์„œ ํ•ด๋‹น ์ปจํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    3. DB ์—†์ด ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.
    4. ์„œ๋ฒ„๋Š” ์œ ์ €์˜ ID๋ฅผ ๊ฐ€์ ธ๋‹ค๊ฐ€, 'sign ์•Œ๊ณ ๋ฆฌ์ฆ˜'์„ ์ด์šฉํ•ด์„œ 'sign'์„ ํ•œ๋‹ค.
    5. ํ•ด๋‹น sign๋œ ์ •๋ณด๋ฅผ stringํ˜•ํƒœ๋กœ ๋ณด๋‚ธ๋‹ค. (์„ธ์…˜ID๋ณด๋‹ค ๊ธธ๋‹ค.)
    6. ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๋ ค๋ฉด, ํ•ด๋‹น 'sign info' or 'Token'์„ ์„œ๋ฒ„์— ๋ณด๋‚ด์•ผ ํ•œ๋‹ค.
    7. ์„œ๋ฒ„๋Š” Token์„ ๋ฐ›์œผ๋ฉด, ํ•ด๋‹น sign์ด ์œ ํšจํ•œ์ง€ ์ฒดํฌํ•˜๊ฒŒ ๋˜๋ฉด, User๋กœ ์ธ์ฆํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.
    8. ์„œ๋ฒ„๋Š” ์œ ์ €๋ฅผ ์ธ์ฆํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ Token์— ์ €์žฅํ•œ๋‹ค. ํ•ด๋‹น Token์„ User์—๊ฒŒ ์ค€๋‹ค.
    9. ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋ฉด, ์„œ๋ฒ„๋Š” ํ•ด๋‹น Token์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์ฆํ•˜๋ฉด ๋œ๋‹ค!!!
  • ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ค ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•œ ์„ธ์…˜ ID์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค req.session์ด ๋‹ฌ๋ผ์„œ ๋ช‡๋ช‡ ์ •๋ณด๋ฅผ req.session object์— ๋ง๋ถ™์ธ ๊ฒƒ์ด๋‹ค.
    req.session.loggedIn = true;
    req.session.user = user;
    

์ค‘์š”

์„œ๋ฒ„๊ฐ€ ๋ธŒ๋ผ์šฐ์ €ํ•œํ…Œ ์„ธ์…˜ id๋ฅผ ์ฃผ๊ณ , ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋งˆ๋‹ค ์ฟ ํ‚ค์—์„œ ์„ธ์…˜ id๋ฅผ ๊ฐ€์ ธ์™€ ๋ณด๋‚ด์ค€๋‹ค. ์„œ๋ฒ„๊ฐ€ ๊ทธ ์„ธ์…˜id๋ฅผ ์ฝ๊ณ  ๊ทธ ์œ ์ €๊ฐ€ ๋ˆ„๊ตฐ์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

  1. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งˆ๋‹ค express-session middleware์ด ์žˆ์œผ๋ฉด,
  2. express๊ฐ€ ์•Œ์•„์„œ ๊ทธ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•œ ์„ธ์…˜ id๋ฅผ ๋งŒ๋“ค๊ณ  ๋ธŒ๋ผ์šฐ์ €ํ•œํ…Œ ๋ณด๋‚ด์ค€๋‹ค.
  3. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ฟ ํ‚ค์— ๊ทธ ์„ธ์…˜ id๋ฅผ ์ €์žฅํ•˜๊ณ  express์—์„œ๋„ ๊ทธ ์„ธ์…˜์„ ์„ธ์…˜ DB์— ์ €์žฅ๋œ๋‹ค.
  • ์„ธ์…˜ DB์— ์žˆ๋Š” id === ์ฟ ํ‚ค์— ์žˆ๋Š” id
  1. ๋ธŒ๋ผ์šฐ์ €ํ•œํ…Œ ๋ณด๋‚ด์„œ ์ฟ ํ‚ค์— ์ €์žฅํ•œ ์„ธ์…˜ id๋ฅผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ localhost:4000์˜ ๋ชจ๋“  URL์— ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋งˆ๋‹ค ์„ธ์…˜ id๋ฅผ ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ๋ณด๋‚ธ๋‹ค.
  2. ์„œ๋ฒ„์—์„œ ์–ด๋–ค ์œ ์ €๊ฐ€, ์–ด๋–ค ๋ธŒ๋ผ์šฐ์ €์—์„œ ์š”์ฒญ์„ ๋ณด๋ƒˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
  • ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ์ ์€ middleware๋กœ express-session์„ ์ถ”๊ฐ€์„ค์น˜ํ•  ๋•Œ ์ƒ์„ฑ๋จ.
  • req.sessionStore() ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํ•œ๋ฒˆ์€ undefined๊ฐ€ ๋‚˜์˜จ ์ด์œ  --> ์„ธ์…˜์€ ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๋Š”๋ฐ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฒซ ์š”์ฒญ ๋•Œ ์„ธ์…˜์„ ๊ฐ€์ง€๊ณ  ์žˆ์„๋ฆฌ๊ฐ€ ์—†๋‹ค.
  • ์ฒซ ์š”์ฒญ ๊ทธ ์ดํ›„๋ถ€ํ„ฐ ์ฒซ๋ฒˆ์งธ ์š”์ฒญ ๋•Œ ์„ธ์…˜์„ ๋งŒ๋“ค์–ด์„œ ๋„˜๊ฒผ์œผ๋‹ˆ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด๋‹น ๊ฐ’์„ ์ฟ ํ‚ค์— ์ €์žฅํ•˜๊ณ  ๋งค ์š”์ฒญ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.
  • ์„ธ์…˜์€ ์„œ๋ฒ„๊ฐ€ ๋งŒ๋“ค์–ด์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋ผ ์„œ๋ฒ„๊ฐ€ ์žฌ๋ถ€ํŒ…๋˜๋ฉด ์ดˆ๊ธฐํ™”๋œ๋‹ค. --> ๊ทธ๋ž˜์„œ DB์— ์ €์žฅํ•ด์„œ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ์„ธ์…˜์˜ ๊ฐ’์€ ์„œ๋ฒ„๊ฐ€ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ณ ์œ ๊ฐ’์ด๋‹ค๋ณด๋‹ˆ ํ•ด๋‹น ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ์š”์ฒญํ•œ ๊ฑด์— ๋Œ€ํ•ด ์œ ์ €๋ฅผ ํŠน์ •์ง€์„ ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์„œ๋ฒ„์— ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ํ•ด์„œ ๋กœ๊ทธ์ธ์ด ๋˜๋ฉด ์„œ๋ฒ„๋Š” ์„ธ์…˜id๋ฅผ ์‘๋‹ตํ•ด์ฃผ๊ณ  ๋ธŒ๋ผ์šฐ์ €๋Š” ์ฟ ํ‚คStorage์— ๊ทธ ์„ธ์…˜id๋ฅผ ๋ณด๊ด€ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๊ทธ ์ดํ›„ ๋‹ค์‹œ ์„œ๋ฒ„์— ๋ฐฉ๋ฌธํ•  ์‹œ์—๋Š” ๊ทธ ์„ธ์…˜id๋งŒ ๋ณด์—ฌ์ฃผ๋ฉด ์ž๋™์œผ๋กœ ๋กœ๊ทธ์ธ๋˜๊ฒŒ ํ•ด์ค˜์„œ ๊ณ„์† ๋กœ๊ทธ์ธํ•  ์ˆ˜๊ณ ๋ฅผ ๋œ์–ด์ค€๋‹ค๋Š” ๋œป.

๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐ€์งœ ์‚ฌ์šฉ์ž(๋ด‡)์—๊ฒŒ๋„ ์ฟ ํ‚ค๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ์„ค์ •.

  • resave: ture
  • saveUninitialized: true

๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ๋งŒ ์ฟ ํ‚ค๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ์„ค์ •.

  • resave: false
  • saveUninitialized: false

์ฟ ํ‚ค์˜ ํ”„๋กœํผํ‹ฐ & ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •

  • secret : cookie์— signํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” string.
    • signํ•˜๋Š” ์ด์œ : ์„œ๋ฒ„๊ฐ€ cookie๋ฅผ ์คฌ๋‹ค๋Š” ๊ฑธ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•จ. ์ธ์ฆํ‘œ์‹œ.
  • Domain : cookie๋ฅผ ๋งŒ๋“  ์„œ๋ฒ„๊ฐ€ ๋ˆ„๊ตฌ์ธ๊ฐ€?? ๋ธŒ๋ผ์šฐ์ €๋Š” domain์— ๋”ฐ๋ผ ์„œ๋ฒ„๋ฅผ ์ „์†กํ•œ๋‹ค.
  • Path : URL
  • Expires : ๋งŒ๋ฃŒ๋‚ ์งœ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด 'session' cookie๋กœ ์„ค์ •๋จ.
    • ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ซ์œผ๋ฉด session cookie๋Š” ์‚ฌ๋ผ์ง€๊ฑฐ๋‚˜, ์ปดํ„ฐ ์žฌ์‹œ์ž‘ํ•˜๋ฉด session์ด ์‚ฌ๋ผ์ง€๊ฒŒ ๋จ.
  • Max-age : session์ด ์–ธ์ œ ๋งŒ๋ฃŒ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ.
    cookie: {
      maxAge: 20000,
    },
    
  • .env ํŒŒ์ผ์—๋Š” ์ฝ”๋“œ์— ๋“ค์–ด๊ฐ€๋ฉด ์•ˆ๋˜๋Š” ๊ฐ’๋“ค์„ ์ถ”๊ฐ€ํ•  ๊ฒƒ. (๋‹จ, ๋ชจ๋“  ๊ฑด ๋Œ€๋ฌธ์ž๋กœ ์ ์–ด์•ผ ํ•  ๊ฒƒ!) ex. ๋ชจ๋“  API key or ๋ชจ๋“  ๋น„๋ฐ€๋กœ ํ•ด์•ผํ•˜๋Š” URL.
    1. env ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ
    2. env ํŒŒ์ผ์„ .gitignore์— ์ถ”๊ฐ€ํ•˜๊ธฐ
    3. ๋น„๋ฐ€๋กœ ํ•ด์•ผํ•˜๋Š” string์„ process.env.(ํ™˜๊ฒฝ๋ณ€์ˆ˜)๋กœ ๋ฐ”๊พธ๊ธฐ

์†Œ์…œ ๋กœ๊ทธ์ธ ๋งŒ๋“œ๋Š” ๋ฒ• (Github)

  1. https://github.com/settings/applications/new ์—ฌ๊ธฐ๋กœ ๊ฐ€์„œ ์„ค์ •์„ ํ•ด์ค€๋‹ค.
  2. Github์— User๋ฅผ ๋ณด๋‚ธ๋‹ค. --> https://github.com/login/oauth/authorize?client_id=์ž…๋ ฅ๊ฐ’
  3. URL์— ์žˆ๋Š” ๊ฒƒ๋“ค์„ ๋ฐ”๊ฟˆ์œผ๋กœ์จ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ User๋ฅผ ์Šน์ธํ•  ์ˆ˜ ์žˆ๋‹ค. --> https://github.com/login/oauth/authorize?client_id=์ž…๋ ฅ๊ฐ’&allow_signup=false&scope
  • scope : ์œ ์ €์—๊ฒŒ์„œ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ์ •๋ณด๋ฅผ ์ฝ์–ด๋‚ด๊ณ  ์–ด๋–ค ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์— ๋Œ€ํ•œ ๊ฒƒ.
  1. User๊ฐ€ Github์—์„œ "์˜ˆ"๋ผ๊ณ  ํ•˜๋ฉด Github๋Š” code๊ฐ’์„ ์ค„ ๊ฒƒ์ž„.
  2. ๊ทธ code๊ฐ’์„ ๊ฐ€์ง€๊ณ  access_token์œผ๋กœ ๋ฐ”๊พผ๋‹ค.
  3. ๊ทธ access_token์œผ๋กœ Github API๋ฅผ ์‚ฌ์šฉํ•ด User ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ž„.
  4. ์ด GET URL์„ ํ†ตํ•ด์„œ ์ธ์ฆ์„ ์œ„ํ•œ access_token์„ ๋ณด๋‚ด์ค˜์•ผ ํ•œ๋‹ค.



Webpack

  • ์•ž์„œ ๋งŒ๋“  JS์ฝ”๋“œ๋“ค์€ Babel Node.js์—์„œ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๋Š” ๊ฒƒ๋“ค์ด์ž Backend Part์ด์ง€๋งŒ,
  • Webpack ์—์„œ๋Š” ์ด์ œ๋ถ€ํ„ฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€ํ™”์‹œ์ผœ์ฃผ๋Š” ๊ฒƒ์ด์ž Frontend Part์ด๋‹ค.

devDependencies ๋กœ ์„ค์น˜

npm i webpack webpack-cli -D

Webpack --- script ์„ค์ •

"assets": "webpack --config webpack.config.js"

ํ•„์ˆ˜ ์„ค์ •

  • entry: ์†Œ์Šค์ฝ”๋“œ์ด์ž, ์šฐ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ๋“ค(์˜ˆ์œ js)
  • entry: ์ด ํ”„๋กœํผํ‹ฐ์— ์šฐ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ์˜ ๊ฒฝ๋กœ ์ž…๋ ฅ
  • output: ์ž‘์—…์ด ๋๋‚œ ๊ฒฐ๊ณผ๋ฌผ
  • filename: ์ด ํ”„๋กœํผํ‹ฐ์— ์šฐ๋ฆฌ ๊ฒฐ๊ณผ๋ฌผ์ด ๋  ํŒŒ์ผ ์ด๋ฆ„ ์ž…๋ ฅ
  • path: ์ด ํ”„๋กœํผํ‹ฐ์— ์šฐ๋ฆฌ ๊ฒฐ๊ณผ๋ฌผ ํŒŒ์ผ์„ ์–ด๋””์— ์ €์žฅํ•  ์ง€ ์ง€์ • (์ด ๊ฒฝ๋กœ๋Š” ์ ˆ๋Œ€๊ฒฝ๋กœ์—ฌ์•ผ ํ•ด!)
  • dirname: directory name ํŒŒ์ผ๊นŒ์ง€์˜ ๊ฒฝ๋กœ ์ „์ฒด
  • resolve: ๊ฒฝ๋กœ์ถ”๊ฐ€
  • mode: ๊ธฐ๋ณธ์„ค์ •์ด production mode๋กœ ์„ค์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— '๊ฐœ๋ฐœ๋ชจ๋“œ ์ค‘'์œผ๋กœ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ, development ์ถ”๊ฐ€ํ•  ๊ฒƒ!
  • watch: true ํ•˜๊ฒŒ ๋˜๋ฉด, Client ํŒŒ์ผ ํ™•์ธ์„ ์œ„ํ•ด, ๋‘˜์งธ๋Š” Backend ํŒŒ์ผ ํ™•์ธ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์ด ๋‘˜ ๋ชจ๋‘ ๋™์‹œ์— ์‹คํ–‰๋˜์–ด์•ผ๋งŒ ํ•œ๋‹ค.
  • clean: true ํ•˜๊ฒŒ ๋˜๋ฉด, output folder๋ฅผ build๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— clean ํ•ด์ฃผ๋Š” ๊ฒƒ!

์•„๋ž˜ ์ฝ”๋“œ๋“ค ์ค‘์š”~ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š” ๊ตฌ์กฐ ํŒŒ์•…ํ•˜๊ธฐ!

const path = require("path");
module.exports = {
  entry: "./src/client/js/main.js",
  mode: "development",
  watch: true,
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "assets", "js"),
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: { },
        },
      },
    ],
  },
};
  • client/js/main.js : (webpackํ•˜๊ธฐ ์ „) ์ตœ์‹ ์˜ ์„ธ๋ จ๋œ ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ณต๊ฐ„.
  • assets/js/main.js : (webpack ํ•œ ํ›„) ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋“ค.
  • base.pug๋Š” assets ํด๋”์—์„œ๋ถ€ํ„ฐ ํŒŒ์ผ๋“ค์„ ๋ถˆ๋Ÿฌ์˜ฌ ๊ฒƒ์ž„. ์ฃผ์†Œ๊ฒฝ๋กœ๋Š” /static/ URL ์ด ๋  ๊ฒƒ์ž„.

SCSS Loader

npm i sass-loader sass webpack --save-dev npm i --save-dev css-loader npm i --save-dev style-loader

      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
  • Webpack์ด ์ ํ˜€์ ธ์žˆ๋Š” ์—ญ์ˆœ์œผ๋กœ ์‹คํ–‰๋จ. sass-loader > css-loader > style-loader ์ˆœ์œผ๋กœ
    • sass-loader : scss๋ฅผ ์ผ๋ฐ˜์ ์ธ css๋กœ ๋ฐ”๊ฟ”์คŒ.
    • style-loader : css code๋ฅผ ๋ธŒ๋ผ์šฐ์ €์— ์ ์šฉํ•˜๋Š” ์—ญํ• .

MiniCssExtractPlugin

style-loader๋ฅผ ์ด์šฉํ•˜๋Š” ๋Œ€์‹ ์—, ์ด Plugin์„ ์‚ฌ์šฉํ•˜์—ฌ, css ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์—

npm i --save-dev mini-css-extract-plugin

Styles



Video Player making~~~

Time Formatting

ํƒ€์ž„ ํฌ๋งทํ•  ๋•Œ ์“ฐ๋Š” JS ์†์ž„์ˆ˜๋กœ ์“ฐ์ด๋Š” ํ•จ์ˆ˜.

new Date(5*1000)
Thu Jan 01 1970 09:00:05 GMT+0900 (ํ•œ๊ตญ ํ‘œ์ค€์‹œ)
new Date(5*1000).toISOString()
'1970-01-01T00:00:05.000Z'
new Date(5*1000).toISOString().substr(11,8)
'00:00:05'

Etc ์ด๋ฒคํŠธ ํ•จ์ˆ˜

  • input event ๋Š” ํด๋ฆญํ•˜๊ณ  ์ด๋™ํ–ˆ์„ ๋•Œ ์ผ์–ด๋‚˜๋Š” ์ด๋ฒคํŠธ ํ•จ์ˆ˜์ด๋‹ค.

Views API

Status() / Sendstatus()

  • Status() : render()ํ•˜๊ธฐ ์ „์— ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ.

    return res.status(400).render();
    
  • Sendstatus() : ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ณด๋‚ด๊ณ  ์—ฐ๊ฒฐ์„ ๋๋‚ด๋Š” ๊ฒƒ!

    return res.sendStatus(404);
    


Video Recorder ๋น„๋””์˜ค ๋…นํ™”

objectURL(url์„ ์‚ฌ์šฉํ•ด์„œ ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋งŒ๋“  ๋งˆ๋ฒ•์˜ URL)

  • createObjectUrl : ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํŒŒ์ผ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ผ ๋ฟ. (๊ทธ ํŒŒ์ผ์„ ๋ฏธ๋ฆฌ๋ณด๊ณ  ์‹ถ์„ ๋•Œ)
  • createObjectUrl()์„ ๋งค๋ฒˆ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด URL์„ ์ƒ์„ฑํ•จ.
  • ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ํŒŒ์ผ์„ ์ €์žฅํ•ด๋‘๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ ํŒŒ์ผ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” URL์„ ์ค€ ๊ฒƒ.

Webassembly Video Transcode ๋น„๋””์˜ค ๋ณ€ํ™˜

  • FFmpeg.wasm : ๋น„๋””์˜ค๋ฅผ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž์˜ ์ปดํ“จํ„ฐ๋ฅผ ์‚ฌ์šฉํ•จ.


์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋‚จ๊ธธ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” Flash message

  1. ์„œ๋ฒ„์— express-flash๋ผ๋Š” middleware ์„ค์น˜.
  2. ๋ฉ”์‹œ์ง€๋ฅผ ๋‚จ๊ธธ ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉ์ž๋ฅผ ๋ณดํ†ต redirectํ•˜๋Š” ๊ณณ(ํ…œํ”Œ๋ฆฟ์„ renderingํ•˜๋Š” ๊ณณ์ด๋‚˜ ์–ด๋””๋“ )์— req.flash()๋ฅผ ์‚ฌ์šฉํ•จ.

    req.flash("๋ฉ”์„ธ์ง€ํƒ€์ž…", "๋‚ด์šฉ")

  • flash middleware์€ messages๋ผ๊ณ  ํ•˜๋Š” locals๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค!!!


Comment Section

Api Route

  1. fetch๋กœ ๋ฐฑ์—”๋“œ์— ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ์—

    method: "POST", headers: {}, body: {}, URL๊ณผ ๋”๋ถˆ์–ด ์ด ์„ธ ๊ฐ€์ง€๋ฅผ ๋ง๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.

  2. headers์—๋Š” ์ด ์š”์ฒญ์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๋ช…์‹œํ•˜๋ฉฐ, body์—๋Š” ์‹ค์งˆ์ ์ธ ์ปจํ…์ธ ๊ฐ€ ํฌํ•จ๋œ๋‹ค.

  3. ๋”ฐ๋กœ ๋ช…์‹œํ•˜์ง€ ์•Š์„ ์‹œ์— ๋ชจ๋“  body์˜ ์ปจํ…์ธ ๋Š” Text File๋กœ์„œ ์ „์†ก๋˜๊ณ  ๋ฐ›์•„ ์ธ์‹๋œ๋‹ค.

  4. ํŠนํžˆ body: { ... }, ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋„˜๊ฒจ์ค„ ์‹œ ์™ธ๋ถ€์—์„œ ์ด ์˜ค๋ธŒ์ ํŠธ๋Š” [object Object]๋ผ๋Š” ์˜๋ฏธ ์—†๋Š” ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

  5. ์˜ค๋ธŒ์ ํŠธ์™€ ๊ทธ ์•ˆ์˜ ์„ธ๋ถ€ ๋ณ€์ˆ˜ ๋ชฉ๋ก๋“ค์„ ๋„˜๊ฒจ์ฃผ๊ณ  ์‹ถ์„ ์‹œ, JSON์ด๋ผ๋Š” ๊ทœ์•ฝ์— ์˜๊ฑฐํ•œ ์˜ค๋ธŒ์ ํŠธ ๋‚ด์˜ ๋ชจ๋“  ๊ธฐ๋ก์„ ํ…์ŠคํŠธํ™”ํ•˜์—ฌ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋•Œ JSON.stringify({ ... }) ๋ผ๋Š” ํŽธ๋ฆฌํ•œ ์ž์ฒด ํ‘œ์ค€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

  6. ๋ง๋ถ™์—ฌ headers ์•ˆ์— "Content-Type": "application/json"์ด๋ผ๋Š” ๋ช…์‹œ๋ฅผ ํ•ด ์ฃผ์–ด ์ „์†ก๋œ ํ…์ŠคํŠธ๊ฐ€ JSONํŒŒ์ผ์ž„์„ ๋ฐฑ์—”๋“œ์— ์ธ์‹์‹œ์ผœ ์ค€๋‹ค.

  7. ๋ฐฑ์—”๋“œ์— (์ด๋ฅผํ…Œ๋ฉด express๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ผ๋ฉด) app.use(express.json()); ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด ์ž์ฒด ๋‚ด์—์„œ JSON.parse("..."); JSONํŒŒ์ผ์„ ๋‹ค์‹œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ํ‘œ์ค€ ํ•จ์ˆ˜๋กœ ์š”์ฒญ body ๋‚ด์˜ ์ปจํ…์ธ ๋ฅผ ๋””์ฝ”๋”ฉํ•˜๋Š” ์ž‘์—…์„ ํ•œ๋‹ค.

About

LSGTube (Wetube app Clone) built Using NodeJS, Express, Mongo and ES6 ๐Ÿ’—


Languages

Language:JavaScript 68.1%Language:Pug 17.8%Language:SCSS 14.1%