์ฒดํฌํฌ์ธํŠธ

FE

HTML & CSS

  • HTML๋Š” ์šฉ๋„์— ๋งž๋Š” tag๋ฅผ ์ฐพ์•„์„œ ์‚ฌ์šฉ
  • HTML5 Layout ํƒœ๊ทธ๋ฅผ ํ™œ์šฉ
  • ๋ชจ๋“  ์—˜๋ฆฌ๋จผํŠธ๋“ค์€ ๊ฐ€์ง€๋Ÿฐํžˆ ๋ฐฐ์น˜ํ•ด์•ผํ•˜๊ณ , ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์„ ์œ ์ง€.
  • ๋ฐฐ์น˜๋ฅผ ํ• ๋•Œ flex ์†์„ฑ ๋˜๋Š” Position ์†์„ฑ์„ ์‚ฌ์šฉ
  • HTML,CSS ๋ธŒ๋ผ์šฐ์ € ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•œ ๋ฌธ์ œ ๋ถ„์„ ๋ฐฉ๋ฒ•

JavaScript ์™€ DOM

  • DOM ์— ๋Œ€ํ•œ ์ •์˜์™€ DOM APIs ์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ดํ•ด
  • DOM ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” querySelector ์™€ ๊ฐ™์€ API ์‚ฌ์šฉ
  • addEventListener ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•œ ์ด๋ฒคํŠธ ๋“ฑ๋ก
  • breakpoint๋ฅผ ํ™œ์šฉํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹คํ–‰ ์ค‘๋‹จ๊ณผ ๋””๋ฒ„๊น…

์„œ์ˆ ํ˜•

  • CSS ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”.
  • ์ฃผ์†Œ์ฐฝ์— URL์„ ์ž…๋ ฅ ํ›„, ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง์ด ๋ ๋•Œ๊นŒ์ง€์˜ ๊ณผ์ •์„ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”.

BE

Node.js

  • Node.js ์„ค์น˜
  • Node.js ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ ๋ฐ ๋™์ž‘์›๋ฆฌ ํ•™์Šต
  • Node.js ๊ณต์‹๋ฌธ์„œ์—์„œ API ์‚ดํŽด๋ณด๊ธฐ

Express

  • Express ์„ค์น˜
  • Express ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ๊ณผ ํŒจํ‚ค์ง€๋“ค์˜ ์—ญํ•  ์‚ดํŽด๋ณด๊ธฐ
  • Middleware์˜ ๋™์ž‘๋ฐฉ์‹ ์ดํ•ด
  • ํ…œํ”Œ๋ฆฟ ์—”์ง„ ๋ฌธ๋ฒ• ํ•™์Šต ๋ฐ ํ™œ์šฉ

์„œ์ˆ ํ˜•

  • ์ฃผ์†Œ์ฐฝ์—์„œย http://localhost:3000/blog/230801.html์„ ์ž…๋ ฅํ•ด์„œ ์‘๋‹ตํ•˜๊ธฐ๊นŒ์ง€์˜ ์ผ์–ด๋‚˜๋Š” ์ผ๋“ค์„ Express โ†’ Node.js โ†’ EventLoop โ†’ LibUV โ†’ OS(Linux) ์˜ ๊ด€์ ์—์„œ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.
  • ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์–ด๋–ค ๋Œ€์•ˆ์ด ์žˆ์„ ์ˆ˜ ์žˆ์„๊นŒ์š”?

ํ•ต์‹ฌ ๊ฒฝํ—˜ ๊ณต์œ 

์ด๋ฒคํŠธ ์œ„์ž„

๊ณตํ†ต์ ์ธ ์š”์†Œ๋“ค์— ๋Œ€ํ•ด์„œ ๋˜‘๊ฐ™์€ html ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ๋ถ€๋ถ„๋“ค์„ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์—ฌ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐœ๋ณ„์ ์ธ ์„œ๋ฒ„์˜ templating ์ž‘์—…์—์„œ๋„ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์ „์ฒด์ ์ธ ์ฝ”๋“œ์˜ ๊ธธ์ด๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ํ™œ์šฉ๋„๊ฐ€ ๋†’๋‹ค.

