<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>doeunn.log</title>
    <link>https://doeunn.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 21 Jul 2026 14:25:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>doeunnkimm</managingEditor>
    <image>
      <title>doeunn.log</title>
      <url>https://tistory1.daumcdn.net/tistory/5421329/attach/32bf4585255e455fbc55bba1d5385eff</url>
      <link>https://doeunn.tistory.com</link>
    </image>
    <item>
      <title>[디프만x인프런 수강일기] CS완전정복 스터디 - 3주차 후기</title>
      <link>https://doeunn.tistory.com/284</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Dt7D/btsCQ3MixOZ/E85tHOF9TOA5VaNSkPQJq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Dt7D/btsCQ3MixOZ/E85tHOF9TOA5VaNSkPQJq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Dt7D/btsCQ3MixOZ/E85tHOF9TOA5VaNSkPQJq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Dt7D%2FbtsCQ3MixOZ%2FE85tHOF9TOA5VaNSkPQJq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1703947336402&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&quot; data-og-description=&quot;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이제는 공부하는 방식에 적응~.~&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 주부터 적용한 스터디 방식이 저한테 잘 맞는 것 같았어요. 그래서 이번 주도 강의에서 중요한 내용만 받아 적고, 설명해주시는 내용 중에 궁금한 내용을 질문과 답변 형식으로 추가 정리했어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1nKga/btsCWMvKmVc/JzI9HxjxgrvX6tGu8ksV20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1nKga/btsCWMvKmVc/JzI9HxjxgrvX6tGu8ksV20/img.png&quot; data-alt=&quot;이번 주 정리한 내용 ~.~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1nKga/btsCWMvKmVc/JzI9HxjxgrvX6tGu8ksV20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1nKga%2FbtsCWMvKmVc%2FJzI9HxjxgrvX6tGu8ksV20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;268&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이번 주 정리한 내용 ~.~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주 주제였던 `데이터베이스`는 그래도 좀 와닿는 부분이 많았어요. 예전에 공부한 적도 있고 직접 다뤄본 적도 있어서 그런지 지난 주 `운영체제` 때보다는 수월하게 강의를 들을 수도 정리할 수도 있었던 것 같아요.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;월9게모거 (월요일 9시 게더 모닥불 거기라는 뜻..)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;1396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN25kS/btsCOE7kB7Q/T85uNoKSMOwwd6Q6EqAsG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN25kS/btsCOE7kB7Q/T85uNoKSMOwwd6Q6EqAsG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN25kS/btsCOE7kB7Q/T85uNoKSMOwwd6Q6EqAsG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN25kS%2FbtsCOE7kB7Q%2FT85uNoKSMOwwd6Q6EqAsG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;580&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;1396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주도 어김없이 체크인부터 해서 서로 일주일을 어떻게 보냈는지 가볍게 이야기했어요! 사실 저는 이 시간이 제일 재밌답니다. 별 TMI가 다 나와서 웃기기도 하고 재밌더라구요 ㅋㅋ..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uJUm8/btsCN4E5KPY/yPztyCColKMigF8VWEwR01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uJUm8/btsCN4E5KPY/yPztyCColKMigF8VWEwR01/img.png&quot; data-alt=&quot;저의 3주차 TMI&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uJUm8/btsCN4E5KPY/yPztyCColKMigF8VWEwR01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuJUm8%2FbtsCN4E5KPY%2FyPztyCColKMigF8VWEwR01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;38&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저의 3주차 TMI&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저에게 3주차에는 무슨 일이 있었나 기억이 안 나서 들어가서 보니까 이런 일이 있었나보군요..! ㅋㅋㅋ 기억 상 정말 굉장히 바빴었는데... 암튼 그렇습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3주차 스터디는 저랑 비슷하게 다들 수월하게 진행되는 느낌이 있었는데, 그래도 그 와중에 직접 면접 때 받은 질문도 공유해주시고 몰랐던 내용들도 있었어서 역시나 스터디원분들 덕분에 이번 주도 의미있게 스터디를 진행할 수 있었습니다.&lt;/p&gt;</description>
      <category>디프만x인프런</category>
      <category>디프만</category>
      <category>인프런</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/284</guid>
      <comments>https://doeunn.tistory.com/284#entry284comment</comments>
      <pubDate>Sat, 30 Dec 2023 23:50:30 +0900</pubDate>
    </item>
    <item>
      <title>[디프만x인프런 수강일기] CS완전정복 스터디 - 2주차 후기</title>
      <link>https://doeunn.tistory.com/283</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFeQAu/btsCWK5LHmd/JiPSuMNCgPItykKg2vG3zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFeQAu/btsCWK5LHmd/JiPSuMNCgPItykKg2vG3zK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFeQAu/btsCWK5LHmd/JiPSuMNCgPItykKg2vG3zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFeQAu%2FbtsCWK5LHmd%2FJiPSuMNCgPItykKg2vG3zK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1703946792174&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&quot; data-og-description=&quot;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1주차가 너무 좋았어서, 기대되는 2주차&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1주차에는 제가 강의의 모든 내용(강의자분이 하시는 모든 말)을 적었던 터라 제가 더 공부하고 싶은 내용까지 할 시간이 없었어요. 그래서 이번 주부터는 중요한 내용만을 정리하고 강의자분이 추가로 설명하시는 부분은 이해하고 거기서 궁금한 점들을 더 정리했어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l4E2v/btsCLqu1ylx/AdSq9YRkjkBIrPiUHL0KbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l4E2v/btsCLqu1ylx/AdSq9YRkjkBIrPiUHL0KbK/img.png&quot; data-alt=&quot;더 궁금한 내용은 질문과 답변 형식으로 해서 정리했어요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l4E2v/btsCLqu1ylx/AdSq9YRkjkBIrPiUHL0KbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl4E2v%2FbtsCLqu1ylx%2FAdSq9YRkjkBIrPiUHL0KbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;322&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;756&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;더 궁금한 내용은 질문과 답변 형식으로 해서 정리했어요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그랬더니 좀 더 얻어가는 게 많게 공부하는 느낌이 들었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이번 주도 월요일 9시 게더 모닥불 거기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주차도 어김없이 월요일 9시에 게더에서 만났어요. 2주차 내용이 `운영체제`였어서 그런지 질문의 내용이나 답변들이 확실히 어렵더라구요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zb4Rq/btsCQ5wxCZO/jGZFEF9YsPu0TNlpbhVdkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zb4Rq/btsCQ5wxCZO/jGZFEF9YsPu0TNlpbhVdkK/img.png&quot; data-alt=&quot;제가 답변한 부분입니다  &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zb4Rq/btsCQ5wxCZO/jGZFEF9YsPu0TNlpbhVdkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZb4Rq%2FbtsCQ5wxCZO%2FjGZFEF9YsPu0TNlpbhVdkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;519&quot; height=&quot;242&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제가 답변한 부분입니다  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 알게 된 내용들이 많아서 더 귀를 쫑긋하고 스터디에 참여했던 것 같습니다 ㅎㅎ..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVsK2S/btsCWI7W5j0/t9VXvPW8DCoWlP9reTtAl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVsK2S/btsCWI7W5j0/t9VXvPW8DCoWlP9reTtAl0/img.png&quot; data-alt=&quot;매번 댓글로 호응까지 해주는 스터디원분들 덕분에 행복할지도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVsK2S/btsCWI7W5j0/t9VXvPW8DCoWlP9reTtAl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVsK2S%2FbtsCWI7W5j0%2Ft9VXvPW8DCoWlP9reTtAl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;331&quot; height=&quot;205&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;매번 댓글로 호응까지 해주는 스터디원분들 덕분에 행복할지도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;체크아웃 시간&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 주도 어김없이 체크아웃 시간으로 이번 주 스터디 진행에 대해 한번씩 돌아봤어요. 다들 운영체제는 와닿지 않아서 더 내용이 어렵게 느껴졌다고 하시더라구요. 또, 다들 질문 통해서 많이 알아가서 좋은 시간이였다고들 하셨습니다. 한 주 한 주 점점 더 알아가는 느낌이라 뿌듯하게 2주차도 마무리했습니다 :)&lt;/p&gt;</description>
      <category>디프만x인프런</category>
      <category>디프만</category>
      <category>인프런</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/283</guid>
      <comments>https://doeunn.tistory.com/283#entry283comment</comments>
      <pubDate>Sat, 30 Dec 2023 23:41:26 +0900</pubDate>
    </item>
    <item>
      <title>[디프만x인프런 수강일기] CS완전정복 스터디 - 1주차 후기</title>
      <link>https://doeunn.tistory.com/282</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ogthy/btsCTBVUVVa/ZlpKUkRCOkcDZ8pu7pzbf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ogthy/btsCTBVUVVa/ZlpKUkRCOkcDZ8pu7pzbf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ogthy/btsCTBVUVVa/ZlpKUkRCOkcDZ8pu7pzbf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fogthy%2FbtsCTBVUVVa%2FZlpKUkRCOkcDZ8pu7pzbf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure id=&quot;og_1703945874443&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&quot; data-og-description=&quot;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Msaw3/hyUXZRsMun/8FotKamdrHgKS2IUXpwx80/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hcR8u/hyUTDvLUzH/esZmnIpZzeVSdrkDkrm8L1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/jhTGA/hyUXNjcKAO/XBsJv47afJswAfyLLVl780/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;기출로 대비하는 개발자 전공면접 [CS 완전정복] 강의 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;본격적인 시작&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 1주차 스터디가 시작되었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 공부를 하면 좋을지 고민이 많았는데, 저는 CS 지식에 대해 많이 부족해서 원래 제 공부 스타일인 &quot;최대한 많이 받아적자&quot;로 시작했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAkg8R/btsCWMJheTx/yxNtPob23ekkGISXsOM4w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAkg8R/btsCWMJheTx/yxNtPob23ekkGISXsOM4w1/img.png&quot; data-alt=&quot;다 받아적어버린 나..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAkg8R/btsCWMJheTx/yxNtPob23ekkGISXsOM4w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAkg8R%2FbtsCWMJheTx%2FyxNtPob23ekkGISXsOM4w1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;370&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다 받아적어버린 나..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하니까 꼼꼼하게 하나하나 알아갈 순 있지만 시간이 꽤 많이 소요되더라구요. 강의 내용 이외에도 더 많이 알아보고 싶었는데 사실 시간이 부족해서 그러진 못했습니다.  &lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;월요일 9시는 게더에서 스터디 정기 모임 !&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약속한대로 시간에 맞춰 모닥불이 모락모락 피는 게더 그곳에서 만나 스터디를 시작했어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;1376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGa60Q/btsCP4ECSo3/mwVZQeMVprADE2EUaWRkwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGa60Q/btsCP4ECSo3/mwVZQeMVprADE2EUaWRkwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGa60Q/btsCP4ECSo3/mwVZQeMVprADE2EUaWRkwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGa60Q%2FbtsCP4ECSo3%2FmwVZQeMVprADE2EUaWRkwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;552&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;1376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스터디 방식으로 정했던 체크인 체크아웃 방식으로 스터디 모임 시작에는 서로 일주일 동안 어떻게 지냈는지 이야기하고 조금 분위기(?)를 풀고 슬슬 스터디로 넘어갔어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 스터디는 일주일 안에 `강의 듣기 + 내용 정리하기 + 목요일 저녁까지 예상 질문 2개씩 남기기 + 답변 달아오기` 이렇게 수행을 하기로 했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1734&quot; data-origin-height=&quot;1098&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8F4Xg/btsCLppp363/i2Ah3CTQbepvzjghL691v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8F4Xg/btsCLppp363/i2Ah3CTQbepvzjghL691v1/img.png&quot; data-alt=&quot;1주차 예상질문 표의 일부입니다 :)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8F4Xg/btsCLppp363/i2Ah3CTQbepvzjghL691v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8F4Xg%2FbtsCLppp363%2Fi2Ah3CTQbepvzjghL691v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;356&quot; data-origin-width=&quot;1734&quot; data-origin-height=&quot;1098&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1주차 예상질문 표의 일부입니다 :)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 스터디 모임날에는 순서대로 답변자가 질문을 읽고 답변하고 필요하다면 질문자는 의도를 설명해주는 시간으로 스터디를 진행했습니다. 중간중간에 질문자 분이 직접 면접 때 받은 질문이라고 소개해주시면서 정보 공유도 하고 좋더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 좋았던 건 질문에 대한 답변을 준비하면서 공부한 내용들을 모두가 약속한 것처럼 정리해오셨더라구요 ㅎㅎㅋㅋㅋㅋ 그래서 나중에 들어가서 한번더 찾아보기 좋았던 것 같습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;체크아웃 시간&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 예상 질문에 대한 답변을 끝내고 1주차 스터디를 마무리하기 전에 이번 주 스터디 내용에 대하 점검하는 시간으로 체크아웃 타임을 가졌어요. 그냥 이번 주 스터디하는 동안 어땠는지 이야기하는 시간이에요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다들 예상 질문을 만들고 답변하니까 더 깊게 공부를 할 수 있었고 다양한 관점에서의 질문에 답변해보니까 그것도 좋았다고 하시더라구요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 스터디였는데 모두가 열심히 해오고 생각보다 얻어가는 게 많은 시간이였던 것 같아요. 앞으로도 기대가 되는 1주차 스터디였습니다  &lt;/p&gt;</description>
      <category>디프만x인프런</category>
      <category>디프만</category>
      <category>인프런</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/282</guid>
      <comments>https://doeunn.tistory.com/282#entry282comment</comments>
      <pubDate>Sat, 30 Dec 2023 23:30:18 +0900</pubDate>
    </item>
    <item>
      <title>[디프만x인프런 수강일기] CS완전정복 스터디 OT 후기</title>
      <link>https://doeunn.tistory.com/281</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZ03Sf/btsBmRfxou9/IUyZxkKneUB6R4OaLc8BPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZ03Sf/btsBmRfxou9/IUyZxkKneUB6R4OaLc8BPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZ03Sf/btsBmRfxou9/IUyZxkKneUB6R4OaLc8BPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZ03Sf%2FbtsBmRfxou9%2FIUyZxkKneUB6R4OaLc8BPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; data-filename=&quot;CS완전정복_스터디.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;좋은 기회로 CS 스터디를 시작하다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디프만 14기로 활동하게 되면서, 인프런에서 제공하는 강의에 대해 스터디 참여를 할 수 있는 기회가 있었어요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 좋은 기회라고 생각해 냉큼(?) 참여하겠다고 했습니다  &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9개의 후원 강의들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프런 후원 강의는 아래와 같았어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 WEB파트였던 만큼 `함수형 프로그래밍과 JavaScript`도 수강하고 싶었지만 이번이 아니면 CS를 공부할 기회가 없을 것 같아 CS완전정복 스터디에 참여하게 되었답니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5DLok/btsBqDATvVw/Gl28ssYdYUBPuiHhYKn8rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5DLok/btsBqDATvVw/Gl28ssYdYUBPuiHhYKn8rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5DLok/btsBqDATvVw/Gl28ssYdYUBPuiHhYKn8rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5DLok%2FbtsBqDATvVw%2FGl28ssYdYUBPuiHhYKn8rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1170&quot; height=&quot;592&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;나 어쩌다 스터디장까지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 스터디 참여를 희망하는 분들끼리 슬랙에 초대되고 단지 얼른 시작하고 싶은 마음에 제가 커리큘럼을 대강 구성을 해서 스터디원분들께 보냈었어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzHI7r/btsBqMq1yV7/geGLoIKl7ftBcKmeGGE2gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzHI7r/btsBqMq1yV7/geGLoIKl7ftBcKmeGGE2gk/img.png&quot; data-alt=&quot;아아...혜자 반응들 무한 감사&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzHI7r/btsBqMq1yV7/geGLoIKl7ftBcKmeGGE2gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzHI7r%2FbtsBqMq1yV7%2FgeGLoIKl7ftBcKmeGGE2gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;336&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아아...혜자 반응들 무한 감사&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;같이 게더 모닥불  아래서.. OT &lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 7명의 일정을 조율해서 다같이 게더에서 만나서 첫 OT를 진행했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 OT인 만큼 정해야할 것들이 많았어요. CS 스터디를 진행하실 생각이 있으시다면 아래 리스트의 내용을 정해보시는 걸 추천드려요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스터디장&lt;/li&gt;
