2024-04-03.md

๐Ÿก

DIL: ๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๋”ฅ ๋‹ค์ด๋ธŒ, 5์ฃผ์ฐจ-3

์Šคํ„ฐ๋””: ์›”๊ฐ„ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์˜ค๋Š˜ ์ง„ํ–‰: ๊ฐœ์ธ๊ณต๋ถ€


DIL-week5-3_2024-04-03

| DIL ์ฃผ์ฐจ | ๋ฒ”์œ„ | ๋‚ด์šฉ | ์˜ค๋Š˜์ฐจ ์ง„๋„ | | -------- | ---- | -------------------------------------------------- | ----------- | | 5์ฃผ์ฐจ | 9์žฅ | ๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ๋„๊ตฌ๋กœ ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ ํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ | 541p~556p |

์˜ค๋Š˜ ์ฝ์€ ๋‚ด์šฉ์„ markdown์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ฉ”๋ชจ


๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ๋„๊ตฌ: Next.js

styled components

  • getInitialProps์— async ํ•จ์ˆ˜๋กœ Document context ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์Œ. new ServerStyleSheet()๋กœ sheet ์ƒ์„ฑ. document์˜ renderPage ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ. enhanceApp, sheet.collectStyles(<App {}>)
MyDocument.getInitialProps = async (
  ctx: DocumentContext
): Promise<DocumentInitialProps> => {
  const sheet = new ServerStyleSheet(); // ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
  const originalRenderPage = ctx.renderPage; // render ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅ

  try {
    ctx.renderPage = () =>
      originalRenderPage({
        // ctx.renderPage ์žฌ์ •์˜ (์„œ๋ฒ„์ธก ๋žœ๋”๋ง์— ์‚ฌ์šฉ๋  ํŽ˜์ด์ง€)
        enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />), // ์Šคํƒ€์ผ ์‹œํŠธ๋ฅผ ์ˆ˜์ง‘ํ•œ๋‹ค
      });

    const initialProps = await Document.getInitialProps(ctx); // ์ดˆ๊ธฐ ์†์„ฑ์„ ๊ฐ€์ ธ์˜จ๋‹ค
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          {sheet.getStyleElement()}
        </>
      ), // ํ˜„์žฌ ํŽ˜์ด์ง€์— ์‚ฌ์šฉ๋œ ์Šคํƒ€์ผ์‹œํŠธ ์ถ”๊ฐ€
    };
  } finally {
    sheet.seal(); // ๋งˆ์ง€๋ง‰์œผ๋กœ seal(): ์Šคํƒ€์ผ ์‹œํŠธ ์ˆ˜์ง‘์„ ์ข…๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœ
  }
};

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ์ž‘์„ฑ

  • ์˜ˆ์ œ: getServerSideProps๋กœ todo API๋ฅผ ๋ถˆ๋Ÿฌ์™€ ๋žœ๋”๋งํ•˜๋Š” ์ฝ”๋“œ
  • pages: Next.js ์˜ˆ์•ฝ์–ด | ํด๋” | ๋‚ด์šฉ | | --- | --- | | pages | ์˜ˆ์•ฝ์–ด๋กœ ์ง€์ •๋œ ํด๋”, ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ… | | components | ํŽ˜์ด์ง€ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ์•„๋‘  | | hooks | ํ•œ๋•€ํ•œ๋•€ ํ›… | | types | ์„œ๋ฒ„ ์‘๋‹ต ํƒ€์ž… ๋“ฑ, ๊ณตํ†ต ํƒ€์ž… | | utils | ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ์—์„œ ๊ณต์šฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ ํ‹ธ์„ฑ ํŒŒ์ผ |
  • ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ… ๋นผ๊ณ ๋Š” ์ •ํ•ด์ง„ ์ปจ๋ฒค์…˜์€ ์—†๋‹ค.
  • ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ๋งŒ ๋ช…ํ™•ํžˆ ๋˜์–ด ์žˆ๋‹ค๋ฉด? ๊ตฌ์กฐ๋Š” ํŒ€์˜ ๋…ผ์˜์‚ฌํ•ญ