pug ํ…œํ”Œ๋ฆฟ ์—”์ง„์˜ ๊ฒฝ์šฐ, ์ด๋ฅผ mixin ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, ์ด mixin์€ argument๋ฅผ ๋ฐ›๊ณ  ์ด์— ํ•ด๋‹นํ•˜๋Š” html ์š”์†Œ๋“ค์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์•Œ๋˜ ๋ฆฌ์•กํŠธ์™€ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ์˜ ๊ตฌ์กฐ์™€ ๋น„์Šทํ•˜์—ฌ ์•Œ์•„๋ณด๊ฑฐ๋‚˜ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์ ์„ ๊ฐ€์กŒ๋‹ค.

mixin card(title,detail,author,date,id)
    style
        | @import url('/shared/card/css/card.css')
    include /shared/deleteConfirm/component/deleteConfirm.pug
    div.cardContainer(id=`${id}` draggable="true" data-date=`${date}`)
        form(action="post").editform(hidden)
            .form__div--cardForm
                input.form__input--title(type="text" placeholder="์ œ๋ชฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”" value=`${title}`) 
                textarea.form__textarea--cardDetail(type="text" placeholder="๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”" rows=1 maxlength=500)#cardDetail #{detail}
                .form__div--buttonWrapper
                    input.form__input__cancel-button(type="button", value="์ทจ์†Œ")
                    input.form__input__submit-button(type="button", value="๋“ฑ๋ก")
        li.generalCard(data-drag=id)
            .articleWrapper
                article
                    p.title #{title}
                    p.detail #{detail}
                p.author author by #{author}
            aside
                img.deleteTodo(src="../asset/close.svg", alt="delete", data-close=id)
                img.activeEditmode(src="../asset/pen.svg", alt="edit", data-edit=id)
        +deleteConfirm("todo")

ํ•ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐ๊ฐ์˜ todolist ์•ˆ์˜ ์นด๋“œ๋“ค์ด๋ฉฐ, ์ด๋ฅผ +card(title,detail,author,date,id)๋ฅผ ํ†ตํ•ด ๊ณ„์†ํ•ด์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ฐ”๊ฟ”์ฃผ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ฐœ๋ณ„ ์นด๋“œ์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ œ์ž‘ํ•˜๊ณ  ๋ถ™์—ฌ์ฃผ์—ˆ๋Š”๋ฐ, ๋ฌธ์ œ๋Š” ํ•ด๋‹นํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ 3๋ฒˆ์ด ์‹คํ–‰๋˜์—ˆ๋‹ค.

๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•ด๋ณด๋‹ˆ section์ด 3๊ฐœ๋กœ ๋‚˜๋‰˜์–ด์ ธ ์ด ๋˜ํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌํ˜„ํ–ˆ์—ˆ๋Š”๋ฐ, ์žฌ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ฌธ์ œ์ ์€ id๊ฐ€ ๋ชจ๋‘ ๊ฐ™์•„ ์ด๋ฅผ ํŒ๋ณ„ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ์ ์ด๋‹ค. ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์—์„œ ๋“ฑ๋กํ–ˆ๋˜ ์ด๋ฒคํŠธ๊ฐ€ ๊ฐ๊ฐ ์‹คํ–‰๋˜์–ด 3๋ฒˆ์ด ์‹คํ–‰๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๊ฒƒ์ด๋‹ค.

๊ธฐ์กด์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ ์ปดํฌ๋„ŒํŠธ์— ํ•ด๋‹นํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์—ˆ๋Š”๋ฐ,

  1. querySelectorAll๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฐ€์ ธ์™€ forEach๋ฌธ์„ ํ†ตํ•ด ๊ฐ๊ฐ์˜ ์š”์†Œ์— ์ด๋ฒคํŠธ ๋“ฑ๋ก
  2. ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์œ„์ž„ํ•˜์—ฌ ์ฒ˜๋ฆฌ ๊ฐ€ ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ 1๋ฒˆ์˜ ๊ฒฝ์šฐ ๊ฐœ๋ณ„์ ์ธ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋งŽ์•„์ง€๊ฒŒ ๋˜๋ฉด ๊ฐ๊ฐ์— ๋Œ€ํ•ด์„œ๋„ ๋ชจ๋“  ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ƒ์— ์ด์Šˆ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์œ„์—์„œ ๋ชจ๋‘ ๊ณตํ†ต์ ์œผ๋กœ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ํ•˜๋‚˜ ๋“ฑ๋กํ•˜๊ณ , ์œ„์ž„ํ•˜์—ฌ ํ•ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ๋ถ„ ํ•œ ํ›„์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ด๋ฒคํŠธ์œ„์ž„์„ ์„ ํƒํ•˜์˜€๋‹ค.