&lt;li&gt;스터디 운영 방식&lt;/li&gt;
&lt;li&gt;스터디 규칙&lt;/li&gt;
&lt;li&gt;스터디 장소 / 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 첫 슬랙을 보냈던 제가 스터디장이 되었답니다  &lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;우리 스터디는 말이죠&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 우선 게더에서 일주일에 1번 모여서 정기적으로 스터디를 진행하기로 했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또, 스터디 운영 방식 및 규칙에 대해서는 다음과 같았어요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일주일 동안 강의 수강하면서 개인 정리 (단, 공개된 곳에서 다같이 각자)&lt;/li&gt;
&lt;li&gt;예상 질문을 2개 이상씩 만들고 랜덤으로 분배해서 만나는 날까지 답변 준비해오기&lt;/li&gt;
&lt;li&gt;매 스터디날 마다 체크인 / 체크아웃 방식으로 짧게 나마 친해지는 시간 가지기&lt;/li&gt;
&lt;li&gt;운영 방식에 따라 일주일에 성실히 수행하지 못했을 경우 1만원 씩 벌금&lt;/li&gt;
&lt;li&gt;공지 올리면 리액션 많이많이  &lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 이런 것들을 정했습니다   저는 아무리 스터디를 위해 만났다 하더라도 서로 가까워져야 더 편한 분위기에서 더 좋은 내용들이 나오고 서로에게 도움이 되는 말들을 주고 받을 수 있을 거라고 생각하기 때문에 체크인 / 체크아웃 처럼 서로 이야기를 하는 시간도 넣었어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byhICT/btsBkkvDUWb/9cMzfSMM4b3AgUKy2oY220/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byhICT/btsBkkvDUWb/9cMzfSMM4b3AgUKy2oY220/img.png&quot; data-alt=&quot;첫날에도 가볍게 체크아웃을 해보았어요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byhICT/btsBkkvDUWb/9cMzfSMM4b3AgUKy2oY220/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyhICT%2FbtsBkkvDUWb%2F9cMzfSMM4b3AgUKy2oY220%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;224&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;첫날에도 가볍게 체크아웃을 해보았어요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;은근 나름 재밌는 거 같은데 저만 그런가요&lt;/s&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;OT를 마치고&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다들 적극적으로 의견도 내주시고 말씀도 너무 다들 웃기셔서 OT 끝나고 스터디원분들이랑 한참을 떠들다가 나갔네요,,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;970&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uvAmx/btsBkmUuoUF/3phVjlgrOZbIpUTHCLgzC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uvAmx/btsBkmUuoUF/3phVjlgrOZbIpUTHCLgzC1/img.png&quot; data-alt=&quot;역시나 반응은 혜자였다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uvAmx/btsBkmUuoUF/3phVjlgrOZbIpUTHCLgzC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuvAmx%2FbtsBkmUuoUF%2F3phVjlgrOZbIpUTHCLgzC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;521&quot; height=&quot;310&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;970&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;역시나 반응은 혜자였다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 지금 스터디에 총 7명 중 1명 WEB, 6명 SERVER 이렇게 구성되어 있는데요! WEB 한명이 접니다만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 `어느정도의 기본기 + 분명 필요한 순간이 올 거 같음`의 마음으로 시작하게 되었답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1701700508484&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;기출로 대비하는 개발자 전공면접 [CS 완전정복] - 인프런 | 강의&quot; data-og-description=&quot;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7MHNe/hyUE14P2OK/oYjj3UDr595WFMMkLW6bGK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hL7ck/hyUIFMB3z2/GAZpdfru7G36kSt4OpkC41/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/CrnJS/hyUIFsjbLA/RNxXa7RE23GWrheFpMkpak/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A0%84%EA%B3%B5%EB%A9%B4%EC%A0%91-cs-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7MHNe/hyUE14P2OK/oYjj3UDr595WFMMkLW6bGK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hL7ck/hyUIFMB3z2/GAZpdfru7G36kSt4OpkC41/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/CrnJS/hyUIFsjbLA/RNxXa7RE23GWrheFpMkpak/img.png?width=2370&amp;amp;height=948&amp;amp;face=0_0_2370_948');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;기출로 대비하는 개발자 전공면접 [CS 완전정복] - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CS 전공면접 기출 분석 [운영체제/자료구조/알고리즘/데이터베이스/네트워크]!, 딱 필요한 핵심만 추렸다!  CS 전공면접, 이제 자신있게 준비하세요. 수강생 합격수기  &amp;nbsp; [사진] &amp;nbsp; [사진] [사진&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 열심히  &lt;/p&gt;</description>
      <category>디프만x인프런</category>
      <category>디프만</category>
      <category>인프런</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/281</guid>
      <comments>https://doeunn.tistory.com/281#entry281comment</comments>
      <pubDate>Mon, 4 Dec 2023 23:39:25 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] next.config.js 옵션 알아보기</title>
      <link>https://doeunn.tistory.com/280</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Ddcs/btslLEcb2hm/0554ZSKR5DQUdDeV4CUKck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Ddcs/btslLEcb2hm/0554ZSKR5DQUdDeV4CUKck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Ddcs/btslLEcb2hm/0554ZSKR5DQUdDeV4CUKck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Ddcs%2FbtslLEcb2hm%2F0554ZSKR5DQUdDeV4CUKck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Configuration&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CRA로 프로젝트를 만들었을 때는 webpack config 등을 커스텀하려고 하면 React에 기본으로 셋업되어 있는 configuration을 해제해서 직접 커스터마이징할 수 있게 하거나(`npm run eject`), carco(Create React App Configuration Override)와 같은 도구 등을 사용하여야 했습니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;next.config.js&lt;/b&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js에서는 기존에 있는 것을 eject 하거나 craco 같은 도구를 쓸 필요없이 root 디렉토리에 `next.config.js`을 저장해 두고 그곳에서 필요한 여러 configuration을 추가하면 됩니다. 그렇게 추가한 config는 서버를 띄우거나 build하는 타이밍에 사용됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;환경 변수&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 작성해 주면 `process.env.{ 환경변수 이름 }`으로 환경 변수를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688031049367&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  env: {
    customKey: 'TEST NEXT CONFIG',
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 페이지에서 `&lt;b&gt;process.env.customKey&lt;/b&gt;`를 콘솔 명령어를 통해 확인해 보았더니 아래와 같이 잘 나오는 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;23&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMyrP7/btslRHMsnQD/BM65tGMt4ttndmimR5qDs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMyrP7/btslRHMsnQD/BM65tGMt4ttndmimR5qDs1/img.png&quot; data-alt=&quot;콘솔 명령&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMyrP7/btslRHMsnQD/BM65tGMt4ttndmimR5qDs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMyrP7%2FbtslRHMsnQD%2FBM65tGMt4ttndmimR5qDs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;155&quot; height=&quot;23&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;23&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;콘솔 명령&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js/basePath&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Base Path&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Base Path는 프로젝트의 구조를 커스텀할 때 활용합니다. 이를 통해 모든 경로의 base path를 변경해줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688031444526&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  basePath: '/docs',
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 basePath는 `/`이기 때문에 &amp;lt;Link&amp;gt; 컴포넌트나 &amp;lt;Image&amp;gt; 컴포넌트에 경로를 입력해주려고 할 때 `/docs/hello` 이런 식으로 입력을 했었다면 basePath를 `/docs`로 입력하고서는 `/hello`만 입력해도 `/docs/hello`로 된다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Rewrites&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청 경로를 다른 경로로 매핑할 수 있습니다. rewrite는 URL 프록시 역할을 하고, 요청 경로를 마스킹하여 &lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: start;&quot;&gt;사용자가 사이트에서 자신의 위치를 ​​변경하지 않은 것처럼 보이게 합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Rewrite vs Redirect&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;공통점&lt;/b&gt;&lt;br /&gt;특정 path에 접근시 정해진 화면이 보이도록 한다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;차이점&lt;/b&gt;&lt;br /&gt;rewrite는 유저가 입력한 url&amp;nbsp; 그대로 유저에게 보여주어 유저는 화면이 변경된지 모른다.&lt;br /&gt;redirect는 정해진 path로 url이 변경된다.&lt;br /&gt;&lt;br /&gt;예를 들어, test.com/old로 접근했을 때 /new로 변경되도록 설정했다면&lt;br /&gt;rewrite는 test.com/old 인채로 /new의 화면이 보여지고, redirect는 test.com/old에 진입하자마자 /new로 경로를 변경해 버린다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rewrite는 `source`와 `destination`이 필요합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;source : 들어오는 요청 경로&lt;/li&gt;
&lt;li&gt;destination : 라우팅하려는 경로&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688032639333&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  async rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ]
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로, &lt;b&gt;rewrites도 slug처럼 작동하게 하고 싶다면&lt;/b&gt; 아래와 같이 작성해주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1688032759701&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  async rewrites() {
    return [
      {
        source: '/about/:slug+',
        destination: '/',
      },
    ]
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 `/about/aaa`와 같이 about과 관련된 모든 url에 대해 모두 `/`로 rewrite하겠다라고 작성해줄 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Header, Cookies, Query를 매칭해서 rewrites도 가능&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헤더, 쿠키, 쿼리 값도 필드와 일치할 때 rewrites하도록도 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;has
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;type: 'header' | 'cookie' | 'query' | 'host'&lt;/li&gt;
&lt;li&gt;key: 일치시킬 유형의 키 이름&lt;/li&gt;
&lt;li&gt;value: 확인할 값&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 간단하게 `query`로 테스트를 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688033329761&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async rewrites() {
    return [
      {
        source: '/about',
        has: [{ type: 'query', key: 'test', value: 'rewrite' }],
        destination: '/',
      },
    ]
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 작성했습니다. `/about`이라는 url로 접근하면, `query`를 확인합니다. key는 `test`이고 value는 `rewrite`인지를 확인합니다. 만약 일치하다면 `/`로 rewrites하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js/redirects&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Redirect&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rewrites를 살펴볼 때 잠깐 설명했는데, 요청 경로를 다른 대상 경로로 화면은 마찬가지로 url로 이동시킵니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;source : 들어오는 요청 경로&lt;/li&gt;
&lt;li&gt;destination : 라우팅하려는 경로&lt;/li&gt;
&lt;li&gt;permanent : 유저나 검색 엔진에서 해당 리다이렉트 값을 영구적으로 저장할 것인지에 대한 여부. 만약 이벤트 페이지이거나 임시 페이지인 경우는 `false`로 지정해주면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688034136604&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redirect에서도 Rewrite와 비슷하게 헤더, 쿠키, 쿼리로 매칭하여 redirect할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js/runtime-configuration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Runtime Configuration&lt;/a&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js가 실행하는 동안 동작 및 설정을 조정할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;serverRuntimeConfig : server측에서 접근 가능한 런타임 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;publicRuntimeConfig : client측과 server측 양쪽에서 접근 가능한 공개 설정&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: left;&quot;&gt;  next.config.js&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688044268558&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;serverRuntimeConfig: {
    // Will only be available on the server side
    mySecret: 'secret',
  },
  publicRuntimeConfig: {
    // Will be available on both server and client
    staticFolder: '/static',
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 작성하고 특정 파일에 아래 내용을 작성해봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1688044357753&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import getConfig from 'next/config'

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
console.log(serverRuntimeConfig.mySecret)
console.log(publicRuntimeConfig.staticFolder)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;107&quot; data-origin-height=&quot;47&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ8enz/btslQnA1KbS/UnhFnIE6r31cytkKQZVPkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ8enz/btslQnA1KbS/UnhFnIE6r31cytkKQZVPkK/img.png&quot; data-alt=&quot;client&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ8enz/btslQnA1KbS/UnhFnIE6r31cytkKQZVPkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ8enz%2FbtslQnA1KbS%2FUnhFnIE6r31cytkKQZVPkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;121&quot; height=&quot;53&quot; data-origin-width=&quot;107&quot; data-origin-height=&quot;47&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;client&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;112&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IXgjG/btslRJju03Y/9As8ax4czIKjhV6rAzoc0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IXgjG/btslRJju03Y/9As8ax4czIKjhV6rAzoc0k/img.png&quot; data-alt=&quot;server&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IXgjG/btslRJju03Y/9As8ax4czIKjhV6rAzoc0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIXgjG%2FbtslRJju03Y%2F9As8ax4czIKjhV6rAzoc0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;120&quot; height=&quot;57&quot; data-origin-width=&quot;112&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;server&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;`serverRuntimeConfig`는 client 콘솔에는 `undefined`로 커버가 된 것을 확인할 수 있었고, server 콘솔에서는 모두 로그가 찍힌 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. &lt;a href=&quot;https://nextjs.org/docs/pages/api-reference/next-config-js/distDir&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;distDir&lt;/a&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 시 생성되는 디렉토리 이름을 변경해줄 수 있습니다. 원래는 `.next`였죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688044880525&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  distDir: 'build',
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 설정해주고 `yarn build`를 해보면 `build`라는 폴더가 생기면 빌드된 파일들이 포함되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 위와 같이 설정하고 `yarn build`를 해주면 마지막에 에러가 뜹니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJv8IN/btslVmtECdT/K1n0zgTijqvcPY9LF22Ak1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJv8IN/btslVmtECdT/K1n0zgTijqvcPY9LF22Ak1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJv8IN/btslVmtECdT/K1n0zgTijqvcPY9LF22Ak1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJv8IN%2FbtslVmtECdT%2FK1n0zgTijqvcPY9LF22Ak1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;116&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;export-marker.json은 지금 `build`파일에 존재하는데 못찾겠다면서요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 next-sitemap.config.js 파일로 가서 추가 설정이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  next-sitemap.config.js&lt;/p&gt;
&lt;pre id=&quot;code_1688045189092&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: '배포주소',
  generateRobotsTxt: true, // (optional)
  // ...other options
  sourceDir: 'build'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 `sourceDir`을 알려줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 next.config.js에서 커스텀할 수 있는 내용들에 대해 알아보았습니다. 모든 내용을 다룬 것은 아니니 공식 문서를 참고하시면 더욱 좋을 것 같습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 필요한 것만&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 설정이 가능, 찾아서 쓸 수 있으면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 환경변수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;process.env.*&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. rewrite / redirect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;url 유지 / url 자체 redirect&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 기타&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack부터 기타 세밀한 설정까지&lt;/p&gt;</description>
      <category>프론트엔드/Next.js</category>
      <category>frontend</category>
      <category>next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/280</guid>
      <comments>https://doeunn.tistory.com/280#entry280comment</comments>
      <pubDate>Thu, 29 Jun 2023 22:31:25 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Next.js에서 Error Handling을 해서 원하는 에러 문구를 보여주자</title>
      <link>https://doeunn.tistory.com/279</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0jKFc/btslDYmXAdx/OptzHLvoV6h0cIoIdOt7pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0jKFc/btslDYmXAdx/OptzHLvoV6h0cIoIdOt7pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0jKFc/btslDYmXAdx/OptzHLvoV6h0cIoIdOt7pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0jKFc%2FbtslDYmXAdx%2FOptzHLvoV6h0cIoIdOt7pk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Error Handling&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/pages/building-your-application/configuring/error-handling&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 문서&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: start;&quot;&gt;공식문서에서 개발, 서버 측 및 클라이언트 측 오류를 처리하는 방법을 설명하고 있습니다 :) 해당 내용에 대해 살펴보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: start;&quot;&gt;1. 개발 중 오류 처리&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #171717; text-align: start;&quot;&gt;Next.js 개발 단계에서 런타임 오류가 발생하면 오버레이가 발생합니다&lt;span&gt;&amp;nbsp;&lt;/span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;웹 페이지를 덮는 모달입니다.&lt;span&gt; devlopment 모드로 &lt;/span&gt;실행될&lt;span&gt;&amp;nbsp;&lt;/span&gt;때만&lt;span&gt;&amp;nbsp;&lt;/span&gt;표시 되며 빌드 환경에서는 표시되지 않습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;오류를 수정하면 오버레이가 자동으로 해제됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wQSU7/btslLE9vzQS/ON9RwERy0whCcgfGkfCBok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wQSU7/btslLE9vzQS/ON9RwERy0whCcgfGkfCBok/img.png&quot; data-alt=&quot;이런 거 많이 볼 수 있죠?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wQSU7/btslLE9vzQS/ON9RwERy0whCcgfGkfCBok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwQSU7%2FbtslLE9vzQS%2FON9RwERy0whCcgfGkfCBok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;689&quot; height=&quot;315&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이런 거 많이 볼 수 있죠?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 서버 오류 처리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 측 오류를 처리하기 위해 기본적으로 정적인 500 페이지를 제공합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz8OXp/btslMVbXjWK/m3uAxIaXgRjxKwM117bKHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz8OXp/btslMVbXjWK/m3uAxIaXgRjxKwM117bKHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz8OXp/btslMVbXjWK/m3uAxIaXgRjxKwM117bKHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz8OXp%2FbtslMVbXjWK%2Fm3uAxIaXgRjxKwM117bKHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;262&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`500.js`라는 파일을 만들어 커스텀해서 에러 페이지를 보여줄 수도 있습니다. 마찬가지로 404, 401과 같이 에러 status code 이름으로 파일을 만들어 컴포넌트를 추가하면 해당 에러에 대해 만들어둔 Custom 에러 컴포넌트를 사용자에게 보여줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  pages/404.js&lt;/p&gt;
&lt;pre id=&quot;code_1687955910294&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function Custom404() {
  return &amp;lt;h1&amp;gt;404 - Page Not Found&amp;lt;/h1&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 오류 페이지 Customizing&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 status code에 대해 한번에 처리하고 싶다면 다음과 같이 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  pages/_error.js&lt;/p&gt;
&lt;pre id=&quot;code_1687956107895&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import ErrorNext from 'next/error'

function Error({ statusCode }) {
  if (statusCode === 404) {
    return &amp;lt;p&amp;gt;404에러에요!&amp;lt;/p&amp;gt;
  }
  return &amp;lt;ErrorNext statusCode={statusCode} /&amp;gt;
}

Error.getInitialProps = ({ res, err }) =&amp;gt; {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404
  return { statusCode }
}

export default Error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`next/error`의 컴포넌트는 위에서 기본적으로 보여주었던 next에서 제공하고 있는 에러 컴포넌트입니다. 저는 위와 같이 내가 따로 처리하고 싶은 statusCode에 대해서는 특별하게 return 하고 있고 나머지에 대해서는 기본 컴포넌트를 사용하여 처리되도록 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할 점은 예를 들어 이미 `404.js`파일이 존재한다면 404.js 파일을 먼저 인식하여 _error.js 파일로 인식이 되지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서는 제가 간단하게 작성했지만, 특정 statusCode에 대해 분기처리 하고 싶다고 하면&lt;/p&gt;
&lt;pre id=&quot;code_1687956438864&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const getErrorMessage = status =&amp;gt; {
	switch (status) {
		case 403:
			return {
				title: '세션이 만료되었습니다.',
				content: '로그인을 해주세요',
			}
		// case 409:
		case 500:
			return {
				title: '서버에서 오류가 발생하였습니다.',
				content:
					'잠시 후 다시 시도해주세요. 문제가 지속될 경우 고객 센터에 문의해 주세요.',
			}
		case 502:
			return {
				title: '연결 과정에서 문제가 발생하였습니다.',
				content: '잠시 후 다시 시도해주세요.',
			}
		case 503:
			return {
				title: '서비스를 일시적으로 이용할 수 없습니다.',
				content: '나중에 다시 시도해주세요.',
			}
		default:
			return {
				title: '서비스에 접속할 수 없습니다.',
				content: '새로고침을 하거나 잠시 후 다시 접속해 주시기 바랍니다.',
			}
	}
}
export default getErrorMessage&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 처럼 따로 정의해두고 에러 컴포넌트에서 statusCode에 따라 처리하는 것도 좋은 방법일 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 클라이언트 오류 처리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React의 ErrorBoundary에 대한 사용방법을 설명하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js에서 ErrorBoundary를 사용하려면 클래스 구성 요소를 생성하고 pages/_app.js를 래핑해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 ErrorBoundary 컴포넌트를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  components/ErrorBoundary.js&lt;/p&gt;
&lt;pre id=&quot;code_1687956676674&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react'

/**
 * Error 관련되어서는 hook에서 life cycle method가 존재하지 않아서
 * class형 컴포넌트 사용이 불가피
 */
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)

    // 초기 상태를 setup
    this.state = { hasError: false, error: null, errorInfo: null }
  }

  static getDerivedStateFromError(error) {
    console.log(`getDerivedStateFromError: ${error}`)

    return { hasError: true }
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ error, errorInfo })
    console.log(`componentDidCatch: ${(error, errorInfo)}`)
  }

  render() {
    if (this.state.hasError) {
      if (this.props.fallbackComponent) {
        // props로 받은 fallbackComponent가 있다면
        return this.props.fallbackComponent
      }

      return (
        &amp;lt;div&amp;gt;
          &amp;lt;h2&amp;gt;Error occurred&amp;lt;/h2&amp;gt;
          &amp;lt;details style={{ whiteSpace: 'pre-wrap' }}&amp;gt;
            {this.state.error &amp;amp;&amp;amp; this.state.error.toString()}
          &amp;lt;/details&amp;gt;
        &amp;lt;/div&amp;gt;
      )
    }
    return this.props.children
  }
}