๊ฒฐ๋ก 

  • ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์€ ์ผ์ž„
  • ๋Œ€๋‹ค์ˆ˜์˜ ์„œ๋น„์Šค๊ฐ€ ๋งˆ์ดํฌ๋กœ ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ์ง€ํ–ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์ถ•ํ•˜๋Š” ์ผ์ด ์žฆ๋‹ค
  • Template repository๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๐Ÿ‘
    • setting์—์„œ - [x] template repository ์ฒดํฌ
    • Create a new repository ์‹œ, ํ…œํ”Œ๋ฆฟ ์„ ํƒ
  • create-***-app CLI ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ์ˆ˜ ์žˆ๋‹ค (๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์ง€ํ–ฅ)

๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ ๋„๊ตฌ: ๊นƒํ—ˆ๋ธŒ 100% ํ™œ์šฉํ•˜๊ธฐ

| ์„œ๋น„์Šค | ๋‚ด์šฉ | | --------- | -------------------------------------------- | | Package | ์ด๋ฏธ์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ex) ์‚ฌ๋‚ด ๋น„๊ณต๊ฐœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ | | Project | ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ like Jira | | Pages | ๊ฐ„๋‹จ ์›น ์‚ฌ์ดํŠธ | | Codespace | ์ธ๊ณต์ง€๋Šฅ ์ฝ”๋”ฉ ์–ด์‹œ์Šคํ„ด์Šค ์„œ๋น„์Šค |

Github Action์œผ๋กœ Continuous Integration ํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ

  • Continuous Intergration์ด๋ž€?
    • ์ฝ”๋“œ๋Š” ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ
    • ์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž๋“ค์ด ์ง€์†์ ์œผ๋กœ ์ฝ”๋“œ์— ๊ธฐ์—ฌ
    • ์ฝ”๋“œ ์ค‘์•™ ์ €์žฅ์†Œ์—์„œ ์—ฌ๋Ÿฌ ๊ธฐ์—ฌ์ž๊ฐ€ ๊ธฐ์—ฌํ•œ ์ฝ”๋“œ๋ฅผ ์ง€์†์ ์œผ๋กœ ๋นŒ๋“œํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•ด ์ฝ”๋“œ์˜ ์ •ํ•ฉ์„ฑ์„ ํ™•์ธํ•˜๋Š” ๊ณผ์ •
  • ์ •ํ•ฉ์„ฑ ํ™•์ธ์€? ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค
    • ํ…Œ์ŠคํŠธ, ๋นŒ๋“œ, ์ •์  ๋ถ„์„, ๋ณด์•ˆ ์ทจ์•ฝ์  ๋ถ„์„

์  ํ‚จ์Šค Jenkins

  • ๊ณผ๊ฑฐ CI ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฃผ ์“ฐ์ธ ๋ฌด๋ฃŒ ์†”๋ฃจ์…˜
  • ๋ฒˆ๊ฑฐ๋กญ๋‹ค
    • ์„ค์น˜ํ˜•, ์„œ๋ฒ„ ๊ตฌ์ถ•, ์„œ๋ฒ„์— ์  ํ‚จ์Šค ์„ค์น˜, ์  ํ‚จ์Šค ์ €์žฅ์†Œ์™€ ์—ฐ๊ฒฐ
    • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํ•„์š”ํ•ด
  • ํŽธ๋ฆฌํ•˜๋‹ค
    • ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ๊ธฐ๋Šฅ ํ†ตํ•ฉ

๊นƒํ—ˆ๋ธŒ ์•ก์…˜

  • ๊นƒํ—ˆ๋ธŒ SaaS, ๊นƒํ—ˆ๋ธŒ ์ €์žฅ์†Œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ
    • ๋ณธ๋ž˜ ๋ชฉ์ ์€ ๊นƒํ—ˆ๋ธŒ ์ด๋ฒคํŠธ(push, PR etc)๋ฅผ ํŠธ๋ฆฌ๊ฑฐ๋กœ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ๋•๋Š” ๋„๊ตฌ์˜€๋‹ค
  • ์œ ์šฉ~ ๊ฒฝ์ œ์ ~(์ œํ•œ์  ๋ฌด๋ฃŒ) ๋น ๋ฆ„~

๊ธฐ๋ณธ ๊ฐœ๋…