document.getElementById("sections").addEventListener("click", (event) => {
  // ๊ฐ ์„น์…˜๋ณ„ ์ด๋ฒคํŠธ๋“ค
  let addTodo = event.target.dataset.addform;
 
  if (addTodo) {
    // ๊ฐ ํผ์— ์ด๋ฒคํŠธ ์œ„์ž„
    let form = document.getElementById(addTodo);
    // ๋ณด์ด๊ฒŒ ํ•˜๋Š” ์†์„ฑ
    form.hidden = false;
 
    // ํ• ์ผ ์ถ”๊ฐ€ ํผ ์ž…๋ ฅ๋ž€ ํฌ๊ธฐ ์กฐ์ ˆ
    let detailInput = form.getElementsByClassName(
      "form__textarea--cardDetail"
    )[0];
    detailInput.addEventListener("input", adjustTextInput);
 
    // ์ฐฝ ๋‹ซ๊ธฐ ํผ
    let cancelButton = form.getElementsByClassName(
      "form__input__cancel-button"
    )[0];
    cancelButton.addEventListener("click", () => closeForm(form));
 
    let submitButton = form.getElementsByClassName(
      "form__input__submit-button"
    )[0];
    submitButton.addEventListener("click", () => {
      console.log("submit event");
    });
  }
 
  // ๊ฐ ์นด๋“œ ๊ด€๋ จ ์ด๋ฒคํŠธ๋“ค
  // ์นด๋“œ ํŒŒํŠธ(ํŽธ์ง‘ ๋ชจ๋“œ ์—ด๊ธฐ)
  let editId = event.target.dataset.edit;
  if (editId) {
    const editComponent = document.getElementById(editId);
    // Edit mode ํ™œ์„ฑํ™”
    editComponent.getElementsByClassName("editform")[0].hidden = false;
 
    // ํ• ์ผ ์ถ”๊ฐ€ ํผ ์ž…๋ ฅ๋ž€ ํฌ๊ธฐ ์กฐ์ ˆ
    let detailInput = editComponent.getElementsByClassName(
      "form__textarea--cardDetail"
    )[0];
    detailInput.addEventListener("input", adjustTextInput);
 
    // ์นด๋“œ ์ˆ˜์ • -> ์ทจ์†Œ ๋ˆŒ๋ €์„ ๋•Œ
    let cancelButton = editComponent.getElementsByClassName(
      "form__input__cancel-button"
    )[0];
    cancelButton.addEventListener("click", () => closeEditForm(editComponent));
    // ์ผ๋ฐ˜ ์นด๋“œ ์ˆจ๊ธฐ๊ธฐ
    const generalCard = editComponent.getElementsByClassName("generalCard")[0];
    if (generalCard) {
      generalCard.style.display = "none";
    }
  }
 
  // ์นด๋“œ ์‚ญ์ œํ•˜๊ธฐ
  let closeId = event.target.dataset.close;
  if (closeId) {
    const closeComponent = document.getElementById(closeId);
    closeComponent.getElementsByClassName("modalBackground")[0].style.display =
      "flex";
    closeComponent
      .getElementsByClassName("cancelButton")[0]
      .addEventListener("click", () => {
        closeComponent.getElementsByClassName(
          "modalBackground"
        )[0].style.display = "none";
      });
    closeComponent
      .getElementsByClassName("conFirmButton")[0]
      .addEventListener("click", () => {
        closeComponent.getElementsByClassName(
          "modalBackground"
        )[0].style.display = "none";
        closeComponent.remove();
      });
  }
});

FSD ํŒจํ„ด

Feature-sliced Design์€ ๋ชจ๋“ˆ ๊ฐ„์˜ ๋А์Šจํ•œ ๊ฒฐํ•ฉ๊ณผ ๋†’์€ ์‘์ง‘๋ ฅ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‰ฝ๊ฒŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์•„ํ‚คํ…์ฒ˜์ด๋‹ค. ์ด๋Ÿฌํ•œ ํŒจํ„ด์€ ์„ธ ๊ฐ€์ง€ ๊ตฌ๋ถ„ ๊ฐœ๋…์ด ์žˆ๋‹ค.