export default ErrorBoundary&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 만들어준 ErrorBoundary 컴포넌트를 _app.js에서 래핑해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  _app.js&lt;/p&gt;
&lt;pre id=&quot;code_1687957382439&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Layout from '@/components/Layout'
import '@/styles/globals.css'
import ErrorBoundary from '@/components/ErrorBoundary'

export default function App({ Component, pageProps }) {

  return (
    &amp;lt;Layout&amp;gt;
      &amp;lt;ErrorBoundary&amp;gt;
        &amp;lt;Component {...pageProps} pathname={router.pathname} /&amp;gt;
      &amp;lt;/ErrorBoundary&amp;gt;
    &amp;lt;/Layout&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;next_17.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYKXpg/btslKeDJEsW/xOySWycmvzH2OQE3l2ou10/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYKXpg/btslKeDJEsW/xOySWycmvzH2OQE3l2ou10/img.gif&quot; data-alt=&quot;실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYKXpg/btslKeDJEsW/xOySWycmvzH2OQE3l2ou10/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bYKXpg/btslKeDJEsW/xOySWycmvzH2OQE3l2ou10/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;279&quot; data-filename=&quot;next_17.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의도적으로 에러를 throw하여 테스트 해보았을 때 미리 Custom 해두었던 에러 메세지가 화면에 렌더링된 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 fallbackComponent를 추가해봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1687957680915&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;ErrorBoundary fallbackComponent={&amp;lt;div&amp;gt;에러 발생!  &amp;lt;/div&amp;gt;}&amp;gt;
	&amp;lt;Component {...pageProps} pathname={router.pathname} /&amp;gt;
&amp;lt;/ErrorBoundary&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;next_18.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv6Z9Q/btslIlw0Wz2/wNiu3HbvrZOVykDpw4okh1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv6Z9Q/btslIlw0Wz2/wNiu3HbvrZOVykDpw4okh1/img.gif&quot; data-alt=&quot;실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv6Z9Q/btslIlw0Wz2/wNiu3HbvrZOVykDpw4okh1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bv6Z9Q/btslIlw0Wz2/wNiu3HbvrZOVykDpw4okh1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;287&quot; data-filename=&quot;next_18.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 fallbackComponent로 특별히 화면에 렌더하고 싶은 컴포넌트를 넘겨주었더니 해당 컴포넌트로 화면에 렌더링된 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 에러가 런타임 에러 모달로 뜬다면 development 모드에서가 아닌 build 환경에서 확인해보시면 되겠습니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 Custom Error 컴포넌트를 통해 Error Handling에 대해 알아보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Error&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;handled vs unhandled&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Error Handling&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Development / Server / Client&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Error Page Custom&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;404.js / _error.js / next/error&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Client&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error Boundary&lt;/p&gt;</description>
      <category>프론트엔드/Next.js</category>
      <category>frontend</category>
      <category>next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/279</guid>
      <comments>https://doeunn.tistory.com/279#entry279comment</comments>
      <pubDate>Wed, 28 Jun 2023 22:16:12 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Web vitals와 성능 측정 도구에 대해 알아보자</title>
      <link>https://doeunn.tistory.com/278</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VVmkB/btslCjSFAsR/L5qwYYrgibbTcfFt63uGQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VVmkB/btslCjSFAsR/L5qwYYrgibbTcfFt63uGQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VVmkB/btslCjSFAsR/L5qwYYrgibbTcfFt63uGQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVVmkB%2FbtslCjSFAsR%2FL5qwYYrgibbTcfFt63uGQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://web.dev/vitals/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;Web Vitals&lt;/b&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글은 어떻게 페이지의 품질을 평가할까요? SEO 전략을 세우는 데 중요한 구글의 품질 평가 요소 중 한 축을 담당하는 코어 웹 바이탈에 대해 알아보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Core Web Vitals&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코어 웹 바이탈(Core Web Vitals)은 웹 페이지 로딩 속도, 모바일 친화성, 세이프 브라우징, 암호화(HTTPS 적용 여부), 방해요소 여부 등과 같은 웹 콘텐츠 이용자의 사용 경험에 영향을 미치는 다양한 측정 가능한 값들 중에서 구글이 중요하다 강조하는 아래의 3가지 매트릭스는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw0Vl9/btslImtOcRV/aHGAWjbh4rdSrZ8Hdta500/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw0Vl9/btslImtOcRV/aHGAWjbh4rdSrZ8Hdta500/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw0Vl9/btslImtOcRV/aHGAWjbh4rdSrZ8Hdta500/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw0Vl9%2FbtslImtOcRV%2FaHGAWjbh4rdSrZ8Hdta500%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;705&quot; height=&quot;197&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;웹 바이탈의 3가지 핵심 매트릭스&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. LCP(Largest Contentful Paint, 최대 콘텐츠풀 페인트)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 화면에 렌더링된 콘텐츠를 보는데 걸리는 시간&lt;/li&gt;
&lt;li&gt;LCP는 웹 페이지의 로딩 속도에 대한 지표&lt;/li&gt;
&lt;li&gt;웹사이트가 사용자에게 화면에서 완전하고 상호작용할 준비가 된 가장 큰 콘텐츠를 표시하는 데 걸리는 시간을 측정&lt;/li&gt;
&lt;li&gt;다음과 같이 사용자 경험과 관련된 로드 시간만 계산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미지&lt;/li&gt;
&lt;li&gt;비디오 썸네일&lt;/li&gt;
&lt;li&gt;CSS를 사용한 배경 이미지&lt;/li&gt;
&lt;li&gt;단락, 제목 및 목록과 같은 텍스트 요소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;좋은 LCP 점수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우수한 사용자 경험을 제공하려면 &lt;b&gt;2.5초 이하로 권장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCP에 &lt;span style=&quot;color: #ee2323;&quot;&gt;악영향&lt;/span&gt;을 미치는 원인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;느린 서버 응답 시간&lt;/b&gt;&lt;br /&gt;브라우저가 서버에서 콘텐츠를 받는 데 걸리는 시간이 올래 걸릴수록 화면에 렌더링하는 데 시간이 더 오래 걸린다. 서버가 콘텐츠를 처리하는 방법과 위치를 개선해야 한다. &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;자원을 캐시하거나, HTML 페이지를 우선 캐시되도록 하는 등을 방법&lt;/span&gt;&lt;/b&gt;으로 서버 응답 시간을 단축할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자바스크립트와 CSS의 렌더 블로킹&lt;/b&gt;&lt;br /&gt;브라우저가 콘텐츠를 렌더링하려면, HTML 마크업을 파싱해서 DOM 트리로 만들어야 한다. HTML 파서는 외부 스타일시트(&amp;lt;link rel=&quot;stylesheet&quot;&amp;gt;)나 동기적인 자바스크립트(&amp;lt;script src=&quot;main.js&quot;&amp;gt;)를 만나면 중단될 것이다.&lt;br /&gt;스크립트와 스타일시트는 모두 LCP를 지연시키는 렌더 블로킹 리소스이다. 웹 페이지의 주요 컨텐츠를 빠르게 로딩하기 위해서 &lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;중요하지 않는 자바스크립트와 CSS는 지연&lt;/span&gt;&lt;/b&gt;시켜야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;느린 리소스 로딩 시간&lt;/b&gt;&lt;br /&gt;LCP에 영향을 주는 엘리먼트의 타입들은 &amp;lt;img&amp;gt;, &amp;lt;svg&amp;gt; 엘리먼트 내부의 &amp;lt;image&amp;gt;, &amp;lt;video&amp;gt;, CSS 그라데이션과 다르게 url() 함수를 통해 로드된 배경 이미지들이다.&lt;br /&gt;상단부가 렌더링된 경우 이런 엘리먼트를 로드하는 데 걸리는 시간은 LCP에 직접적인 영향을 미친다. 이런 파일이 가능한 빠르게 로드될 수 있도록 하는 방법에는 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;이미지 최적화 및 압축, 중요한 리소스를 미리 로드, 텍스트 파일 압축 등&lt;/b&gt;&lt;/span&gt;이 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Client-side 렌더링&lt;/b&gt;&lt;br /&gt;클라이언트에서 주로 렌더링되는 사이트를 만들고 있다면, 용량이 큰 자바스크립트 번들의 사용이 LCP에 미칠 수 있는 영향을 조심해야 한다.&lt;br /&gt;클라이언트 측에서 렌더링되는 사이트를 만들 때 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;핵심 자바스크립트를 최소화, 서버 측 렌더링을 사용, 사전 렌더링한다 등과 같은 최적화 방법&lt;/b&gt;&lt;/span&gt;을 고려해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. FID(First Input Delay, 최소 입력 지연)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저가 첫 번째 클라이언트 요청에 응답하는 데 걸리는 시간을 계산&lt;/li&gt;
&lt;li&gt;콘텐츠가 그려진 시점과 사이트가 이벤트 핸들러를 실행하고 처리할 준비가 된 시점 사이의 시간&lt;/li&gt;
&lt;li&gt;이 지연은 JS를 다운로드하고 실행해야 하는 양, 이미지 크기, 사용자 정의 글꼴 등에 따라 사이트마다 다를 수 있다.&lt;/li&gt;
&lt;li&gt;FID가 높을수록 사용자에게 더 답답&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;좋은 FID 점수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우수한 사용자 경험을 제공하려면 &lt;b&gt;100ms 이하&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FID에 &lt;span style=&quot;color: #ee2323;&quot;&gt;악영향&lt;/span&gt;을 미치는 원인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JavaScript 실행&lt;br /&gt;브라우저가 다음 단계를 결정하기 위해 기다리는 동안 웹 사이트가 응답하지 않은 것처럼 느끼게 하여 입력 지연 시간이 길어질 수 있다. &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;비동기 작업을 작은 단위로 나누어 처리하거나 서버 측에서 콘텐츠를 생성하여 클라이언트 측에서 후처리해야 하는 양을 최소화하거나, 사용하지 않는 JS를 delay하거나 해서 최적화 방법&lt;/b&gt;&lt;/span&gt;을 고려할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. CLS(Cumulative Layout Shife, 누적 레이아웃 시프트)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방문자에게 콘텐츠가 얼마나 불안정한 지 측정하는 사용자 경험 측정 항목&lt;/li&gt;
&lt;li&gt;뉴스 기사를 보려고 들어간 웹 사이트에서 기사 링크를 클릭한 순간 레이아웃이 이동해서 광고가 나타나 기사가 아닌 광고를 클릭한 경험이 있을텐데...&amp;nbsp;&lt;/li&gt;
&lt;li&gt;이렇게 페이지에 들어갔을 때 갑작스럽게 발생하는 레이아웃 이동의 정도를 합산한 이동 거리 개념을 도입&lt;/li&gt;
&lt;li&gt;안정적인 레이아웃이냐를 따진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;좋은 CLS 점수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우수한 사용자 경험을 제공하려면 &lt;b&gt;0.1 이하&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CLS에 &lt;span style=&quot;color: #ee2323;&quot;&gt;악영향&lt;/span&gt;을 미치는 원인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;치수가 없는 이미지&lt;/b&gt;&lt;br /&gt;이미지 및 비디오 요소에 `width`와 `height` 속성을 항상 포함하거나 또는 CSS를 사용하여 필요한 공간을 잡는다. 이 방법을 사용하면 이미지가 로드되는 동안 브라우저가 문서의 공간을 올바르게 할당할 수 있다. 영역을 미리 확보게 두는 것이 중요한데, 이럴 때 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;`aspect-ratio` 속성을 사용하거나 반응형 이미지를 처리하거나 하는 방법&lt;/b&gt;&lt;/span&gt;으로 최적화를 할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;크기가 없는 광고, 삽입 및 iframe&lt;/b&gt;&lt;br /&gt;광고는 웹에서 레이아웃 이동에 가장 큰 영향을 주는 요소 중 하나이다. 동적인 광고 크기는 형재 보고 있는 콘텐츠를 페이지 아래로 밀어버릴 수 있어 사용자 환경에 최적화되지 않을 수 있다. &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;광고 슬롯을 위한 정적 공간을 확보하거나, 뷰포트 상단 근처에 광고 배치하지 않는 방법&lt;/b&gt;&lt;/span&gt; 등으로 개선할 수 있겠다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동적으로 삽입된 콘텐츠&lt;/b&gt;&lt;br /&gt;사용자 상호 작용에 대한 응답이 없는 경우 기존 콘텐츠 위에 새 콘텐츠를 삽입하지 않도록 한다. 사이트를 로드하려고 할 때 뷰포트의 맨 위/아래에 나타나는 ,UI로 인해 레이아웃 이동을 경험했을텐데, 이는 광고와 마찬가지로 페이지의 나머지 콘텐츠를 이동시키는 배너 및 폼에서 종종 발생한다.&lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;미리 뷰포트에 충분한 공간을 확보하여(placeholder 또는 Skeleton UI 사용) 로드할 때 페이지의 콘텐츠가 이동하지 않도록&lt;/b&gt; &lt;/span&gt;해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;FOIT/FOUT을 유발하는 웹 글꼴&lt;/b&gt;&lt;br /&gt;FOIT : 웹 폰트가 적용되지 않은 텍스트가 보이지 않는 상태. 폰트가 바뀌면서 텐스트 번쩍임이 일어난다.&lt;br /&gt;FOUT: : 웹 폰트가 적용되지 않는 Fallback 폰트 상태(unstyled)에서 폰트가 바뀌면서 텍스트 번쩍임이 일어난다&lt;br /&gt;이럴 때는 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;`font-display`를 사용하여 사용자 정의 폰트의 렌더링 동작을 수정&lt;/b&gt;&lt;/span&gt;할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Google을 활용한 성능 측정&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/speed?hl=ko&quot;&gt;https://developers.google.com/speed?hl=ko&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;https://pagespeed.web.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크를 통해 성능을 측정할 수도 있고, 상세하게 여러 요인들을 알려주기도 합니다. 해당 내용들을 참고해 웹 성능 최적화를 수행을 할 수 있습니다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Chrome을 활용한 성능 측정&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Lighthouse&lt;/li&gt;
&lt;li&gt;React debug tool profiler&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그래서 Next.js에서 Web vitals를 어떻게 추적?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 방법으로 측정하는 것은 어떤 기능이 어떤 속도로 동작했는지는 볼 수 있지만, 사용자의 상황에서는 어떤 경험을 하고 있는지는 알 수 없었습니다. 그 부분들은 사용자에게 제공된 우리 웹에서 이 vital들을 tracking할 수 있는 로그들을 심어서 볼 수가 있습니다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://nextjs.org/docs/pages/building-your-application/optimizing/analytics&quot;&gt;공식문서&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`_app.js`파일에 아래 내용을 추가해주면 쉽게 report를 얻을 수 있다고 하고 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687922149451&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export function reportWebVitals(metric) {
  console.log(metric)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;306&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddsoVL/btslCyI2Lhj/S4zJSJDYbbWcVGwrIItjgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddsoVL/btslCyI2Lhj/S4zJSJDYbbWcVGwrIItjgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddsoVL/btslCyI2Lhj/S4zJSJDYbbWcVGwrIItjgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddsoVL%2FbtslCyI2Lhj%2FS4zJSJDYbbWcVGwrIItjgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;390&quot; height=&quot;241&quot; data-origin-width=&quot;306&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보면 CLS, LCP, FCP 등이 남았습니다. 해당하는 값은 `value`를 보면 됩니다. 해당 내용을 fetch로 서버에 올린다면 그 값이 우리에게 축적이 되면서 우리의 서비스를 접근하는 사용자가 어떠한 환경에서 어느정도의 퍼포먼스를 경험하고 있는지를 분석할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 Web vitals와 성능 측정 방식에 대해서도 간단히 알아보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. web.dev&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LCP(2.5s) / FID(100ms) / CLS(0.1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Google&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;web url 입력시 점수 측정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Chrome&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Performance / Lighthouse&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. reportWebvitals&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹서비스에 접근한 사용자의 로그 수집&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고 문서&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/vitals/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Google Devloper - Web vitals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ascentkorea.com/core-web-vitals/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;코어 웹 바이탈(Core web Vitals)이란 무엇인가?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ui.toast.com/posts/ko_202012101720&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LCP(Largest Contentful Paint) 최적화하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rockcontent.com/blog/largest-contentful-paint/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;What is Largest Contentful Paint?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.onely.com/blog/what-is-first-input-delay/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;First Input Delay: A Complete Guide to Optimizing FID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wit.nts-corp.com/2020/12/28/6240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;새로운 웹페이지 성능 측정 지표 CLS(Cumulative Layout Shift)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프론트엔드/Next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/278</guid>
      <comments>https://doeunn.tistory.com/278#entry278comment</comments>
      <pubDate>Wed, 28 Jun 2023 12:21:34 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Custom App - 생산성을 높이는 _app.js에서 할 수 있는 일들</title>
      <link>https://doeunn.tistory.com/277</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lx6H7/btsltVLxuK7/mdiNYHFj9AVtPu3pvcjBF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lx6H7/btsltVLxuK7/mdiNYHFj9AVtPu3pvcjBF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lx6H7/btsltVLxuK7/mdiNYHFj9AVtPu3pvcjBF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLx6H7%2FbtsltVLxuK7%2FmdiNYHFj9AVtPu3pvcjBF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/pages/building-your-application/routing/custom-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;Custom App&lt;/b&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js에서 `_app.js` 파일은 모든 구성요소를 Wrap하고 있는 요소라고도 할 수 있습니다. 따라서 `_app.js`에서 모든 컴포넌트에게 필요한 것들을 정의하고 초기화하여 조금이라도 반복되는 코드들을 줄일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서에서는 다음과 같은 내용들을 수행할 수 있다고 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페이지 변경 간에 레이아웃 유지&lt;/li&gt;
&lt;li&gt;페이지 탐색 시 고정적인 state를 유지&lt;/li&gt;
&lt;li&gt;페이지에 추가 데이터 주입&lt;/li&gt;
&lt;li&gt;글로벌 CSS 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나씩 예시 코드를 살펴보며 무엇을 이야기하는지를 알아봅시다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 페이지 변경 간에 레이아웃 유지&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 페이지에 걸쳐 동일한 레이아웃을 유지해야 한다면 매번 컴포넌트의 최상단에 Layout 컴포넌트를 Wrapper로 씌워줄 필요가 없습니다. 이럴 때 `_app.js` 파일에서 한번에 Wrap해주면 되는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  _app.js&lt;/p&gt;
&lt;pre id=&quot;code_1687855881526&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function App({ Component }) {
  const router = useRouter()

  return (
    // 아래와 같이 _app.js에서 Layout을 감싸주면
    // _app.js는 전체 컴포넌트의 Wrapper이기 때문에 전부 적용된다.
    &amp;lt;Layout home={router.pathname === '/'}&amp;gt;
      &amp;lt;Component {...pageProps} /&amp;gt;
    &amp;lt;/Layout&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에는 특정 페이지에서는 조금 다른 스타일이 필요한 경우를 위해 옵션도 prop으로 전달할 수 있도록 한 형태입니다. 위와 같이 작성해주면 다른 페이지 컴포넌트에서는 해당 컴포넌트의 View 로직만 집중해서 작성할 수 있겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 페이지 탐색 시 고정적인 state를 유지&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`_app.js`에서 어떤 state를 가지고 있고, 해당 state를 계속 유지하는 경우도 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 모든 페이지에 걸쳐 언제 방문했는지 년-월-일-시간을 표시해야 하는 경우를 예시로 들어보겠습니다. 그런데 방문 시간은 해당 사이트에 처음 방문한 시간을 표시하죠? 즉, navigate를 넘나들더라도 방문시간이 그때그때마다 변경되지 않아야 한다는 말과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  _app.js&lt;/p&gt;
&lt;pre id=&quot;code_1687856954184&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function App({ Component, pageProps }) {
  const router = useRouter()
  const [visitedTime] = useState(new Date())

  return (
    &amp;lt;Layout home={router.pathname === '/'}&amp;gt;
      &amp;lt;div&amp;gt;visited: {format(visitedTime, &quot;yyyy-MM-dd'T'HH:mm:ss.SSSxxx&quot;)}&amp;lt;/div&amp;gt;
      &amp;lt;Component {...pageProps} pathname={router.pathname} /&amp;gt;
    &amp;lt;/Layout&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;next_16.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rajc8/btslC48eYSY/s5KfskmcJkkTVIsNaW3Hhk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rajc8/btslC48eYSY/s5KfskmcJkkTVIsNaW3Hhk/img.gif&quot; data-alt=&quot;실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rajc8/btslC48eYSY/s5KfskmcJkkTVIsNaW3Hhk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/rajc8/btslC48eYSY/s5KfskmcJkkTVIsNaW3Hhk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;679&quot; height=&quot;339&quot; data-filename=&quot;next_16.gif&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 화면을 보게되면 `_app.js`에서 관리하는 state이므로 navigate를 하더라도 변하지 않고 유지되는 것을 확인할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 페이지에 추가 데이터 주입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 모든 페이지에 지금 페이지 pathname을 주입한다고 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  _app.js&lt;/p&gt;
&lt;pre id=&quot;code_1687856437380&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function App({ Component, pageProps }) {
  const router = useRouter()

  return (
    &amp;lt;Layout home={router.pathname === '/'}&amp;gt;
      &amp;lt;Component {...pageProps} pathname={router.pathname} /&amp;gt;
    &amp;lt;/Layout&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 작성해주면 모든 페이지들은 prop으로 pathname을 받아 사용할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  pages/posts/[id].js&lt;/p&gt;
&lt;pre id=&quot;code_1687856523562&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default Post({ postData, pathname }) {
  // ...
  
  return (
    &amp;lt;h2&amp;gt;pathname: {pathname}&amp;lt;/h2&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;219&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNiTsw/btslBPRu8Zc/seD6iySBDUbhHR99oV6hkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNiTsw/btslBPRu8Zc/seD6iySBDUbhHR99oV6hkk/img.png&quot; data-alt=&quot;실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNiTsw/btslBPRu8Zc/seD6iySBDUbhHR99oV6hkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNiTsw%2FbtslBPRu8Zc%2FseD6iySBDUbhHR99oV6hkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;219&quot; height=&quot;53&quot; data-origin-width=&quot;219&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 글로벌 CSS 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`_app.js`에서 css를 import해주면 전역에서 스타일이 적용되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  _app.js&lt;/p&gt;
&lt;pre id=&quot;code_1687857197231&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import '@/styles/globals.css'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프론트엔드/Next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/277</guid>
      <comments>https://doeunn.tistory.com/277#entry277comment</comments>
      <pubDate>Tue, 27 Jun 2023 18:15:58 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] ../ 때문에 길어지는 import문은 별칭 절대경로 @ 사용하기</title>
      <link>https://doeunn.tistory.com/276</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brlOHJ/btsls7yvT9p/I8o0rV7GPsrbnn04KfSd30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brlOHJ/btsls7yvT9p/I8o0rV7GPsrbnn04KfSd30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brlOHJ/btsls7yvT9p/I8o0rV7GPsrbnn04KfSd30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrlOHJ%2Fbtsls7yvT9p%2FI8o0rV7GPsrbnn04KfSd30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/pages/building-your-application/configuring/absolute-imports-and-module-aliases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;Absolute Imports and Module Path Aliases&lt;/b&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 하면 어떤 라이브러리 혹은 컴포넌트를 import하는 일이 많습니다. 일반적으로 `import Somthing from '../../components/Something'` 과 같은 형식으로 상대경로를 이용해서 불러옵니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 규모가 커질 수록, 생성되는 폴더 및 파일이 많아질수록 depth가 깊어져 아래와 같이 import문이 굉장히 길어질 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687837164955&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Something from '../../../../components/common/layout/Something/';
import SubThing from '../../../../components/common/base/SubThing/';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보기 불편할 뿐더러 지저분해 보이기까지도 한다. 따라서 이럴 때 경로를 `절대경로`와 `별칭`을 사용하여 간단하게 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;jsconfig.json / tsconfig.json 생성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에 맞게 config 파일을 생성해주고, 다음 내용을 추가해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  jsconfig.json&lt;/p&gt;
&lt;pre id=&quot;code_1687837325302&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;baseUrl&quot;: &quot;.&quot;,
    &quot;paths&quot;: {
      &quot;@/components/*&quot;: [&quot;components/*&quot;]
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`baseUrl`을 &quot;.&quot;으로 해서 root 디렉토리를 baseUrl이 되도록 설정합니다. 그리고 @/components는 components 폴더를 의미하는 별칭으로 설정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 설정해주면 다음과 같이 수정해줄 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687837575331&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt; before
import Layout from '../../components/Layout'

&amp;gt; after
import Layout from '@components/Layout'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;훨씬 간략하고 보기 편하다고 생각이 듭니다 :)&lt;/p&gt;</description>
      <category>프론트엔드/Next.js</category>
      <category>frontend</category>
      <category>next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/276</guid>
      <comments>https://doeunn.tistory.com/276#entry276comment</comments>
      <pubDate>Tue, 27 Jun 2023 12:51:18 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Dynamic Import(Lazy load) &amp;amp; Hydration &amp;amp; Static Export</title>
      <link>https://doeunn.tistory.com/275</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p08L2/btslugBgQgt/euUjUiLuYj6b5tREYCDzQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p08L2/btslugBgQgt/euUjUiLuYj6b5tREYCDzQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p08L2/btslugBgQgt/euUjUiLuYj6b5tREYCDzQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp08L2%2FbtslugBgQgt%2FeuUjUiLuYj6b5tREYCDzQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;567&quot; data-filename=&quot;nextjs.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Dynamic Import&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dynamic Import는 컴포넌트를 사용하는 시점에 로드하는 것인데요. Next.js에서는 이미지나 Link 컴포넌트 두 가지 모두 Viewport 안에 들어왔을 떄 로드하는 것들이 있었습니다. 그런 것들을 &lt;b&gt;Lazy Load&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트 마저도 상단에서 모두 한번에 import해서 사용하는 것이 아니라 &lt;b&gt;필요한 타이밍에 로드해서 사용할 수 있는 방법&lt;/b&gt;을 제공합니다. Next.js에서는 그것을 &lt;b&gt;Dynamic&lt;/b&gt;이라는 개념으로 사용됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dynamic Import를 사용하면 모듈을 빌드 타임이 아닌 런타임에 불러오도록 합니다. 이를 통해 번들 파일을 분리하고 초기 렌더링 시간 단축이란느 퍼포먼스 향상을 기대할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션에는 초기 로딩부터 사용하지 않는 부분이 존재할 수 있으며, 또 그 부분의 사이즈가 생각보다 클 수 있기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;next/dynamic을 이용해서&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`next/dynamic`을 사용하면 페이지의 초기 번들에 포함되지 않습니다. 페이지는 Suspense를 통해 fallback을 먼저 렌더링한 다음 로드가 되면 그때 구성 요소를 렌더링합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1687831185965&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import dynamic from 'next/dynamic'

const Button = dynamic(() =&amp;gt; import('../../components/Button'), {
  loading: () =&amp;gt; &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;,
})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dynamic Import를 사용하면 따로 빌드가 되게 됩니다. 반면 Dynamic Import를 사용하지 않으면 따로 쪼개지 않고 chunk에 같이 묶이게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Automatic Static Optimization&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js가 정적 페이지는 .html으로 요청에 맞춰 동작하는 페이지는 .js로 빌드하는 것을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js는 자동적으로 정적인 것은 최적화해서 정적인 파일로, 동적인 것은 동적인 파일로 만들어줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`getServerSideProps`또는 `getInitialProps`가 페이지에 있는 경우 Next.js는 요청에 따라 페이지를 렌더링하도록 전환합니다. 위 경우가 아니라면 페이지를 HTML로 미리 렌더링하여 자동으로 페이지를 정적으로 최적화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;router의 query&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dynamic하다 static하다라는 것을 보았을 때, router의 query의 경우 client-side의 경우 &lt;b&gt;hydration 이후 query 값을 읽어올 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Next.js의 hydrate&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Server Side 단에서 렌더링된 정적인 페이지와 번들링된 JS 파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 JS코드를 서로 매칭시키는 과정이다. React는 JS만을 사용해 화면을 painting한다. Next.js는 Server Side에서 미리 웹페이지를 Pre-rendering하여 generate된 HTML document를 클라이언트에게 전송한다.&lt;br /&gt;&lt;br /&gt;Next.js를 통해 클라이언트가 받은 정적 웹페이지는 JS가 없기 때문에 interactive하지 않다. 개발자 도구의 네트워크 탭을 보면, document Type의 파일을 다운로드 받은 뒤 JS파일들이 다운로드되는 것을 확인할 수 있다.&lt;br /&gt;&lt;br /&gt;그리고 이 JS코드들이 이전에 보내진 HTML DOM 요소 위에서 한번 더 렌더링을 하면서 각자 자기 자리를 찾아가며 매칭이 된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 확인해봅시다. 정적인 파일에서 Client Side 부분에 다음과 같은 코드를 추가해봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1687833896138&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const router = useRouter()

useEffect(() =&amp;gt; {
	console.log(router.query)
}, [router.query])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`build`하고 실행해서 살펴보면 새로고침 했을 때, 분명 query가 있음에도 처음에 빈 객체가 먼저 뜹니다. 이는 dydration 즉, 사용자와 interaction할 준비가 될 때까지는 query가 없다고 판단하여 빈 객체가 콘솔에 찍힌 것이고, 그 이후에 query가 보여진 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pOgZb/btsluguTr9r/C1ANU4qfPSTEhNphjUq6q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pOgZb/btsluguTr9r/C1ANU4qfPSTEhNphjUq6q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pOgZb/btsluguTr9r/C1ANU4qfPSTEhNphjUq6q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpOgZb%2FbtsluguTr9r%2FC1ANU4qfPSTEhNphjUq6q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;396&quot; height=&quot;170&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;client side에서 코드를 작성하고 있다면 query의 존재가 이후에 주입될 수 있다는 점을 염두하고 있는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Next.js이 Hydration함으로써 얻게되는 이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React와 다르게 Pre-rendering된 Document는 자바스크립트 요소가 빠진 가벼운 상태이기 때문에 클라이언트 측에서 빠르게 로딩이 가능한 장점이 있습니다. 또한, 이후에 Chunk 단위로 다운로드된 자바스크립트 요소들이 렌더링될 때는 먼저 받아진 document의 DOM 요소에 자바스크립트 속성이 매칭되는 것이기 때문에 웹 페이지를 다시 그리는 과정이 일어나지 않게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀더 쉽게 이해해보자면, React는 CSR(Client-side Rendering)로, 처음에 브라우저에 빈 HTML을 파일을 받아 아무것도 보여주지 않다가, 사용자 기기에서 렌더링이 진행되어 한 번에 화면을 보여줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lsutO/btslpZtUus2/Wcs9lOHmHkYVEqrwwpJHo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lsutO/btslpZtUus2/Wcs9lOHmHkYVEqrwwpJHo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lsutO/btslpZtUus2/Wcs9lOHmHkYVEqrwwpJHo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlsutO%2FbtslpZtUus2%2FWcs9lOHmHkYVEqrwwpJHo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;380&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, Next.js는 모든 페이지를 미리 렌더링(pre-render)합니다. 이는 Next.js가 모든 일을 클라이언트 측에서 모든 작업을 수행하는 것이 아니라, 각 페이지의 HTML을 미리 생성하는 것입니다. 생성된 HTML은 해당 페이지에 필요한 최소한의 JS코드와 연결됩니다. 그 후 브라우저에 의해 페이지가 로드되면, JS코드가 실행되어 페이지와 유저가 상호작용(interaction)할 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 이러한 과정을 hydration이라 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY6ThT/btslwqDD2RE/FThCdcaxAESfbCm6uZO3nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY6ThT/btslwqDD2RE/FThCdcaxAESfbCm6uZO3nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY6ThT/btslwqDD2RE/FThCdcaxAESfbCm6uZO3nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY6ThT%2FbtslwqDD2RE%2FFThCdcaxAESfbCm6uZO3nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;365&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Static Export&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js 프로젝트를 정적인 파일들만으로 build하는 것을 말합니다. CDN 등에 정적인 파일들만을 올려서 서비스를 제공하는 것도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Node.js 서버가 있어야만 동작하는 기능들을 포기해야 한다는 말과 같습니다. &lt;a href=&quot;https://nextjs.org/docs/pages/building-your-application/deploying/static-exports&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 문서&lt;/a&gt;에서는 다음과 같이 Static Export를 사용했을 때 지원받지 못하는 것들을 나열하고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcTqNo/btsls7kUQGw/sM34WmsykQKBhePaMDybTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcTqNo/btsls7kUQGw/sM34WmsykQKBhePaMDybTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcTqNo/btsls7kUQGw/sM34WmsykQKBhePaMDybTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcTqNo%2Fbtsls7kUQGw%2FsM34WmsykQKBhePaMDybTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;468&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서에 사용하는 방법도 자세히 설명되어 있으니 같이 참고하면 좋을 것 같습니다 bb&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행해보면, 위에 지원하지 않는 기능이 포함된 경우 export할 떄 에러가 발생합니다. 그래서 적절히 변경해주고 다시 export를 해보면 .next에 `out`이라는 폴더가 생기는데, 그 안에는 &lt;b&gt;모두 html로 이루어진 파일들이 존재&lt;/b&gt;하며, next의 기본 동작을 위한 파일들만 js로 구성되어 있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 Dynamic Import와 Hydration 그리고 Static Export에 대해 알아보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Dynamic Import&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lazy load로 초기 청크 사이즈 줄이기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Suspense&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Promise resolved 되어야 렌더&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Automatic Static Optimize&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알아서 정적 파일과 동적 파일 구분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Static HTML Export&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의도적으로 정적 파일로 export 가능&lt;/p&gt;</description>
      <category>프론트엔드/Next.js</category>
      <category>frontend</category>
      <category>next.js</category>
      <author>doeunnkimm</author>
      <guid isPermaLink="true">https://doeunn.tistory.com/275</guid>
      <comments>https://doeunn.tistory.com/275#entry275comment</comments>
      <pubDate>Tue, 27 Jun 2023 12:29:19 +0900</pubDate>
    </item>
  </channel>
</rss>