| ๊ฐœ๋… | ๋‚ด์šฉ | ํŠน์ง• | | ------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------- | | runner | ํŒŒ์ผ๋กœ ์ž‘์„ฑ๋œ ๊นƒํ—ˆ๋ธŒ ์•ก์…˜์ด ์‹คํ–‰๋˜๋Š” ์„œ๋ฒ„ | ํŠน๋ณ„ํžˆ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ณต์šฉ ๊นƒํ—™ ์•ก์…˜ ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•˜๊ณ , ๋ณ„๋„์˜ ๋Ÿฌ๋„ˆ๋ฅผ ๊ตฌ์ถ•ํ•ด ์ž์ฒด์ ์œผ๋กœ ์šด์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค | | action | ๋Ÿฌ๋„ˆ์—์„œ ์‹คํ–‰๋˜๋Š” ํ•˜๋‚˜์˜ ์ž‘์—… ๋‹จ์œ„ | yaml ํŒŒ์ผ ์ž‘์„ฑ๋‚ด์šฉ์„ ํ•˜๋‚˜์˜ ์•ก์…˜์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Œ | | event | ๊นƒํ—™ ์•ก์…˜ ์‹คํ–‰์„ ์ผ์œผํ‚ค๋Š” ์ด๋ฒคํŠธ | ํ•œ ๊ฐœ ์ด์ƒ์˜ ์ด๋ฒคํŠธ ์ง€์ •, ๋ธŒ๋žœ์น˜ ์ง€์ •, PR, ์ด์Šˆ, push, schedule(cron ๋ฐฐ์น˜) | | jobs | ํ•˜๋‚˜์˜ ๋Ÿฌ๋„ˆ์—์„œ ์‹คํ–‰๋˜๋Š” ์—ฌ๋Ÿฌ ์Šคํ…์˜ ๋ชจ์Œ | ํ•˜๋‚˜์˜ ์•ก์…˜์—์„œ ์—ฌ๋Ÿฌ ์žก์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , (๊ธฐ๋ณธ)๋‚ด๋ถ€ ๊ฐ€์ƒ๋จธ์‹ ์—์„œ ๋ณ‘๋ ฌ ์‹คํ–‰ | | steps | ์žก ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚˜๋Š” ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์ž‘์—… | ์…ธ ๋ช…๋ น์–ด๋‚˜, ๋‹ค๋ฅธ ์•ก์…˜์„ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋ณ‘๋ ฌx |

  • ์Šคํ…์„ ์—ฎ์–ด์„œ ์žก์„ ๋งŒ๋“ค๊ณ , ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์žก์€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๊ณ , ์žก์„ ํ•˜๋‚˜ ์ด์ƒ ๋ชจ์•„๋‘” ๊ฒƒ์„ ์•ก์…˜์ด๋ผ ํ•˜๋ฉฐ, ์•ก์…˜์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋Ÿฌ๋„ˆ๋‹ค.

์ž‘์„ฑํ•˜๊ธฐ

  • prettier์— yaml๋„ includeํ•˜์ž
  • details ํ™•์ธ
    • ์•ก์…˜์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ <= ๊ณต๊ฐœ ์ €์žฅ์†Œ๋Š” 90์ผ, ๋น„๊ณต๊ฐœ ์ €์žฅ์†Œ๋Š” 400์ผ ์ดํ›„ ๋กœ๊ทธ ์‚ญ์ œ
  • .github/workflow
    • yml, yaml
name: some build
# ์•ก์…˜์˜ ์ด๋ฆ„, ํ•„์ˆ˜ ์•„๋‹˜

run-name: ${{ github. actor }} has been added new commit.
# ์•ก์…˜์ด ์‹คํ–‰๋  ๋•Œ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ดํ‹€๋ช…, ํ•„์ˆ˜ ์•„๋‹˜
# github.actor๋ฅผ ํ™œ์šฉํ•ด ๋ˆ„๊ฐ€ ํŠธ๋ฆฌ๊ฑฐํ–ˆ๋Š” ์ง€ ๊ตฌ๋ณ„ ๊ฐ€๋Šฅ
# ์—†์œผ๋ฉด? ํ’€๋ฆฌํ€˜ ์ด๋ฆ„ or ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€

on: # ์–ธ์ œ ์ด ์•ก์…˜์„ ์‹คํ–‰ํ•  ์ง€ ์ •์˜
  push: # ์ด๋ฒคํŠธ
    branches-ignore: # ๋ธŒ๋žœ์น˜ ์„ค์ •
      - "main"
# ์™œ ignore?
# - main ๋ธŒ๋žœ์น˜์˜ push๋Š”? PR ๋จธ์ง€ ์‹œ ๋ฐœ์ƒํ•œ๋‹ค.
# - PR merge ๋‹จ๊ณ„์—์„œ ์ด๋ฏธ CI ํ†ต๊ณผ๋˜์—ˆ์„ ๊ฒƒ์ด๋ฏ€๋กœ ์ค‘๋ณต ์‹คํ–‰