Layer

  • app
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์ด ์ดˆ๊ธฐํ™”๋˜๋Š” ๊ณณ
    • ํ”„๋กœ๋ฐ”์ด๋”, ๋ผ์šฐํ„ฐ, ์ „์—ญ ์Šคํƒ€์ผ, ์ „์—ญ ํƒ€์ž… ์„ ์–ธ ๋“ฑ
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ง„์ž…์  ์—ญํ• 
  • processes(depricated)
    • ์ด ๋ ˆ์ด์–ด๋Š” ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ์ด๋ฃจ์–ด์ง„ ๋“ฑ๋ก๊ณผ ๊ฐ™์ด ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์— ๊ฑธ์ณ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฒ˜๋ฆฌ
    • ์ด ๋ ˆ์ด์–ด๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ฐ€๋”์”ฉ ๋งˆ์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒ์  ๋ ˆ์ด์–ด์ž…๋‹ˆ๋‹ค.
  • pages
    • ์ด ๋ ˆ์ด์–ด์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŽ˜์ด์ง€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • widgets
    • ํŽ˜์ด์ง€์— ์‚ฌ์šฉ๋˜๋Š” ๋…๋ฆฝ์ ์ธ UI ์ปดํฌ๋„ŒํŠธ
  • features
    • ์ด ๋ ˆ์ด์–ด๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๊ฐ€์น˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค์™€ ๊ธฐ๋Šฅ
    • ์ข‹์•„์š”, ๋ฆฌ๋ทฐ ์ž‘์„ฑ, ์ œํ’ˆ ํ‰๊ฐ€ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์„ ํƒ์  ๋ ˆ์ด์–ด
  • entities
    • ๋น„์ฆˆ๋‹ˆ์Šค ์—”ํ‹ฐํ‹ฐ
    • ์‚ฌ์šฉ์ž, ๋ฆฌ๋ทฐ, ๋Œ“๊ธ€ ๋“ฑ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์„ ํƒ์  ๋ ˆ์ด์–ด
  • shared
    • ์ด ๋ ˆ์ด์–ด์—๋Š” ํŠน์ • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ข…์†๋˜์ง€ ์•Š์€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ์™€ ์œ ํ‹ธ๋ฆฌํ‹ฐ
    • ์—ฌ๊ธฐ์—๋Š” UI ํ‚คํŠธ, axios ์„ค์ •, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ •, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋ฌถ์ด์ง€ ์•Š์€ ํ—ฌํผ ๋“ฑ

Slices

์Šฌ๋ผ์ด์Šค๋Š” ํŠน์ • ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๊ทธ๋ฃนํ™” ํ•œ๋‹ค. ์ด์™€ ๊ฐ™์ด ํ•„์š”ํ•œ ๊ฐ’์— ๋Œ€ํ•ด์„œ ๋…๋ฆฝ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์„ธ๊ทธ๋จผํŠธ

๊ฐ ์Šฌ๋ผ์ด์Šค๋Š” ์„ธ๊ทธ๋จผํŠธ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ ๋ชฉ์ ์— ๋”ฐ๋ผ ์Šฌ๋ผ์ด์Šค ๋‚ด์˜ ์ฝ”๋“œ๋ฅผ ๋‚˜๋ˆ„๋Š”๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

  • api - ํ•„์š”ํ•œ ์„œ๋ฒ„ ์š”์ฒญ.
  • UI - ์Šฌ๋ผ์ด์Šค์˜ UI ์ปดํฌ๋„ŒํŠธ.
  • model - ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง, ์ฆ‰ ์ƒํƒœ์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ. actions ๋ฐ selectors๊ฐ€ ์ด์— ํ•ด๋‹น
  • lib - ์Šฌ๋ผ์ด์Šค ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ณด์กฐ ๊ธฐ๋Šฅ.
  • config - ์Šฌ๋ผ์ด์Šค์— ํ•„์š”ํ•œ ๊ตฌ์„ฑ๊ฐ’์ด์ง€๋งŒ ๊ตฌ์„ฑ ์„ธ๊ทธ๋จผํŠธ๋Š” ๊ฑฐ์˜ ํ•„์š”ํ•˜์ง€ ์•Š์Œ.
  • consants - ํ•„์š”ํ•œ ์ƒ์ˆ˜.

๋‚˜๋Š” ์ด๋Ÿฌํ•œ FSD๋ฅผ ์ผ๋ถ€ ์ฐธ๊ณ ํ•˜์—ฌ ๋‚˜๋งŒ์˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ํ™œ์šฉํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ ์ค‘์š”ํ•œ ์ ์ธ ์Šฌ๋ผ์ด์Šค์™€ ์„ธ๊ทธ๋จผํŠธ์˜ ๋ณธ์งˆ์— ์–ด๊ธ‹๋‚˜์ง€ ์•Š๋„๋ก ์กฐ์œจํ•˜์˜€๋‹ค.