jobs: # ์•ก์…˜์—์„œ ์ˆ˜ํ–‰ํ•  ์žก(1๊ฐœ ์ด์ƒ, ๋ณ‘๋ ฌ), ํ•„์ˆ˜
  build: # ์ž„์˜ ์ง€์ • ์ด๋ฆ„, name๊ณผ ๊ฐ™์€ ์—ญํ• , ๋“ค์—ฌ์“ฐ๊ธฐ ์ง€ํ‚ค๊ธฐ
    runs-on: ubuntu-latest
    # ์–ด๋Š ํ™˜๊ฒฝ์—์„œ ํ•ด๋‹น ์ž‘์—…์ด ์‹คํ–‰๋  ์ง€ ๊ฒฐ์ •: runner
    # ๊นƒํ—ˆ๋ธŒ ์ œ๊ณต ์„œ๋ฒ„: ubuntu-latest
    # ์ปค์Šคํ…€ ๋Ÿฌ๋„ˆ๋ฅผ ์“ด๋‹ค๋ฉด? ํ•ด๋‹น ๋Ÿฌ๋„ˆ๋ช… ์ง€์ •
    # ์ปค์Šคํ…€ ๋Ÿฌ๋„ˆ ์„ค์ •์€? ์ €์žฅ์†Œ Setting > Actions > Runners์—์„œ ์ถ”๊ฐ€
    steps: # ์žก์—์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ์ •์˜
      - uses: actions/checkout@v3
        # ์Šคํ…์—์„œ ์ž‘์—…์„ actions/checkout@v3๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์—…ํ•˜๊ฒ ๋‹ค.
        # ๊นƒํ—ˆ๋ธŒ ๊ธฐ๋ณธ ์•ก์…˜, ํ•ด๋‹น ๋ธŒ๋žœ์น˜์˜ ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹์„ ๊ธฐ์ค€์œผ๋กœ ์ฒดํฌ์•„์›ƒ = ์ตœ์‹ ์ฝ”๋“œ
      - uses: actions/setup-node@v3
        # ์Šคํ…์—์„œ ์ž‘์—…์„ actions/setup-node@v3๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์—…ํ•˜๊ฒ ๋‹ค.
        # ๋Ÿฌ๋„ˆ์— Node.js๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
        with:
          node-version: 16 # ์„ค์น˜๊ฐ€๋Šฅํ•œ ๋ฒ„์ „ => ๊นƒํ—™ ์•ก์…˜ docs ๋ณด์ž
      - name: "install dependencies"
        working-directory: ./my-dir/my-app
        # cd ๊ฐ™์€ ์—ญํ• , ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์ˆ˜ํ–‰ํ•˜๊ฒ ๋‹ค
        run: npm ci # ์˜์กด์„ฑ ์„ค์น˜
      - name: "build"
        working-directory: ./my-dir/my-app
        run: npm run build # CI๋ฅผ ์œ„ํ•œ ์ž‘์—…. ๋นŒ๋“œ ์ˆ˜ํ–‰
  • ์•ก์…˜ ์ž‘์„ฑ
    • pnpm/action-setup: PNPM ์‚ฌ์šฉ ์‹œ
    • borales/action-yarn: yarn ์‚ฌ์šฉ ์‹œ
    • actions/github-script: ๊นƒํ—ˆ๋ธŒ API๋ฅผ ํ˜ธ์ถœํ•ด ํ’€๋ฆฌํ€˜์— ๋Œ“๊ธ€ ๋‹ฌ๊ธฐ
    • ์ด๋ฏธ์ง€ ์ตœ์ ํ™”, ์ž๋™ ๋ฐฐํฌ ๋“ฑ ๋‹ค์–‘ํ•œ ์ž‘์—… ๊ฐ€๋Šฅ
  • ๋ธŒ๋žœ์น˜ ๋ณดํ˜ธ ๊ทœ์น™
    • ๋ธŒ๋žœ์น˜ ๋ณดํ˜ธ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ์ฝ”๋“œ์˜ ์ •ํ•ฉ์„ฑ์„ ํ™•๋ณดํ•œ๋‹ค.
    • CI๊ฐ€ ์„ฑ๊ณตํ•œ ์ฝ”๋“œ๋งŒ ํ‘ธ์‹œ