<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Dahee's Solution Hub</title>
    <link>https://coding-dahee.tistory.com/</link>
    <description>배운건 공유해야 진짜 내것이 된다!</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 00:21:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>안다희</managingEditor>
    <image>
      <title>Dahee's Solution Hub</title>
      <url>https://tistory1.daumcdn.net/tistory/3017483/attach/edc24a28928341ca88ed00470fb0da2b</url>
      <link>https://coding-dahee.tistory.com</link>
    </image>
    <item>
      <title>Windows에서 SAP NetWeaver Developer Edition 설치 가이드</title>
      <link>https://coding-dahee.tistory.com/311</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;포스팅 목적&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음 SAP를 설치하는 사용자를 위한 Windows 기준 설치 가이드 작성&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;설치 환경&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;32GB RAM / 1TB SSD / Windows 11&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안내사항&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;※ 본 가이드는 &lt;b&gt;SAP NetWeaver 7.x Developer Edition (NPL)&lt;/b&gt; 기준으로 작성됨&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;전체 설치 순서&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;style&gt;
#toc-list{
  background:#fafafa;
  border:1px solid #f0f0f0;   /* ← 더 연한 회색 */
  border-radius:14px;
  padding:20px 24px;
  box-shadow:0 6px 20px rgba(0,0,0,0.04);  /* ← 그림자 아주 연하게 */
  line-height:1.8;
  font-size:15px;
}

#toc-list a{
  color:#333;
  transition:all 0.2s;
}

#toc-list a:hover{
  color:#ff5c5c;
  transform:translateX(3px);
}
&lt;/style&gt;
&lt;/div&gt;
&lt;div id=&quot;toc-list&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;script&gt;
window.addEventListener(&quot;DOMContentLoaded&quot;, function() {
  const headings = document.querySelectorAll(&quot;#toc-content b&quot;);
  const tocList = document.getElementById(&quot;toc-list&quot;);

  headings.forEach((heading, i) =&gt; {
    const id = &quot;toc-&quot; + i;
    heading.id = id;

    const a = document.createElement(&quot;a&quot;);

    a.textContent = heading.textContent;
    a.href = &quot;#&quot; + id;
    a.style.textDecoration = &quot;none&quot;;
    a.style.display = &quot;block&quot;;
    a.style.marginBottom = &quot;6px&quot;;

    tocList.appendChild(a);
  });
});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;설치 상세&lt;/b&gt;&lt;/h4&gt;
&lt;div id=&quot;toc-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  1. openSUSE 설치 파일 다운로드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP를 설치할 리눅스 운영체제 준비&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;gt;&amp;nbsp;&lt;a href=&quot;https://download.opensuse.org/distribution/leap/15.3/iso/&quot;&gt;https://download.opensuse.org/distribution/leap/15.3/iso/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 링크에서 3개 파일 다운로드&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1883&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBsL0K/dJMb99L5Zpb/bedFpxOLPavGd7LndTstIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBsL0K/dJMb99L5Zpb/bedFpxOLPavGd7LndTstIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBsL0K/dJMb99L5Zpb/bedFpxOLPavGd7LndTstIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBsL0K%2FdJMb99L5Zpb%2FbedFpxOLPavGd7LndTstIk%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;1883&quot; height=&quot;117&quot; data-origin-width=&quot;1883&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HMFq8/dJMcagqV1g6/WVktSoKhtDz7OlHz1eaCD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HMFq8/dJMcagqV1g6/WVktSoKhtDz7OlHz1eaCD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HMFq8/dJMcagqV1g6/WVktSoKhtDz7OlHz1eaCD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHMFq8%2FdJMcagqV1g6%2FWVktSoKhtDz7OlHz1eaCD0%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;1914&quot; height=&quot;144&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&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;br /&gt;&lt;b&gt; &lt;span&gt; &lt;/span&gt;2. SAP 설치 파일 다운로드 및 압축해제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 설치 파일 준비&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmkTu3/dJMcab4d57k/4hA05BIGgxIS1xyqXvNh7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmkTu3/dJMcab4d57k/4hA05BIGgxIS1xyqXvNh7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmkTu3/dJMcab4d57k/4hA05BIGgxIS1xyqXvNh7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmkTu3%2FdJMcab4d57k%2F4hA05BIGgxIS1xyqXvNh7k%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;480&quot; height=&quot;259&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; &lt;span&gt;&lt;a href=&quot;https://developers.sap.com/trials-downloads.html&quot;&gt;https://developers.sap.com/trials-downloads.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Part1~11 + License =&amp;gt; 총 12개 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Part1~11 파일 압축해제 방법 : Part1 파일만 압축해제하면, 나머지 자동 해제 (반디집 사용 추천)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  &lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;3. VirtualBox 설치 및 가상머신 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : Windows에서 SAP 설치용 Linux 가상환경 구성&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;gt;&amp;nbsp;&lt;a href=&quot;https://www.virtualbox.org/wiki/Downloads&quot;&gt;https://www.virtualbox.org/wiki/Downloads&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; VirtualBox 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*설치 오류 시, Visual C++ x64 설치 후 재시도&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;gt; 새로만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; ISO Image - 1에서 다운받은 openSUSE iso 파일 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 기본메모리와 프로세서는 녹색 최대치까지, 디스크 크기는 100GB&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 만들기 완료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  4. openSUSE 설치 및 초기 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 설치가 가능한 Linux 환경 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjpN2u/dJMcaflgADm/kLViCZSKiJaP0InfHfaIN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjpN2u/dJMcaflgADm/kLViCZSKiJaP0InfHfaIN0/img.png&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;590&quot; data-is-animation=&quot;false&quot; width=&quot;383&quot; height=&quot;289&quot; style=&quot;width: 53.7737%; margin-right: 10px;&quot; data-widthpercent=&quot;54.41&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjpN2u/dJMcaflgADm/kLViCZSKiJaP0InfHfaIN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjpN2u%2FdJMcaflgADm%2FkLViCZSKiJaP0InfHfaIN0%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;781&quot; height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crN7MN/dJMcafMmrrH/4lpyZmRj2HbIUpP1wTX881/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crN7MN/dJMcafMmrrH/4lpyZmRj2HbIUpP1wTX881/img.png&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;741&quot; data-is-animation=&quot;false&quot; width=&quot;378&quot; height=&quot;341&quot; style=&quot;width: 45.0635%;&quot; data-widthpercent=&quot;45.59&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crN7MN/dJMcafMmrrH/4lpyZmRj2HbIUpP1wTX881/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrN7MN%2FdJMcafMmrrH%2F4lpyZmRj2HbIUpP1wTX881%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;822&quot; height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Installation &amp;gt; Next&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XV5Tr/dJMcabwn6wx/tKeCpMBORxg4RQw5DSyJIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XV5Tr/dJMcabwn6wx/tKeCpMBORxg4RQw5DSyJIk/img.png&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;742&quot; data-is-animation=&quot;false&quot; width=&quot;350&quot; height=&quot;319&quot; style=&quot;width: 45.9108%; margin-right: 10px;&quot; data-widthpercent=&quot;46.45&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XV5Tr/dJMcabwn6wx/tKeCpMBORxg4RQw5DSyJIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXV5Tr%2FdJMcabwn6wx%2FtKeCpMBORxg4RQw5DSyJIk%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;814&quot; height=&quot;742&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv6LZB/dJMcaflgA2w/KBlf6s6kGmQCN92JoT7kb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv6LZB/dJMcaflgA2w/KBlf6s6kGmQCN92JoT7kb0/img.png&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;869&quot; data-is-animation=&quot;false&quot; width=&quot;457&quot; height=&quot;361&quot; style=&quot;width: 52.9264%;&quot; data-widthpercent=&quot;53.55&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv6LZB/dJMcaflgA2w/KBlf6s6kGmQCN92JoT7kb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv6LZB%2FdJMcaflgA2w%2FKBlf6s6kGmQCN92JoT7kb0%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;1099&quot; height=&quot;869&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Yes &amp;gt; Next&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TFIR6/dJMcaflgBds/dGFMkkXbHQ66tzk5EME571/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TFIR6/dJMcaflgBds/dGFMkkXbHQ66tzk5EME571/img.png&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;862&quot; data-is-animation=&quot;false&quot; width=&quot;458&quot; height=&quot;363&quot; style=&quot;width: 49.5678%; margin-right: 10px;&quot; data-widthpercent=&quot;50.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TFIR6/dJMcaflgBds/dGFMkkXbHQ66tzk5EME571/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTFIR6%2FdJMcaflgBds%2FdGFMkkXbHQ66tzk5EME571%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;1089&quot; height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q17oV/dJMcajuoX1C/wJaK8vD2CGmuAGSl5Bwfk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q17oV/dJMcajuoX1C/wJaK8vD2CGmuAGSl5Bwfk0/img.png&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;872&quot; data-is-animation=&quot;false&quot; width=&quot;489&quot; height=&quot;389&quot; style=&quot;width: 49.2694%;&quot; data-widthpercent=&quot;49.85&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q17oV/dJMcajuoX1C/wJaK8vD2CGmuAGSl5Bwfk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq17oV%2FdJMcajuoX1C%2FwJaK8vD2CGmuAGSl5Bwfk0%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;1095&quot; height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Desktop with GNOME&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; (중요) Expert Partitioner&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Start with Current Proposal&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ew1pc8/dJMb99SSG9c/IvCgpPTslhkVDUQAjYukvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ew1pc8/dJMb99SSG9c/IvCgpPTslhkVDUQAjYukvK/img.png&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;876&quot; data-is-animation=&quot;false&quot; width=&quot;486&quot; height=&quot;386&quot; style=&quot;width: 49.4685%; margin-right: 10px;&quot; data-widthpercent=&quot;50.05&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ew1pc8/dJMb99SSG9c/IvCgpPTslhkVDUQAjYukvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Few1pc8%2FdJMb99SSG9c%2FIvCgpPTslhkVDUQAjYukvK%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;1104&quot; height=&quot;876&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egVnVH/dJMcaaRO2Vx/mropJViX2tRLEa3IaUFCjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egVnVH/dJMcaaRO2Vx/mropJViX2tRLEa3IaUFCjk/img.png&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;873&quot; data-is-animation=&quot;false&quot; width=&quot;497&quot; height=&quot;395&quot; style=&quot;width: 49.3687%;&quot; data-widthpercent=&quot;49.95&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egVnVH/dJMcaaRO2Vx/mropJViX2tRLEa3IaUFCjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegVnVH%2FdJMcaaRO2Vx%2FmropJViX2tRLEa3IaUFCjk%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;1098&quot; height=&quot;873&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;sda2 선택하고 Edit 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Format device - Filesystem - Ext4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*SAP 설치에 사용할 디스크를 리눅스용(ext4)으로 준비 / 대용량을 지원하는 파일시스템으로 변경하는 것임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3KN9/dJMcab4ebNB/6XHgUNntcowKqwQa5Udoh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3KN9/dJMcab4ebNB/6XHgUNntcowKqwQa5Udoh1/img.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;869&quot; data-is-animation=&quot;false&quot; width=&quot;474&quot; height=&quot;374&quot; style=&quot;width: 49.8532%; margin-right: 10px;&quot; data-widthpercent=&quot;50.44&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3KN9/dJMcab4ebNB/6XHgUNntcowKqwQa5Udoh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3KN9%2FdJMcab4ebNB%2F6XHgUNntcowKqwQa5Udoh1%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;1102&quot; height=&quot;869&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BjJTf/dJMcaaxvj8y/wAJiJjidc97hb78V1wiIdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BjJTf/dJMcaaxvj8y/wAJiJjidc97hb78V1wiIdK/img.png&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;878&quot; data-is-animation=&quot;false&quot; width=&quot;518&quot; style=&quot;width: 48.984%;&quot; data-widthpercent=&quot;49.56&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BjJTf/dJMcaaxvj8y/wAJiJjidc97hb78V1wiIdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBjJTf%2FdJMcaaxvj8y%2FwAJiJjidc97hb78V1wiIdK%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;1094&quot; height=&quot;878&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Accept&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; &lt;span style=&quot;color: #000000; text-align: center; letter-spacing: 0px;&quot;&gt;Asia, Seoul 선택&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUceXz/dJMcahXGNKB/5H34Gz5SbG7AHLLxgj0VWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUceXz/dJMcahXGNKB/5H34Gz5SbG7AHLLxgj0VWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUceXz/dJMcahXGNKB/5H34Gz5SbG7AHLLxgj0VWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUceXz%2FdJMcahXGNKB%2F5H34Gz5SbG7AHLLxgj0VWk%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;517&quot; height=&quot;412&quot; data-origin-width=&quot;1095&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;(중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;username: vhcalnplci&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pw: Down1oad&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;877&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daggKI/dJMcafyO1cn/DIFDmVSs91GqtTcuHxKKsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daggKI/dJMcafyO1cn/DIFDmVSs91GqtTcuHxKKsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daggKI/dJMcafyO1cn/DIFDmVSs91GqtTcuHxKKsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaggKI%2FdJMcafyO1cn%2FDIFDmVSs91GqtTcuHxKKsk%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;531&quot; height=&quot;421&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;877&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;(중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firewall : disabled&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH service : enabled&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 사진과 같이 설정하고 Install&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 설치 완료되면 boot from harddisk로 부팅&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;   5. 가상머신 네트워크 및 Hostname 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 서버 이름과 IP를 고정하여 설치 오류 방지&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cp8joh/dJMcajnB750/AxHtmhycFz2RIQfILsnBD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cp8joh/dJMcajnB750/AxHtmhycFz2RIQfILsnBD1/img.png&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;858&quot; data-is-animation=&quot;false&quot; width=&quot;522&quot; height=&quot;411&quot; style=&quot;width: 49.5849%; margin-right: 10px;&quot; data-widthpercent=&quot;50.17&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cp8joh/dJMcajnB750/AxHtmhycFz2RIQfILsnBD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcp8joh%2FdJMcajnB750%2FAxHtmhycFz2RIQfILsnBD1%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;1089&quot; height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zu018/dJMcajnB77m/gpwkKXkpLeGzbcxWpOExL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zu018/dJMcajnB77m/gpwkKXkpLeGzbcxWpOExL0/img.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;863&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.2523%;&quot; data-widthpercent=&quot;49.83&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zu018/dJMcajnB77m/gpwkKXkpLeGzbcxWpOExL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzu018%2FdJMcajnB77m%2FgpwkKXkpLeGzbcxWpOExL0%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;1088&quot; height=&quot;863&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;root 로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; terminal 실행 후 `sudo -i` 입력 (sudo = super user do)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*super user 상태여야 문제가 발생하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kQ3tq/dJMcachMECC/y2pBuK6uPENJ3Kg4sGXVVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kQ3tq/dJMcachMECC/y2pBuK6uPENJ3Kg4sGXVVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kQ3tq/dJMcachMECC/y2pBuK6uPENJ3Kg4sGXVVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkQ3tq%2FdJMcachMECC%2Fy2pBuK6uPENJ3Kg4sGXVVK%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;901&quot; height=&quot;527&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;IP 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `ip addr`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 127.0.0.1 확인 : (localhost)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; 10.0.2.15 확인 &lt;/span&gt;: (VirtualBox NAT 네트워크에서 VM에 할당된 IP, SAP 설치 시 hostname/IP 설정에 쓰는 IP)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djMcys/dJMcafMmvqj/aJ0l9tXsAUX2em4oCxzXkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djMcys/dJMcafMmvqj/aJ0l9tXsAUX2em4oCxzXkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djMcys/dJMcafMmvqj/aJ0l9tXsAUX2em4oCxzXkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjMcys%2FdJMcafMmvqj%2FaJ0l9tXsAUX2em4oCxzXkk%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;500&quot; height=&quot;662&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;hosts 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `nano /etc/hosts`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `10.0.2.15&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;vhcalnplci.dummy.nodomain&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;vhcalnplci`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; Ctrl + X -&amp;gt; Y&lt;span&gt;&amp;nbsp; &lt;/span&gt;Enter&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;*가상머신 IP(10.0.2.15)와 hostname(vhcalnplci) 매핑을 위해 /etc/hosts 파일 수정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n0B7T/dJMcagxGS9C/85EJpsNmuP4VfG8EhTgFIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n0B7T/dJMcagxGS9C/85EJpsNmuP4VfG8EhTgFIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n0B7T/dJMcagxGS9C/85EJpsNmuP4VfG8EhTgFIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn0B7T%2FdJMcagxGS9C%2F85EJpsNmuP4VfG8EhTgFIk%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;247&quot; height=&quot;41&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;hostname 설정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `nano /etc/hostname`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `vhcalnplci`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Ctrl + X -&amp;gt; Y Enter&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*SAP 설치를 위해 가상머신의 hostname을 vhcalnplci로 설정&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;gt; `reboot`&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;재부팅 후 root 권한 재설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `sudo -i`&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;`sudo -i` : 슈퍼유저 로그인, root 사용자 최상단 폴더로 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`sudo -s` : 슈퍼유저 로그인, 현재 폴더 위치 유지&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt; 6. 필수 패키지 업데이트 및 설치&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 설치 필수 라이브러리 준비&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmrQx/dJMcabXsVNj/z7Ijqc4wzkff1DzEj0ZZ41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmrQx/dJMcabXsVNj/z7Ijqc4wzkff1DzEj0ZZ41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmrQx/dJMcabXsVNj/z7Ijqc4wzkff1DzEj0ZZ41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpmrQx%2FdJMcabXsVNj%2Fz7Ijqc4wzkff1DzEj0ZZ41%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;500&quot; height=&quot;305&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 업데이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `zypper refresh`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(Ask PackageKit to quit &lt;/span&gt;질문이 나오면 터미널 창만 닫고 다시 터미널창 켜서 &lt;span&gt;`sudo -i`&amp;nbsp; &amp;gt; `&lt;/span&gt;&lt;span&gt;zypper refresh` &lt;/span&gt;하는걸 반복하면 &lt;span&gt;2~3&lt;/span&gt;번 내로 정상적으로 돌아감&lt;span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `zypper update`&lt;/span&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;span&gt;필수 패키지 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `zypper in uuidd tcsh libaio1`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*uuidd : SAP 시스템 식별번호 생성 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*tcsh : SAP 설치 스크립트 실행 쉘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*libaio1 : SAP 필수 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;※&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; `rpm -qa | grep {라이브러리 이름}` 으로 설치 여부 검색 가능&lt;/p&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;487&quot; data-ke-size=&quot;size16&quot;&gt;※ 이미 설치된 경우 nothing to do 메시지 출력&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;span&gt;uuid 서비스 실행 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `service --status-all | grep uuidd`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 현재 실행중인거 아직 없는거 확인 (SAP 설치 직전에 실행할 예정)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;7. VirtualBox 공유폴더 설정 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : Windows &amp;harr; Linux 간 SAP 설치 파일 공유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;829&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I5OYO/dJMcahwDyyk/rDlvCoWnhjbxKChKxD1kE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I5OYO/dJMcahwDyyk/rDlvCoWnhjbxKChKxD1kE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I5OYO/dJMcahwDyyk/rDlvCoWnhjbxKChKxD1kE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI5OYO%2FdJMcahwDyyk%2FrDlvCoWnhjbxKChKxD1kE1%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;500&quot; height=&quot;287&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;829&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;공유폴더 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Virtual Box의 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 공유 폴더 탭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 추가 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 압축해제한 SAP 파일 있는 폴더로 Path 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 자동마운트 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt;&lt;span&gt; 8. SAP NetWeaver 설치 실행&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1748&quot; data-start=&quot;1730&quot; data-ke-size=&quot;size16&quot;&gt;목적 : SAP 서버 설치&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x0aAk/dJMcabiThN0/OjcYVf9SAcdtGAkMa8zOak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x0aAk/dJMcabiThN0/OjcYVf9SAcdtGAkMa8zOak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x0aAk/dJMcabiThN0/OjcYVf9SAcdtGAkMa8zOak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx0aAk%2FdJMcabiThN0%2FOjcYVf9SAcdtGAkMa8zOak%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;500&quot; height=&quot;130&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SAP 라이선스 파일 위치 확인&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;gt; server/TAR/x86_64 안에, 라이선스 파일 넣어두기 (설치 과정에서 자동으로 사용됨)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpOuNR/dJMcaf6Dq4l/1Hj0gKDYnCknNVQib0pNok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpOuNR/dJMcaf6Dq4l/1Hj0gKDYnCknNVQib0pNok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpOuNR/dJMcaf6Dq4l/1Hj0gKDYnCknNVQib0pNok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpOuNR%2FdJMcaf6Dq4l%2F1Hj0gKDYnCknNVQib0pNok%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;500&quot; height=&quot;351&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 설치 파일 위치 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `cd /media`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `cd sf_sap`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `ls -l`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; install.sh 파일 확인, 실행권한 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kibmo/dJMcafyO5sb/voWGokFKhmhcufzRbiB9l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kibmo/dJMcafyO5sb/voWGokFKhmhcufzRbiB9l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kibmo/dJMcafyO5sb/voWGokFKhmhcufzRbiB9l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKibmo%2FdJMcafyO5sb%2FvoWGokFKhmhcufzRbiB9l1%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;500&quot; height=&quot;343&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 로그인 및 시스템 생성에 필요한 서비스 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `sudo systemctl status uuidd` 현재 상태 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; inactive인 것 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; ctrl + c 로 나오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `sudo systemctl start uuidd` 로 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 다시 `sudo systemctl status uuidd` 로 상태 active 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mbEHR/dJMcafyO5wu/iofVRtP7YkzSuuSQrL6Ho0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mbEHR/dJMcafyO5wu/iofVRtP7YkzSuuSQrL6Ho0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mbEHR/dJMcafyO5wu/iofVRtP7YkzSuuSQrL6Ho0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmbEHR%2FdJMcafyO5wu%2FiofVRtP7YkzSuuSQrL6Ho0%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;500&quot; height=&quot;370&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 설치 스크립트 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; `./install.sh`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 약관 나오면 q 로 나오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 약관 동의 yes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 암호 2번 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 자동 설치 시작 (약 10~15분 소요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 설치 중 화면이 위 화면으로 멈춘듯이 보여도 정상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*최소 70GB 이상 디스크 용량 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YcsIa/dJMcabJXK8W/9UpYAb50AEaor7kt5QudYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YcsIa/dJMcabJXK8W/9UpYAb50AEaor7kt5QudYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YcsIa/dJMcabJXK8W/9UpYAb50AEaor7kt5QudYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYcsIa%2FdJMcabJXK8W%2F9UpYAb50AEaor7kt5QudYk%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;500&quot; height=&quot;369&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;설치 완료 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Installation of NPL successful&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt;&lt;span&gt;&lt;span&gt; 9. 포트 포워딩 설정 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : Windows에서 SAP 서버 접속 가능하도록 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1439&quot; data-origin-height=&quot;831&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cavB8W/dJMb99L5868/s4JRvsoou4OoMK6W0EqJFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cavB8W/dJMb99L5868/s4JRvsoou4OoMK6W0EqJFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cavB8W/dJMb99L5868/s4JRvsoou4OoMK6W0EqJFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcavB8W%2FdJMb99L5868%2Fs4JRvsoou4OoMK6W0EqJFk%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;500&quot; height=&quot;289&quot; data-origin-width=&quot;1439&quot; data-origin-height=&quot;831&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;VirtualBox의 설정 &amp;gt; 네트워크 탭 &amp;gt; 포트 포워딩 버튼 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pm7EH/dJMcaaRO8ii/eA9WYKJgW2FtS4LKRzPKm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pm7EH/dJMcaaRO8ii/eA9WYKJgW2FtS4LKRzPKm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pm7EH/dJMcaaRO8ii/eA9WYKJgW2FtS4LKRzPKm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPm7EH%2FdJMcaaRO8ii%2FeA9WYKJgW2FtS4LKRzPKm0%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;500&quot; height=&quot;261&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;RFC TCP 127.0.0.1 3300 10.0.2.15 3300&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SAP GUI TCP 127.0.0.1 3200 10.0.2.15 3200 &lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SSH TCP 127.0.0.1 22 10.0.2.15 22 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인 &lt;span&gt;&amp;gt; &lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 10. SAP GUI 설치 및 접속 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : Windows에서 SAP 시스템(NPL)에 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;733&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ndK2n/dJMcacWmwcH/3lkVW7RfpKhHHpDAAKHBZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ndK2n/dJMcacWmwcH/3lkVW7RfpKhHHpDAAKHBZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ndK2n/dJMcacWmwcH/3lkVW7RfpKhHHpDAAKHBZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FndK2n%2FdJMcacWmwcH%2F3lkVW7RfpKhHHpDAAKHBZK%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;500&quot; height=&quot;383&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;733&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SAP GUI &lt;/span&gt;설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; client &lt;/span&gt;폴더 아래 설치파일 경로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;nbsp;&lt;span&gt;SAP\client\SAPGUI4Windows\50144807_6 압축해제&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 이어서 &lt;span&gt;\BD_NW_7.0_Presentation_7.50_Comp._2_\PRES1\GUI\WINDOWS\Win32&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; SapGuiSetup.exe &lt;/span&gt;실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 첫번째 &lt;span&gt;SAP GUI for ~ &lt;/span&gt;체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; Next, Next 누르면 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; SAP Logon 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UCKt9/dJMcaa5kFpb/F7W0KqPN1qq6pXxksB0Nr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UCKt9/dJMcaa5kFpb/F7W0KqPN1qq6pXxksB0Nr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UCKt9/dJMcaa5kFpb/F7W0KqPN1qq6pXxksB0Nr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUCKt9%2FdJMcaa5kFpb%2FF7W0KqPN1qq6pXxksB0Nr0%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;350&quot; height=&quot;346&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;신규 시스템 엔트리 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 연결 탭에서 빈 공간 우클릭, 신규 엔트리 추가 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 사용자 지정 시스템 선택된 상태에서 다음 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boahxH/dJMcahXGSDj/sht5RWxvG1YLBTTDjiiojK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boahxH/dJMcahXGSDj/sht5RWxvG1YLBTTDjiiojK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boahxH/dJMcahXGSDj/sht5RWxvG1YLBTTDjiiojK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboahxH%2FdJMcahXGSDj%2Fsht5RWxvG1YLBTTDjiiojK%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;400&quot; height=&quot;425&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;접속 정보 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 아래 3가지 입력&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;739&quot; data-start=&quot;654&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;690&quot; data-start=&quot;654&quot;&gt;Application Server : 127.0.0.1&lt;/li&gt;
&lt;li data-end=&quot;717&quot; data-start=&quot;691&quot;&gt;Instance Number : 00&lt;/li&gt;
&lt;li data-end=&quot;739&quot; data-start=&quot;718&quot;&gt;System ID : NPL&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;787&quot; data-start=&quot;741&quot; data-ke-size=&quot;size16&quot;&gt;&amp;gt; 입력하면 나머지 정보는 자동으로 채워짐&lt;br /&gt;&amp;gt; 다음 &amp;rarr; 다음 &amp;rarr; 종료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;734&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGSBuD/dJMb99ZGjjX/uOusi6cA0qbN8OQ7dvhBs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGSBuD/dJMb99ZGjjX/uOusi6cA0qbN8OQ7dvhBs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGSBuD/dJMb99ZGjjX/uOusi6cA0qbN8OQ7dvhBs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGSBuD%2FdJMb99ZGjjX%2FuOusi6cA0qbN8OQ7dvhBs0%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;500&quot; height=&quot;379&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;734&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;생성된 엔트리 더블클릭&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xVUSE/dJMcaiPMiRK/ymqfXemjP5IAuWERFNWuk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xVUSE/dJMcaiPMiRK/ymqfXemjP5IAuWERFNWuk0/img.png&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;1217&quot; data-is-animation=&quot;false&quot; width=&quot;500&quot; height=&quot;593&quot; style=&quot;width: 49.6124%; margin-right: 10px;&quot; data-widthpercent=&quot;50.2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xVUSE/dJMcaiPMiRK/ymqfXemjP5IAuWERFNWuk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxVUSE%2FdJMcaiPMiRK%2FymqfXemjP5IAuWERFNWuk0%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;1027&quot; height=&quot;1217&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcjmri/dJMcaiI1EE3/ZBdHLH1LV6JTp0lOaEtHuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcjmri/dJMcaiI1EE3/ZBdHLH1LV6JTp0lOaEtHuK/img.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1223&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.2248%;&quot; data-widthpercent=&quot;49.8&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcjmri/dJMcaiI1EE3/ZBdHLH1LV6JTp0lOaEtHuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdcjmri%2FdJMcaiI1EE3%2FZBdHLH1LV6JTp0lOaEtHuK%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;1024&quot; height=&quot;1223&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; User : DEVELOPER&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Password : Down1oad&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  11. SAP 라이선스 발급 및 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 시스템 사용 가능 상태로 활성화 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EzLZR/dJMcacoxpCf/2b6Bf67y5uTyRkfuYrPQw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EzLZR/dJMcacoxpCf/2b6Bf67y5uTyRkfuYrPQw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EzLZR/dJMcacoxpCf/2b6Bf67y5uTyRkfuYrPQw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEzLZR%2FdJMcacoxpCf%2F2b6Bf67y5uTyRkfuYrPQw1%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;300&quot; height=&quot;90&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2a4c9%2FdJMcadgGfKj%2FeZaEnt5ZTIOqRsu5sa5w10%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;300&quot; height=&quot;186&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SAP 라이선스 관리 화면 접속&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;gt; SAP GUI 로그인 후 실행창에 입력 : `slicense`&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;gt; Hardware Key 확인&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;1276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7Fx8/dJMcaioL763/Lq9lFLQIfu0unjkWgRwpc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7Fx8/dJMcaioL763/Lq9lFLQIfu0unjkWgRwpc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7Fx8/dJMcaioL763/Lq9lFLQIfu0unjkWgRwpc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7Fx8%2FdJMcaioL763%2FLq9lFLQIfu0unjkWgRwpc1%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;500&quot; height=&quot;491&quot; data-origin-width=&quot;1299&quot; data-origin-height=&quot;1276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 라이선스 발급 사이트 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; &lt;a href=&quot;https://go.support.sap.com/minisap/&quot;&gt;https://go.support.sap.com/minisap/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; &lt;span&gt;NPL &amp;ndash; SAP NetWeaver 7.x (Sybase ASE) &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; Hardware Key 등 Info 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 약관 동의 후 Generate&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; NPL.txt 파일 다운로드 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot; width=&quot;300&quot; height=&quot;186&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;399&quot; data-origin-width=&quot;643&quot; data-widthpercent=&quot;44.97&quot; style=&quot;width: 44.449%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2a4c9/dJMcadgGfKj/eZaEnt5ZTIOqRsu5sa5w10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2a4c9%2FdJMcadgGfKj%2FeZaEnt5ZTIOqRsu5sa5w10%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;643&quot; height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCjKzT/dJMcadAU2EA/4RVijexaiT1PVegiRhQtIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCjKzT/dJMcadAU2EA/4RVijexaiT1PVegiRhQtIK/img.png&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;818&quot; data-is-animation=&quot;false&quot; width=&quot;500&quot; height=&quot;254&quot; style=&quot;width: 54.3882%;&quot; data-widthpercent=&quot;55.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCjKzT/dJMcadAU2EA/4RVijexaiT1PVegiRhQtIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCjKzT%2FdJMcadAU2EA%2F4RVijexaiT1PVegiRhQtIK%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;1613&quot; height=&quot;818&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 라이선스 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 다시 SAP GUI - slicense&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 새로고침 옆 Install New License 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 다운로드한 NPL.txt 업로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; DEMOSYSTEM 항목의 System No이 0이 아닌 값으로 표시되면 정상 적용&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 기존 라이선스가 있는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; DEMOSYSTEM이 적힌 라이선스 삭제 : 우클릭 - Delete License&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; 새로 발급한 NPL.txt 다시 업로드&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;gt; 이미 만료되면, DEVELOPER로 로그인 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; User : sap* / Password : Down1oad&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;   12. SAP 설치 정상 동작 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : SAP 개발 환경 정상 사용 가능 여부 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rv4ru/dJMcaiCgIXa/33qeacgcOMYMz5gUk5hFPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rv4ru/dJMcaiCgIXa/33qeacgcOMYMz5gUk5hFPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rv4ru/dJMcaiCgIXa/33qeacgcOMYMz5gUk5hFPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frv4ru%2FdJMcaiCgIXa%2F33qeacgcOMYMz5gUk5hFPK%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;400&quot; height=&quot;492&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;개발 환경 실행 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; T-code 실행창에 입력 : `SE80`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;nbsp;&lt;span&gt;Repository Browser - Local Objects - DEVELOPER - 엔터 - Programs - &lt;/span&gt;마우스 오른쪽 &lt;span&gt;Create 로 프로그램 생성 가능까지 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxzCb8/dJMcaibe4PW/YazchmGkTQLhlrXtAzzJp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxzCb8/dJMcaibe4PW/YazchmGkTQLhlrXtAzzJp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxzCb8/dJMcaibe4PW/YazchmGkTQLhlrXtAzzJp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxzCb8%2FdJMcaibe4PW%2FYazchmGkTQLhlrXtAzzJp1%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;400&quot; height=&quot;298&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;ABAP 예제 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt; F1 누르면 예제 확인 가능&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;   13. SAP 서버 재시작 방법 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 : 가상머신 재부팅 후 SAP 시스템 재가동&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zpdaB/dJMcabiTjK7/lfYDcPckiNOeyn17G9ZVB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zpdaB/dJMcabiTjK7/lfYDcPckiNOeyn17G9ZVB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zpdaB/dJMcabiTjK7/lfYDcPckiNOeyn17G9ZVB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzpdaB%2FdJMcabiTjK7%2FlfYDcPckiNOeyn17G9ZVB0%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;600&quot; height=&quot;113&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 로그아웃 상태에서 가상머신 터미널 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `sudo -i`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `su npladm`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; `startsap all`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; 출력 메세지 &quot;Instance on host vhcalnplci started&quot; 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;gt; SAP GUI에서 다시 로그인 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &lt;/b&gt; &lt;b&gt; &lt;/b&gt; &lt;b&gt; &lt;/b&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Windows 환경에서 SAP 개발 환경 구축 완료!&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Mac에서 시작해 Windows 환경까지 설치를 3번이나 진행해보았는데,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이제 전체 흐름이 잘 보이는 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;앞으로 3개월마다 라이선스 잘 갱신하면서 SAP 개발 실습을 해보자~&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/SAP ABAP</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/311</guid>
      <comments>https://coding-dahee.tistory.com/311#entry311comment</comments>
      <pubDate>Wed, 18 Feb 2026 03:29:24 +0900</pubDate>
    </item>
    <item>
      <title>ALV 리포트 출력 코드 뜯어보기 with SCARR 테이블</title>
      <link>https://coding-dahee.tistory.com/310</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;포스팅 목적&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ABAP 공부를 하면서 ALV 리포트를 처음 만들게 되었는데,&lt;br /&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;등장 개념&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`아밥타입`, `데이터타입`, `내부 테이블`, `행`, `필드 카탈로그`, `구조체`&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;br /&gt;출력할 ALV 리포트&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfFRec/dJMcahpJ6Qi/FO59IhGlqgTkg9QoVlmsnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfFRec/dJMcahpJ6Qi/FO59IhGlqgTkg9QoVlmsnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfFRec/dJMcahpJ6Qi/FO59IhGlqgTkg9QoVlmsnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfFRec%2FdJMcahpJ6Qi%2FFO59IhGlqgTkg9QoVlmsnK%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;503&quot; height=&quot;362&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;전체 코드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCARR 테이블의 정보를 ALV로 출력하는 코드&lt;/p&gt;
&lt;pre id=&quot;code_1769919731767&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp; Report Z2WEEK_ALV000_SCARR
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;
*&amp;amp;---------------------------------------------------------------------*
REPORT Z2WEEK_ALV000_SCARR.

TABLES:     scarr.

TYPE-POOLS: slis.  

*Data Declaration: 데이터 담기 (엑셀에 첫 행 구성)
*----------------
TYPES: BEGIN OF t_scarr,
  mandt     TYPE scarr-mandt,
  carrid    TYPE scarr-carrid,
  carrname  TYPE scarr-carrname,
  currcode  TYPE scarr-currcode,
  url       TYPE scarr-url,
 END OF t_scarr.

*it_scarr로 표를 만든거임. internal-table
DATA: it_scarr TYPE STANDARD TABLE OF t_scarr INITIAL SIZE 0.

*ALV data declarations
DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE,
      gd_tab_group TYPE slis_t_sp_group_alv,
      gd_layout    TYPE slis_layout_alv,
      gd_repid     LIKE sy-repid.

************************************************************************
*Start-of-selection.
START-OF-SELECTION.

  PERFORM data_retrieval.
  PERFORM build_fieldcatalog.
  PERFORM build_layout.
  PERFORM display_alv_report.


*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  BUILD_FIELDCATALOG
*&amp;amp;---------------------------------------------------------------------*
*       Build Fieldcatalog for ALV Report
*----------------------------------------------------------------------*
*제목을 붙이는 작업
FORM build_fieldcatalog.

  fieldcatalog-fieldname   = 'MANDT'.
  fieldcatalog-seltext_m   = 'Client'.
  fieldcatalog-col_pos     = 0.
  fieldcatalog-outputlen   = 10.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CARRID'.
  fieldcatalog-seltext_m   = 'Airline Code'.
  fieldcatalog-col_pos     = 1.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CARRNAME'.
  fieldcatalog-seltext_m   = 'Airline name'.
  fieldcatalog-col_pos     = 2.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CURRCODE'.
  fieldcatalog-seltext_m   = 'Local currency of airline'.
  fieldcatalog-col_pos     = 3.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'URL'.
  fieldcatalog-seltext_m   = 'Airline URL'.
  fieldcatalog-col_pos     = 4.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.
ENDFORM.                    &quot; BUILD_FIELDCATALOG


*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  BUILD_LAYOUT
*&amp;amp;---------------------------------------------------------------------*
*       Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM build_layout.

  gd_layout-no_input          = 'X'.
  gd_layout-colwidth_optimize = 'X'.
  gd_layout-zebra = 'X'.

ENDFORM.                    &quot; BUILD_LAYOUT


*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  DISPLAY_ALV_REPORT
*&amp;amp;---------------------------------------------------------------------*
*       Display report using ALV grid
*----------------------------------------------------------------------*
FORM display_alv_report.
  gd_repid = sy-repid.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = gd_repid
      is_layout          = gd_layout &quot;위에 붙인 3가지 옵션(build_layout)
      it_fieldcat        = fieldcatalog[] &quot;필드별 제목 넣었던 거
      i_save             = 'X'
    TABLES
      t_outtab           = it_scarr &quot;내가 담은 테이블 출력
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.
  IF sy-subrc &amp;lt;&amp;gt; 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.


ENDFORM.                    &quot; DISPLAY_ALV_REPORT


*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  DATA_RETRIEVAL
*&amp;amp;---------------------------------------------------------------------*
FORM data_retrieval.

  SELECT mandt carrid carrname currcode url
   UP TO 10 ROWS
    FROM scarr    &quot;항공사 테이블
    INTO TABLE it_scarr.

ENDFORM.                    &quot; DATA_RETRIEVAL&lt;/code&gt;&lt;/pre&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;코드 구역별 설명&lt;/b&gt;&lt;/h4&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;pre id=&quot;code_1769922195581&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
REPORT Z2WEEK_ALV000_SCARR.

TABLES:     scarr.

TYPE-POOLS: slis.                

*Data Declaration: 데이터 담기 (엑셀에 첫 행 구성)
*----------------
TYPES: BEGIN OF t_scarr,
  mandt     TYPE scarr-mandt,
  carrid    TYPE scarr-carrid,
  carrname  TYPE scarr-carrname,
  currcode  TYPE scarr-currcode,
  url       TYPE scarr-url,
 END OF t_scarr.
 
 *it_scarr로 표를 만든거임. internal-table
DATA: it_scarr TYPE STANDARD TABLE OF t_scarr INITIAL SIZE 0.

*ALV data declarations
DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE,
      gd_tab_group TYPE slis_t_sp_group_alv,
      gd_layout    TYPE slis_layout_alv,
      gd_repid     LIKE sy-repid.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로그램 이름은 `Z2WEEK_ALV000_SCARR`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `scarr`라는 테이블 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;- `slis`는 ALV&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 출력을 위해 SAP가 제공하는 타입 풀. fieldcatalog, layout, 그룹핑 등 ALV 관련 구조와 테이블 타입들이 정의되어 있음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `BEGIN OF ... END OF` 구문은 구조체(structure) 타입을 정의&lt;br /&gt;=&amp;gt; `scarr` 테이블의 일부 필드인 `mandt`, `carrid`, `carname`, `currcode`, `url`을 사용하여, 한 행을 표현하는 `t_scarr` 구조 타입 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;it_scarr`는 `&lt;/span&gt;t_scarr` 구조를 행으로 갖는 내부 테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `fieldcatalog`는 `slis_t_fieldcat_alv` 타입의 내부 테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `slis_t_fieldcat_alv`는 출력할 필드의 속성을 정의하는 데 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `gd_tab_group`은 필드를 논리적으로 그룹핑하는 데 사용 (이 프로그램에서는 선언만 되고 사용은 x)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `gd_repid`는 현재 실행중인 프로그램 이름을 담기 위해 `sy-repid`와 같은 타입으로 선언된 변수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `sy`에 하이픈(-)으로 접근하면, 시스템 변수 사용 가능&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 실행부 `START-OF-SELECTION`&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769926330105&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
*Start-of-selection.
START-OF-SELECTION.

  PERFORM data_retrieval.
  PERFORM build_fieldcatalog.
  PERFORM build_layout.
  PERFORM display_alv_report.&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;- 실행부. &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 검색화면이 없는 경우, PERFORM 문을 통해 로직이 &lt;/span&gt;순차적으로 실행됨&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 검색화면이 있는 경우,&lt;span&gt; 검색화면에서 실행부분을 누르면 그 다음 로직이&lt;/span&gt;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 서브루틴 `data_retrieval`&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769926501005&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;!abap
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  DATA_RETRIEVAL
*&amp;amp;---------------------------------------------------------------------*
FORM data_retrieval.

  SELECT mandt carrid carrname currcode url
   UP TO 10 ROWS
    FROM scarr    &quot;항공사 테이블
    INTO TABLE it_scarr.

ENDFORM.                    &quot; DATA_RETRIEVAL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;- scarr 테이블에서 `mandt` ~ `url` 필드 조회하여, 미리 선언해둔 내부 테이블 `it_scarr`에 최대 10개 행을 한 번에 일괄 주입함&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4) &lt;b&gt;서브루틴 `build_fieldcatalog`&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769926379988&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  BUILD_FIELDCATALOG
*&amp;amp;---------------------------------------------------------------------*
*       Build Fieldcatalog for ALV Report
*----------------------------------------------------------------------*
*제목을 붙이는 작업
FORM build_fieldcatalog.

  fieldcatalog-fieldname   = 'MANDT'.
  fieldcatalog-seltext_m   = 'Client'.
  fieldcatalog-col_pos     = 0.
  fieldcatalog-outputlen   = 10.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CARRID'.
  fieldcatalog-seltext_m   = 'Airline Code'.
  fieldcatalog-col_pos     = 1.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CARRNAME'.
  fieldcatalog-seltext_m   = 'Airline name'.
  fieldcatalog-col_pos     = 2.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'CURRCODE'.
  fieldcatalog-seltext_m   = 'Local currency of airline'.
  fieldcatalog-col_pos     = 3.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'URL'.
  fieldcatalog-seltext_m   = 'Airline URL'.
  fieldcatalog-col_pos     = 4.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.
ENDFORM.                    &quot; BUILD_FIELDCATALOG&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;- 미리 선언된 `fieldcatalog`에 각 필드의 속성을 정의하여 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `fieldname`은 실제 데이터 테이블의 필드 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `seltext_m`은 ALV 컬럼 헤더에 표시되는 텍스트(한글도 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `col_pos`는 ALV 컬럼의 출력 순서 (0부터 시작, 왼쪽부터)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `APPEND fieldcatalog TO fieldcatalog`에서 첫번째 `fieldcatalog`는 행(work area), 두번째는 테이블을 의미한다. 따라서 테이블에 행을 주입한다. 이후 fieldcatalog(행)을 `clear`하여 다음 행 (work area) 주입 전에 값 초기화&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;&lt;br /&gt;5) &lt;b&gt;서브루틴 `build_layout`&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769926440533&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  BUILD_LAYOUT
*&amp;amp;---------------------------------------------------------------------*
*       Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM build_layout.

  gd_layout-no_input          = 'X'.
  gd_layout-colwidth_optimize = 'X'.
  gd_layout-zebra = 'X'.

ENDFORM.                    &quot; BUILD_LAYOUT&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;- ALV 그리드 출력 시 사용될 레이아웃(`gd_layout`) 설정 값을 지정하는 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `no_input = 'X'` : ALV 그리에서 셀 수정 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `colwidth_potimize = 'X'` : 컬럼 너비 자동 조정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - `zebra = 'X'` : 짝수/홀수 행에 색상 차이 주어 가독성 향상&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6) 서브루틴 `display_alv_report`&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769926446609&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!abap
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  DISPLAY_ALV_REPORT
*&amp;amp;---------------------------------------------------------------------*
*       Display report using ALV grid
*----------------------------------------------------------------------*
FORM display_alv_report.
  gd_repid = sy-repid.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = gd_repid
      is_layout          = gd_layout &quot;위에 붙인 3가지 옵션(build_layout)
      it_fieldcat        = fieldcatalog[] &quot;필드별 제목 넣었던 거
      i_save             = 'X'
    TABLES
      t_outtab           = it_scarr &quot;내가 담은 테이블 출력
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.
  IF sy-subrc &amp;lt;&amp;gt; 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.


ENDFORM.                    &quot; DISPLAY_ALV_REPORT&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;- ALV 리스트를 그리드 형태로 출력 (`REUSE_ALV_GRID_DISPLAY` 함수 모듈 이용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 출력에 필요한 요소를 `EXPORTING`과 `TABLES` 파라미터로 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 1) 프로그램&amp;nbsp; 이름 : `sy-repid`로 프로그램 이름을 가져올 수 있음. 이를 `gd_repid` 변수에 담아 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 2) 레이아웃 옵션 : `build_layout` 서브루틴에서 구성한 `gd_layout` 구조체 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 3) 데이터 : `build_fieldcatalog` 서브루틴에서 구성한 `fieldcatalog[]` 테이블 전체 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 4) 테이블 : `data_retrieval` 서브루틴에서 조회한 결과인 실제 데이터가 담긴 내부 테이블 `it_scarr`&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;&lt;br /&gt;정리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALV 리포트는&amp;nbsp;&lt;b&gt;데이터 + 필드 정의 + 화면 설정 + 출력 호출&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;이번 포스팅에서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 필요한 데이터를 먼저 불러오고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 내부 테이블과 행(구조체) 개념을 이해하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 필드를 어떻게 ALV에 넣는지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; 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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;원하는 데이터를 &lt;b&gt;어떻게 선언&lt;/b&gt;하고 &lt;b&gt;어떻게 다뤄야 ALV에서 출력&lt;/b&gt;이 되는지를 이해하는 것이 가장 중요한 것 같다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Study/SAP ABAP</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/310</guid>
      <comments>https://coding-dahee.tistory.com/310#entry310comment</comments>
      <pubDate>Sun, 1 Feb 2026 12:34:37 +0900</pubDate>
    </item>
    <item>
      <title>웹과 React Native에서 CORS는 어떻게 다를까? (+2024년 12월 근황)</title>
      <link>https://coding-dahee.tistory.com/309</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;i&gt;&lt;span style=&quot;background-color: #ffffff; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt; 본론으로 들어가기 전, 근황을 먼저 공유하겠다!&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;근황&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2024년 11월부터 &lt;b&gt;한국어능력시험 모의테스트 플랫폼&lt;/b&gt;&amp;nbsp;프로젝트 &lt;b&gt;[TopikOn]&lt;/b&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;프론트엔드&lt;/b&gt;를 맡고있고, 2025년 1월 출시를 목표로 하고있다. [나를 포함한 프론트 2명 + 백엔드 1명 + 디자이너 1명 + 기획자 1명 + 풀스택/기획/매니저 1명] = 총 6명과 함께한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모두가 리모트로 일하지만 가끔은 게더를 켜놓고 하루종일 같이 있는 기분을 느끼며 코딩할 때도 있다. 덕분에 밴쿠버에서 외롭지 않게 작업하고 있다ㅎㅎ&lt;/span&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;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;기술스택은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- 프론트엔드: React Native + Next.js&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- 백엔드: NestJS&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: left; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;React Native로는 이미 &lt;b&gt;[&lt;a href=&quot;https://www.roubit.me/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;루빗&lt;/a&gt;]&lt;/b&gt;에서 서비스 운영을 경험하고 &lt;b&gt;[&lt;a href=&quot;https://fastcampus.co.kr/dev_online_renative&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;패스트캠퍼스 강의&lt;/a&gt;]&lt;/b&gt;(접속 안되면 &lt;a href=&quot;https://fastcampus.co.kr/pages/33527&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 링크&lt;/a&gt;)까지 촬영해보았지만, &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Next.js를 활용한 서비스 개발은 처음이라 웹에 관련된 지식이 부족함을 느끼고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그래서 아주 기본이 되는 개념부터 실제 프로젝트를 진행하면서 발생하는 문제까지 다양한 주제로 글 발행을 할 예정이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;단순히 개념을 나열하기보단 현업에서의 연관성을 중심으로 작성한다.&lt;/span&gt;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: start;&quot;&gt;오늘은 웹과 React Native에서의 CORS 차이에 대해 짧게 다뤄본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;CORS (Cross-Origin Resource Sharing)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;브라우저 보안 정책을 이해할 때 기본이 되는 개념이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;CORS는 동일 출처 정책(Same-Origin Policy)으로 인해 다른 출처 간의 요청이 제한되는 것을 해결하고 안전하게 리소스를 공유하는 방법을 제공한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;우리 프로젝트의 백엔드는 어떻게 되어있을까?&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;1146&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1896S/btsLjlY6HeO/T2lybc1UmDjTMWPS95g6OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1896S/btsLjlY6HeO/T2lybc1UmDjTMWPS95g6OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1896S/btsLjlY6HeO/T2lybc1UmDjTMWPS95g6OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1896S%2FbtsLjlY6HeO%2FT2lybc1UmDjTMWPS95g6OK%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;1146&quot; height=&quot;212&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;212&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mDrDs/btsLs8K6634/5oI5eu0KBQX7M01OfdWzvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mDrDs/btsLs8K6634/5oI5eu0KBQX7M01OfdWzvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mDrDs/btsLs8K6634/5oI5eu0KBQX7M01OfdWzvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmDrDs%2FbtsLs8K6634%2F5oI5eu0KBQX7M01OfdWzvk%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;582&quot; height=&quot;425&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;904&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;편의를 위해 허용되어있겠다만, 제대로 처리한다면 클라이언트의 도메인만 처리되어야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 프론트 웹뷰에서 요청하는 도메인이 &lt;a href=&quot;http://www.topikon.com&quot;&gt;https://www.yourapp.com&lt;/a&gt;이라면 아래와 같이 허용할 도메인을 배열에 추가하여 화이트리스트에 등록한다.&lt;/p&gt;
&lt;pre id=&quot;code_1734327166769&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;app.enableCors({
  origin: [&quot;https://www.yourapp.com&quot;],
  ...
});&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 웹 클라이언트가 로컬호스트 환경에서 서버로 API를 테스트해야할 땐 문제가 될 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럴 땐 &lt;b&gt;프록시(proxy)&lt;/b&gt;를 사용해 Header의 Host를 수동으로 요청하여 서버가 허용한 도메인에서 보낸 것처럼 처리할 수 있다. (프로덕션 환경에서는 추천하지 않음.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 &lt;b&gt;서버&lt;/b&gt;에서는 API키, JWT토큰 등의 &lt;b&gt;추가 인증방식&lt;/b&gt;을 통해 클라이언트의 요청을 검증하는 등 다중 보안 레이어를 적용하는 것이 바람직하겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;  그런데 또 하나 생기는 궁금증.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;React Native에서 서버에 요청하는 건 CORS의 영향을 받지 않는걸까?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다. React Native는 웹 애플리케이션처럼 브라우저 환경이 아니라 네이티브 환경에서 실행되기 때문에 요청에 Origin 헤더가 포함되지 않는다. 브라우저가 아니므로 출처(Origin)라는 개념이 적용되지 않아 CORS 검사를 수행할 필요가 없는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대신 네트워크 라이브러리(fetch, axios)를 통해 요청이 직접 서버로 전달된다. 하지만 서버가 화이트리스트 도메인만 허용한다면, 추가적인 인증방식을 통해 검증이 필요하겠다. 가장 많이 쓰는 JWT토큰처럼.&lt;/p&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #474747;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;마무리&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Native 애플리케이션과는 달리, 웹 애플리케이션을 개발할 때는 브라우저의 보안 모델과 동작 원리에 대한 이해가 필수다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'동일 출처 정책(Same-Origin Policy)'과 이를 대응 하기 위한 CORS에 대해 정확히 알고 실제 프로덕트에서 디버깅, 프록시, 그리고 보안 인증 방식(JWT, API 키 등)과 같은 실전 기술을 활용하여 브라우저 보안을 극복해야한다.&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;</description>
      <category>Solve Problem/Deep Dive</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/309</guid>
      <comments>https://coding-dahee.tistory.com/309#entry309comment</comments>
      <pubDate>Mon, 16 Dec 2024 15:59:00 +0900</pubDate>
    </item>
    <item>
      <title>Vanilla JS로 SPA 화면전환 구현해보기 (feat. 프레임워크는 소중하다)</title>
      <link>https://coding-dahee.tistory.com/307</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;순수 Valnilla JS를 사용해 가계부 웹페이지를 만드는 프로젝트를 진행하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;JS만을 사용하다보니, Next.js같은 프레임워크에서 제공하는 기능들을 직접 구현해보는 기회가 되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아무래도 실무에서는 프레임워크를 사용할 확률이 훨씬 높겠지만, 프레임워크에서 어떤 부분들이 개발자의 수고를 덜어주는지 안다면 작동원리를 한층 깊게 이해하며 사용할 수 있게됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure style=&quot;color: #333333; text-align: center;&quot; contenteditable=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/008.gif&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-name=&quot;008&quot; data-emoticon-type=&quot;friends1&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;emoticon&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/008.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;✅그래서 오늘은! &lt;b&gt;JavaScript만으로 SPA를 직접&lt;/b&gt; 만들어보고 &lt;b&gt;작동원리를 이해&lt;/b&gt;해보는 시간을 가져볼게요.&lt;/span&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;SPA 화면 전환&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1044&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/msPLU/btsJ88gkkoA/jSTMQfm2kvbto67wohKhsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/msPLU/btsJ88gkkoA/jSTMQfm2kvbto67wohKhsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/msPLU/btsJ88gkkoA/jSTMQfm2kvbto67wohKhsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmsPLU%2FbtsJ88gkkoA%2FjSTMQfm2kvbto67wohKhsk%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;1044&quot; height=&quot;854&quot; data-origin-width=&quot;1044&quot; data-origin-height=&quot;854&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;오늘 만들어 볼 가계부 UI입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #666666;&quot;&gt;(Figma에서 expense tracker를 검색하면 나오는 &lt;a href=&quot;https://www.figma.com/community/file/998557875473123405/montra-expense-tracker-ui-kit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;템플릿&lt;/a&gt;을 사용했어요.)&lt;/span&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;페이지는 3개입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. Home:  지출 내역을  날짜별로 보는 페이지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. Add/Edit: 지출 내역을 추가/수정하는 페이지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. Report: 지출 분석 내역을 보는 페이지&lt;/span&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: start;&quot;&gt;각 화면은 아래 URL로 접근하기로 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. Home: `/`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. Add/Edit: `/add`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. Report: `/report`&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfevs4/btsKblNrj6S/KvkLVooua8Gu6Pss76GkKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfevs4/btsKblNrj6S/KvkLVooua8Gu6Pss76GkKk/img.png&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;394&quot; data-is-animation=&quot;false&quot; style=&quot;width: 33.2429%; margin-right: 10px;&quot; data-widthpercent=&quot;34.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfevs4/btsKblNrj6S/KvkLVooua8Gu6Pss76GkKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfevs4%2FbtsKblNrj6S%2FKvkLVooua8Gu6Pss76GkKk%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;418&quot; height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U3sJW/btsKdu2wdjF/aDdqT2HQsX5N43ar21ikjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U3sJW/btsKdu2wdjF/aDdqT2HQsX5N43ar21ikjk/img.png&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;494&quot; data-is-animation=&quot;false&quot; style=&quot;width: 31.7148%; margin-right: 10px;&quot; data-widthpercent=&quot;32.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U3sJW/btsKdu2wdjF/aDdqT2HQsX5N43ar21ikjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU3sJW%2FbtsKdu2wdjF%2FaDdqT2HQsX5N43ar21ikjk%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;500&quot; height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYlqPs/btsKdd7Jz6o/QXufS7Jh3PgkEdEsatnXZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYlqPs/btsKdd7Jz6o/QXufS7Jh3PgkEdEsatnXZ1/img.png&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;544&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.7166%;&quot; data-widthpercent=&quot;33.5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYlqPs/btsKdd7Jz6o/QXufS7Jh3PgkEdEsatnXZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYlqPs%2FbtsKdd7Jz6o%2FQXufS7Jh3PgkEdEsatnXZ1%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;568&quot; height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;1. Home 2. Add/Edit  3. Report&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;화면 전환은 &lt;b&gt;SPA(Single Page Application) 방식&lt;/b&gt;으로 &lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;진행합니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;SPA란?&lt;/b&gt;&lt;br /&gt;- 다른 페이지로 이동할 때마다 전체 페이지를 다시 로드하는 대신, 처음부터 하나의 HTML 페이지만 로드하는 방식.&lt;br /&gt;- 빠른 페이지 전환을 통해 부드러운 UX를 제공하며 데이터 로드에 최적화되어있음.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;먼저 Home에서 Add/Edit으로 화면을 이동해봅시다.&lt;/span&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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt; Next.js 로 화면 전환&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1729201725574&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Link from 'next/link';

export default function Home() {
  return (
    ...
    &amp;lt;Link href=&quot;/add&quot;&amp;gt;
      &amp;lt;a&amp;gt;Go to Add/Edit Page&amp;lt;/a&amp;gt;
    &amp;lt;/Link&amp;gt;
    ...
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js의 Link를 사용하면 간편하게 SPA 방식의 화면 전환이 가능해요.&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;JavaScript로 화면 전환&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1729203105660&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;a href=&quot;./add.html&quot;&amp;gt;Go To Add/Edit Page&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 JavaScript로 SPA 방식의 화면 전환을 한다면 아래와 같은 세팅이 필요합니다.&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. index.html 세팅&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729283292066&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
    &amp;lt;title&amp;gt;Expense Tracker&amp;lt;/title&amp;gt;
    &amp;lt;script src=&quot;https://cdn.tailwindcss.com&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;./css/style.css&quot; /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script type=&quot;module&quot; src=&quot;App.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;div&amp;gt;
      &amp;lt;!-- 1. Home --&amp;gt;
      &amp;lt;section id=&quot;homeSection&quot; class=&quot;section&quot;&amp;gt;
        &amp;lt;h2 class=&quot;text-2xl mb-4&quot;&amp;gt;1. Home&amp;lt;/h2&amp;gt;
        &amp;lt;br /&amp;gt;

        &amp;lt;a href=&quot;/add&quot;&amp;gt; &amp;lt;button&amp;gt;Go To Add/Edit Page&amp;lt;/button&amp;gt;&amp;lt;/a&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;a href=&quot;/report&quot;&amp;gt;Go To Report Page&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/section&amp;gt;

      &amp;lt;!-- 2. Add/Edit --&amp;gt;
      &amp;lt;section id=&quot;addSection&quot; style=&quot;display: none&quot; class=&quot;section&quot;&amp;gt;
        &amp;lt;h2 class=&quot;text-2xl mb-4&quot;&amp;gt;2. Add/Edit&amp;lt;/h2&amp;gt;
      &amp;lt;/section&amp;gt;

      &amp;lt;!-- 3. Report --&amp;gt;
      &amp;lt;section id=&quot;reportSection&quot; style=&quot;display: none&quot; class=&quot;section&quot;&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;h2 class=&quot;text-2xl mb-4&quot;&amp;gt;3. Report&amp;lt;/h2&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/section&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 `index.html`에 필요한 화면 기본 구조를 HTML로 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`id`가 `homeSection` / `addSection` / `reportSection` 인 부분 보이시죠!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 한곳에 모두 작성을 해두고, 화면 전환이 필요할 때마다 해당 section의 style을 `display: none;`에서 `display: block;`으로 변경해주어 페이지 전환이 이루어지도록 하는 것입니다.&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. App.js 세팅&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729284806198&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// route page
const routes = [
  {
    path: &quot;/&quot;,
    sectionId: &quot;homeSection&quot;,
  },
  {
    path: &quot;/add&quot;,
    sectionId: &quot;addSection&quot;,
  },
  {
    path: &quot;/report&quot;,
    sectionId: &quot;reportSection&quot;,
  },
];

// be global function by appending `window.`
window.navigate = (url) =&amp;gt; {
  window.history.pushState(null, null, url);
  App();
};

// render page by url &amp;amp; state is maintained without refreshing.
const App = async () =&amp;gt; {
  // hide all sections
  document.querySelectorAll(&quot;.section&quot;).forEach((section) =&amp;gt; {
    section.style.display = &quot;none&quot;;
  });

  // find page to show
  const pageMatches = routes.map((route) =&amp;gt; ({
    route: route,
    isMatch: window.location.pathname === route.path,
  }));
  const match = pageMatches.find((pageMatch) =&amp;gt; pageMatch.isMatch);
  if (match) {
    document.getElementById(match.route.sectionId).style.display = &quot;block&quot;;
  }
};

// Fired when the HTML is fully parsed and the DOM is completely built.
document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  // add click event listener tag &quot;&amp;lt;a&amp;gt;&quot;
  document.body.addEventListener(&quot;click&quot;, (e) =&amp;gt; {
    const target = e.target.closest(&quot;a&quot;);
    if (!(target instanceof HTMLAnchorElement)) return;

    e.preventDefault(); // prevent default page refresh
    navigate(target.href); // change url without refresh = SPA(Single Page Application)
  });

  App();
});

// Listen for 'popstate' events (triggered when the user navigates using the browser's back/forward buttons)
// This ensures the app correctly updates the view when the history state changes without a full page reload.
window.addEventListener(&quot;popstate&quot;, App);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 모든 코드가 화면 전환을 위한 작업 코드입니다 하핫.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하나하나 자세히 볼까요?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-1. routes&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729285629452&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const routes = [
  {
    path: &quot;/&quot;,
    sectionId: &quot;homeSection&quot;,
  },
  {
    path: &quot;/add&quot;,
    sectionId: &quot;addSection&quot;,
  },
  {
    path: &quot;/report&quot;,
    sectionId: &quot;reportSection&quot;,
  },
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 `routes`는, 해당 경로와 매칭되는 `sectionId`를 미리 정의한 배열이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`url`에 따라 html에서 미리 세팅해둔 `section`을 보여줄 때 사용됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-2. navigate&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729285770464&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;window.navigate = (url) =&amp;gt; {
  window.history.pushState(null, null, url);
  App();
};&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;`navigate`는 화면을 전환할 때 사용되는 함수에요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript의 `History API`를 사용하여, 페이지를 새로고침하지 않고도 브라우저의 URL을 변경하고 브라우저의 뒤로가기/앞으로가기 기능을 사용할 수 있어요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt; `window.`를 붙여준 이유는, navigate를 전역 함수로 사용하기 위함입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;App.js 파일은 `&amp;lt;script type=&quot;module&quot; scr=&quot;App.js&quot;&amp;gt;&amp;lt;/script&amp;gt;` 이렇게 import하면서 모듈스코프를 가진 파일이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;`window.`가 붙지 않는다면, navigate 함수는 모듈스코프(파일스코프) 내에 존재하기 때문에, `navigate` 함수가 사용되는 이벤트 핸들러에서는 참조가 불가능해요. 이벤트 핸들러에서 DOM 트리로부터 트리거된 함수는 전역스코프를 사용하기 때문이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;기껏 모듈스코프인 파일을 만들었는데 전역함수로 만드는 것은 좋지 않은 방법인 것 같지만, 일단은 SPA가 어떻게 동작하는지를 이해하기 위해 한 파일에 넣기로 하고 이어서 봅시다!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.webdevsimplified.com/2022-10/js-scoping/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;▷ 전역스코프와 모듈스코프(파일스코프)의 차이점 더 자세히 알아보기&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-3. App()&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729288753337&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// render page by url &amp;amp; state is maintained without refreshing.
const App = async () =&amp;gt; {
  // hide all sections
  document.querySelectorAll(&quot;.section&quot;).forEach((section) =&amp;gt; {
    section.style.display = &quot;none&quot;;
  });

  // find page to show
  const pageMatches = routes.map((route) =&amp;gt; ({
    route: route,
    isMatch: window.location.pathname === route.path,
  }));
  const match = pageMatches.find((pageMatch) =&amp;gt; pageMatch.isMatch);
  if (match) {
    document.getElementById(match.route.sectionId).style.display = &quot;block&quot;;
  }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;`App.js`에서는 `section` class를 가진 요소를 모두 `display: none;`으로 바꾼 뒤,&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현재 URL에 해당하는 요소만 다시 `display: block;`으로 바꿔주는 작업이 진행돼요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;2-4. click event listener&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729289345275&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Fired when the HTML is fully parsed and the DOM is completely built.
document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  // add click event listener tag &quot;&amp;lt;a&amp;gt;&quot;
  document.body.addEventListener(&quot;click&quot;, (e) =&amp;gt; {
    const target = e.target.closest(&quot;a&quot;);
    if (!(target instanceof HTMLAnchorElement)) return;

    e.preventDefault(); // prevent default page refresh
    navigate(target.href); // change url without refresh = SPA(Single Page Application)
  });

  App();
});&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;`DOMContentLoaded`는 브라우저에서 HTML의 구조가 완전히 로드되고 파싱되었을 때 발생하는 이벤트에요.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DOM 요소들이 준비가 되었으니 요소에 이벤트를 붙일 준비가 된 것이죠.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우리는 `&amp;lt;a&amp;gt;` 클릭으로 화면전환을 할 것이기 때문에, 이곳에 이벤트리스너를 등록해줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2-5. popstate event listener&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1729290228846&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Listen for 'popstate' events (triggered when the user navigates using the browser's back/forward buttons)
// This ensures the app correctly updates the view when the history state changes without a full page reload.
window.addEventListener(&quot;popstate&quot;, App);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로, 브라우저의 뒤로가기/앞으로가기 버튼을 눌렀을 때 앱의 상태를 업데이트하는데 사용되는 `popstate` 리스너 등록입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 이벤트가 발생할 때마다 `App()`함수가 호출되기 때문에, URL에 맞게 다시 렌더링/업데이트가 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;2-6. 정리&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;페이지로드가 완료되어 DOM요소가 준비되면 `&amp;lt;a&amp;gt;`태그에 직접 클릭이벤트를 등록하여, 클릭 시 페이지가 새로고침되지 않고 `navigate`함수가 동작되도록 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;`navigate`함수에서는 `history.pushState()`를 사용하여 url을 수정하고 `App`함수를 호출합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;App함수에서는 현재 url에 맞는 section만을 동적으로 렌더링합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt; 이렇게 JavaScript만으로 SPA 방식의 페이지 전환을  구현하였습니다!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ScreenRecording2024-10-18at4.26.45PM-ezgif.com-video-to-gif-converter.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPwe5I/btsKdpfUNoC/a7STK1snwpImaDAwnmeyu1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPwe5I/btsKdpfUNoC/a7STK1snwpImaDAwnmeyu1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPwe5I/btsKdpfUNoC/a7STK1snwpImaDAwnmeyu1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bPwe5I/btsKdpfUNoC/a7STK1snwpImaDAwnmeyu1/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;600&quot; height=&quot;375&quot; data-filename=&quot;ScreenRecording2024-10-18at4.26.45PM-ezgif.com-video-to-gif-converter.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Next.js와 같은 프레임워크를 사용한다면 전부 생략되었을 과정을 직접 작성해보니,&lt;/span&gt;&lt;span&gt;새로고침 없이 URL이 변경되면서 동적인 페이지 상태를 유지하는 &lt;b&gt;SPA&lt;/b&gt;의 원리를 알 수 있었습니다.&lt;/span&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;span&gt;직접 SPA를 구현하는 것이 실무에서는 드물겠지만, 단순히 프레임워크를 잘 활용하는 것보다 이것을 왜 쓰는지 이해하면서 활용할 줄 아는 것이 훨씬 중요합니다.&lt;/span&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;span&gt;오늘의 포스팅은 마치도록 하겠습니다. 감사합니다:)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;001&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/001.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/001.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;</description>
      <category>Solve Problem/Deep Dive</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/307</guid>
      <comments>https://coding-dahee.tistory.com/307#entry307comment</comments>
      <pubDate>Fri, 18 Oct 2024 06:50:50 +0900</pubDate>
    </item>
    <item>
      <title>WebP 적용하기</title>
      <link>https://coding-dahee.tistory.com/306</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React Native는 webp를 지원하지만 , 애니메이션이 있는 webp는 지원하지 않는다.&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;1. &lt;a href=&quot;https://github.com/Aleksefo/react-native-webp-format#installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;react-native-webp-format 설치&lt;/a&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. &lt;/b&gt;&lt;a href=&quot;https://github.com/Aleksefo/react-native-webp-format#android&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;Android 추가 설정&lt;/b&gt;&lt;/a&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;Add the following dependencies to&lt;span&gt;&amp;nbsp;&lt;/span&gt;android/app/build.gradle:&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;clean&quot; style=&quot;background-color: #000000; color: #000000;&quot;&gt;&lt;code&gt;dependencies {
  ...
    implementation 'com.facebook.fresco:webpsupport:2.5.0'
    // Optionally, to display animated WebP images, you have to add:
    implementation 'com.facebook.fresco:animated-webp:2.5.0'
  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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. &lt;/b&gt;&lt;a href=&quot;https://github.com/DylanVann/react-native-fast-image/issues/522#issuecomment-521928182&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;iOS 추가 설정&lt;/b&gt;&lt;/a&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;Go to your&lt;span&gt;&amp;nbsp;&lt;/span&gt;ios -&amp;gt; [App name folder] -&amp;gt; Edit AppDelegate.m&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;
&lt;pre class=&quot;objectivec&quot; style=&quot;background-color: #000000; color: #000000;&quot;&gt;&lt;code&gt;#import &quot;SDImageCodersManager.h&quot;
#import &amp;lt;SDWebImageWebPCoder/SDImageWebPCoder.h&amp;gt;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // . . .

    [SDImageCodersManager.sharedManager addCoder:SDImageWebPCoder.sharedCoder];

    // . . .
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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;잘 띄워진다 유후!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/442025611&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/coDH5E/hyUkkJQi0s/GjRjyjmxkJVuNdXSflT0cK/img.jpg?width=500&amp;amp;height=574&amp;amp;face=0_0_500_574,https://scrap.kakaocdn.net/dn/jcZBV/hyUlvYAgyB/ERtYYYKeRuLK9JJV5FzKjk/img.jpg?width=500&amp;amp;height=574&amp;amp;face=0_0_500_574&quot; data-video-width=&quot;500&quot; data-video-height=&quot;574&quot; data-video-origin-width=&quot;500&quot; data-video-origin-height=&quot;574&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;'코딩을 보라'에서 업로드한 동영상&quot; data-video-play-service=&quot;daum_tistory&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/442025611?service=daum_tistory&quot; width=&quot;500&quot; height=&quot;574&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/React Native</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/306</guid>
      <comments>https://coding-dahee.tistory.com/306#entry306comment</comments>
      <pubDate>Fri, 27 Oct 2023 18:38:09 +0900</pubDate>
    </item>
    <item>
      <title>React Native Flipper 사용 시, Android 에뮬레이터 인식하지 못할 때</title>
      <link>https://coding-dahee.tistory.com/305</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #232629; text-align: left;&quot;&gt;Android SDK location path를 알맞게 변경해주면 된다.&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;2034&quot; data-origin-height=&quot;1588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYwptt/btstRuGftbF/RR6Fwl2vwXFO3f3edU3J61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYwptt/btstRuGftbF/RR6Fwl2vwXFO3f3edU3J61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYwptt/btstRuGftbF/RR6Fwl2vwXFO3f3edU3J61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYwptt%2FbtstRuGftbF%2FRR6Fwl2vwXFO3f3edU3J61%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;2034&quot; height=&quot;1588&quot; data-origin-width=&quot;2034&quot; data-origin-height=&quot;1588&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;검색 키워드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react native flipper not recognize android emulator&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;출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694660303312&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;Android Emulator unable to connect to Flipper&quot; data-og-description=&quot;I followed the instructions here https://fbflipper.com/docs/getting-started/android-native/#diagnostics. I added the 3 dependencies in build.gradle, and added the application class with the same&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&quot; data-og-url=&quot;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/A9IAn/hyTSyP589T/KVmnCptJIlcvPZhwoBZg21/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/b4h0wV/hyTVOwX6Wp/gA2Luc0IRBTtQv2zUmjTz0/img.png?width=1138&amp;amp;height=304&amp;amp;face=0_0_1138_304,https://scrap.kakaocdn.net/dn/eEX1J/hyTSB0lQ6b/VnYTWRpaKKQ68ZcaLVhqC1/img.png?width=548&amp;amp;height=470&amp;amp;face=0_0_548_470&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/A9IAn/hyTSyP589T/KVmnCptJIlcvPZhwoBZg21/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/b4h0wV/hyTVOwX6Wp/gA2Luc0IRBTtQv2zUmjTz0/img.png?width=1138&amp;amp;height=304&amp;amp;face=0_0_1138_304,https://scrap.kakaocdn.net/dn/eEX1J/hyTSB0lQ6b/VnYTWRpaKKQ68ZcaLVhqC1/img.png?width=548&amp;amp;height=470&amp;amp;face=0_0_548_470');&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;Android Emulator unable to connect to Flipper&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I followed the instructions here https://fbflipper.com/docs/getting-started/android-native/#diagnostics. I added the 3 dependencies in build.gradle, and added the application class with the same&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/Troubleshooting</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/305</guid>
      <comments>https://coding-dahee.tistory.com/305#entry305comment</comments>
      <pubDate>Thu, 14 Sep 2023 11:59:25 +0900</pubDate>
    </item>
    <item>
      <title>React Native에서 설정된 언어를 Next.js에 전달하기</title>
      <link>https://coding-dahee.tistory.com/302</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native에서 Next.js로 웹뷰 이동을 할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native에 미리 세팅된 언어를 Next.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) localStorage에 저장해서 클라이언트 렌더링 때 context 등의 전역변수로 관리한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라이언트 렌더링 할 때서야 언어를 감지하므로 UX 상 좋지 않다.&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) Next.js는 서버사이드 렌더링이기 때문에 서버에서 미리 유저의 언어를 알아낸다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이거다! HTTP Aceept-Language 헤더에 기반해 사용자의 local을 감지하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690882562431&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// RN 코드

import WebView from &quot;react-native-webview&quot;;

&amp;lt;WebView
    ...
    source={{
      uri: &quot;이동할 URL&quot;,
      headers: {
        'Accept-Language': `${사용자 언어}`, // ex) &quot;ko&quot;, &quot;en&quot;
      },
    }}
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1690882712144&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// next.js 코드
// next-18next.config.js

/** @type {import('next-i18next').UserConfig} */
module.exports = {
  i18n: {
    defaultLocale: &quot;en&quot;,
    locales: [&quot;en&quot;, &quot;ko&quot;, &quot;es&quot;], // 영어, 한국어, 스페인어 지원
    localeDetection: true, // 디폴트 값. 이것이 true여야 'Accept-Language'에 있는 locale을 감지한다.
  },
};&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;이것이 SSR이로구나      &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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jeonbyeongmin/Next.js%EB%A1%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4i18n-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@jeonbyeongmin/Next.js%EB%A1%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4i18n-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690882369420&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Next.js로 다국어(i18n) 제공하기&quot; data-og-description=&quot;Next.js로 다국어를 적용하면서 공부하고 고민했던 흔적들에 대해서 설명합니다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@jeonbyeongmin/Next.js%EB%A1%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4i18n-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@jeonbyeongmin/Next.js로-다국어i18n-제공하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Qc4EO/hyTvd6aAS6/lYAKJGYhDmnrhKq3IwCKcK/img.png?width=1214&amp;amp;height=696&amp;amp;face=0_0_1214_696,https://scrap.kakaocdn.net/dn/bX459y/hyTvlJSy8y/aGaToYJ8xnF0sdxlyQyi90/img.png?width=1214&amp;amp;height=696&amp;amp;face=0_0_1214_696,https://scrap.kakaocdn.net/dn/ctryY4/hyTwdjaiRV/GBaGwtOjIPmMv8w0vNB31k/img.jpg?width=3024&amp;amp;height=4032&amp;amp;face=926_1883_1940_2298&quot;&gt;&lt;a href=&quot;https://velog.io/@jeonbyeongmin/Next.js%EB%A1%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4i18n-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@jeonbyeongmin/Next.js%EB%A1%9C-%EB%8B%A4%EA%B5%AD%EC%96%B4i18n-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Qc4EO/hyTvd6aAS6/lYAKJGYhDmnrhKq3IwCKcK/img.png?width=1214&amp;amp;height=696&amp;amp;face=0_0_1214_696,https://scrap.kakaocdn.net/dn/bX459y/hyTvlJSy8y/aGaToYJ8xnF0sdxlyQyi90/img.png?width=1214&amp;amp;height=696&amp;amp;face=0_0_1214_696,https://scrap.kakaocdn.net/dn/ctryY4/hyTwdjaiRV/GBaGwtOjIPmMv8w0vNB31k/img.jpg?width=3024&amp;amp;height=4032&amp;amp;face=926_1883_1940_2298');&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;Next.js로 다국어(i18n) 제공하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Next.js로 다국어를 적용하면서 공부하고 고민했던 흔적들에 대해서 설명합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jake-seo-dev.tistory.com/483&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jake-seo-dev.tistory.com/483&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690882364874&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;HTTP 헤더란? (Http headers)&quot; data-og-description=&quot;HTTP 헤더란? HTTP 통신의 핵심이 되는 중요한 컴포넌트 중 하나이다. 요청 혹은 응답의 필수 구성요소이다. 클라이언트와 서버 간의 메세지 전송 및 해석을 돕기 위해 메타데이터와 추가 정보를 &quot; data-og-host=&quot;jake-seo-dev.tistory.com&quot; data-og-source-url=&quot;https://jake-seo-dev.tistory.com/483&quot; data-og-url=&quot;https://jake-seo-dev.tistory.com/483&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mFit2/hyTvkRJFAt/9KEKNjRtQ7hdhjiDohFUlK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/QLOac/hyTwoLK5Kl/W2NGklIpxqD58qA2jG8eq0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://jake-seo-dev.tistory.com/483&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jake-seo-dev.tistory.com/483&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mFit2/hyTvkRJFAt/9KEKNjRtQ7hdhjiDohFUlK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/QLOac/hyTwoLK5Kl/W2NGklIpxqD58qA2jG8eq0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;HTTP 헤더란? (Http headers)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTTP 헤더란? HTTP 통신의 핵심이 되는 중요한 컴포넌트 중 하나이다. 요청 혹은 응답의 필수 구성요소이다. 클라이언트와 서버 간의 메세지 전송 및 해석을 돕기 위해 메타데이터와 추가 정보를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jake-seo-dev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/pages/building-your-application/routing/internationalization&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/pages/building-your-application/routing/internationalization&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/React Native</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/302</guid>
      <comments>https://coding-dahee.tistory.com/302#entry302comment</comments>
      <pubDate>Tue, 1 Aug 2023 18:39:28 +0900</pubDate>
    </item>
    <item>
      <title>인프런 &amp;lt;AWS 입문자를 위한 강의&amp;gt; 강의메모</title>
      <link>https://coding-dahee.tistory.com/301</link>
      <description>&lt;figure id=&quot;og_1690628460868&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;AWS(Amazon Web Service) 입문자를 위한 강의 - 인프런 | 강의&quot; data-og-description=&quot;요즈음 회사 및 다양한 프로젝트에서 종종 사용되는 AWS 서비스들의 핵심 이론을 배우며 뿐만 아니라 함께 따라하는 실습을 통하여 AWS를 온전히 내것으로 만들자!, [사진] AWS 핵심 기술, 기본기부&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/aws-%EC%9E%85%EB%AC%B8&quot; data-og-url=&quot;https://www.inflearn.com/course/aws-%EC%9E%85%EB%AC%B8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bN0Kcn/hyTtuzcUzD/IbpgGATlXC1mrIqhSithK0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fwBMy/hyTtnfMx6G/SGoRHwkh31qhl4c27ewrS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/ct1JSa/hyTtuMKeWD/2v9bXrAVY37d4pNErP9EKk/img.png?width=638&amp;amp;height=433&amp;amp;face=0_0_638_433&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/aws-%EC%9E%85%EB%AC%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/aws-%EC%9E%85%EB%AC%B8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bN0Kcn/hyTtuzcUzD/IbpgGATlXC1mrIqhSithK0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fwBMy/hyTtnfMx6G/SGoRHwkh31qhl4c27ewrS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/ct1JSa/hyTtuMKeWD/2v9bXrAVY37d4pNErP9EKk/img.png?width=638&amp;amp;height=433&amp;amp;face=0_0_638_433');&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;AWS(Amazon Web Service) 입문자를 위한 강의 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;요즈음 회사 및 다양한 프로젝트에서 종종 사용되는 AWS 서비스들의 핵심 이론을 배우며 뿐만 아니라 함께 따라하는 실습을 통하여 AWS를 온전히 내것으로 만들자!, [사진] AWS 핵심 기술, 기본기부&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;EBS: Elastic Block Storage&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 저장 공간이 생성되며, EC2 인스턴스에 부착된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 디스크 볼륨 위에 File System이 생성된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- EBS는 특정 Availability Zone에 생성된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;EBS 볼륨 타입&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;lt;&amp;lt;SSD군&amp;gt;&amp;gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;1) General Purpose SSD (GP2)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;2) Provisioned IOPS SSD (IO1)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;lt;&amp;lt;Magnetic/HDD군&amp;gt;&amp;gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;3) Throughput Optimizaed HDD (ST1)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;4) CDD HDD (SC1)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;5) Magnetic (Sandard)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;ELB: Elastic Load Balancers&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 수많은 서버의 흐름을 균형있게 흘려보내는데 중추적인 역할을 함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 하나의 서버로 traffic이 몰리는 병목현상(bottleneck) 방지&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Traffic의 흐름을 Unhealty instance -&amp;gt; healthy instance로&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;1. Application Load Balancer: OSI Layer7에서 작동됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;-&amp;gt; HTTP, HTTPS와 같은 traffic의 load balancing에 가장 적합&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;-&amp;gt; 고급 request 라우팅 설정을 통하여 특정 서버로 request를 보낼 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;2. Network Load Balancer: OSI Layer4에서 작동됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;-&amp;gt; 매우 빠른 속도를 자랑하며 Production 환경에서 종종 쓰임&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;-&amp;gt; 극도의 performance가 요구되는 TCP traffic에서 적합&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;-&amp;gt; 초당 수백만개의 request를 아주 미세한 delay로 처리 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;3. Classic Load Balancer: 현재 Legacy&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;---&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;Load Balancer Error: 504 Error&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgFW5N/btspk87PnvN/fYr4gzOFGkU3kKdAN1VhYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgFW5N/btspk87PnvN/fYr4gzOFGkU3kKdAN1VhYk/img.png&quot; data-alt=&quot;T.T&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgFW5N/btspk87PnvN/fYr4gzOFGkU3kKdAN1VhYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgFW5N%2Fbtspk87PnvN%2FfYr4gzOFGkU3kKdAN1VhYk%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;336&quot; height=&quot;118&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;118&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;T.T&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;웹서버,데이터베이스 Layer에서 대부분 해결 가능.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;X-Forwarded-For 헤더&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Cloud Watch&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- AWS 리소스 사용의 실시간 모니터링 기능 지원&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 다양한 이벤트들을 수집하여 로그파일로 저장&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 이벤트&amp;amp;알람 설정을 통해 SNS, AWS Lambda로 전송 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;사용 용례 1&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Use Case: 매일 얼마나 많은 사용자들이 모바일 앱을 사용하는지 알고 싶음.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Potential Issue: 특정날에 수많은 traffic이 몰릴 수 있어 병목현상이 생길 수 있음.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Solution: 매일 traffic rate와 특정 버튼의 유저 클릭 횟수를 분석하여 더 효율적인 앱개발 가능.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;사용 용례 2&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Use Case: 특정 시간대에 웹서버 상태를 점검하여 비용 절감 목표&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Potential Issue: 낮,밤에 따라 다른 서버의 성능 -&amp;gt; 똑같은 비용을 내면 비효율.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- Solution: 알람 설정을 통해 특정 threshold에 도달했을 때, 상황 보고해줌으로서 서버 management 가능.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;</description>
      <category>Study/AWS</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/301</guid>
      <comments>https://coding-dahee.tistory.com/301#entry301comment</comments>
      <pubDate>Sat, 29 Jul 2023 20:05:31 +0900</pubDate>
    </item>
    <item>
      <title>Next i18n 적용하기</title>
      <link>https://coding-dahee.tistory.com/300</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/package/next-i18next&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.npmjs.com/package/next-i18next&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690445705741&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;next-i18next&quot; data-og-description=&quot;The easiest way to translate your NextJs apps.. Latest version: 14.0.0, last published: a month ago. Start using next-i18next in your project by running &amp;#96;npm i next-i18next&amp;#96;. There are 125 other projects in the npm registry using next-i18next.&quot; data-og-host=&quot;www.npmjs.com&quot; data-og-source-url=&quot;https://www.npmjs.com/package/next-i18next&quot; data-og-url=&quot;https://www.npmjs.com/package/next-i18next&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/MzDjw/hyTrNeGHwS/U0lsJXOiUl92c0ls9MZpe1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dt2xwF/hyTrP4CXSO/QhsBVSLeZ0Zk1WzKmkYeO1/img.jpg?width=1920&amp;amp;height=783&amp;amp;face=0_0_1920_783,https://scrap.kakaocdn.net/dn/b73Woq/hyTrQCsm7D/AmEOcTXgZCQNDZ3Anho000/img.jpg?width=1040&amp;amp;height=489&amp;amp;face=0_0_1040_489&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/package/next-i18next&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.npmjs.com/package/next-i18next&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/MzDjw/hyTrNeGHwS/U0lsJXOiUl92c0ls9MZpe1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/dt2xwF/hyTrP4CXSO/QhsBVSLeZ0Zk1WzKmkYeO1/img.jpg?width=1920&amp;amp;height=783&amp;amp;face=0_0_1920_783,https://scrap.kakaocdn.net/dn/b73Woq/hyTrQCsm7D/AmEOcTXgZCQNDZ3Anho000/img.jpg?width=1040&amp;amp;height=489&amp;amp;face=0_0_1040_489');&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;next-i18next&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The easiest way to translate your NextJs apps.. Latest version: 14.0.0, last published: a month ago. Start using next-i18next in your project by running `npm i next-i18next`. There are 125 other projects in the npm registry using next-i18next.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.npmjs.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;주의할 점은, 페이지 level에서 getStaticProps를 추가하면, 해당 파일에서는 useTranslation을 사용하지 못한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. useTranslation을 매 파일마다 import해서 쓰기 귀찮으니까, custom hook을 하나 만들어줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690445826148&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// use-t.ts
import { useTranslation } from &quot;next-i18next&quot;;

export const useT = () =&amp;gt; {
  const result = useTranslation(&quot;common&quot;);

  return {
    ...result,
  };
};

// usage
export default function Category(props) {
  const { t } = useT();

  return (
      ...
      &amp;lt;Typography.P14_Bold
        content={t(&quot;loot_box&quot;)}
        color={...}
      /&amp;gt;
      ...
	
  )
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Solve Problem/Guide | Tip</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/300</guid>
      <comments>https://coding-dahee.tistory.com/300#entry300comment</comments>
      <pubDate>Thu, 27 Jul 2023 17:18:25 +0900</pubDate>
    </item>
    <item>
      <title>인프런 &amp;lt;스타트업과 함께하는 AWS 클라우드&amp;gt; 강의기록</title>
      <link>https://coding-dahee.tistory.com/298</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅섹션 0: 클라우드를 사용해야 하는 이유&lt;/b&gt;&lt;/h3&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;Security Group&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;&amp;lt;보안그룹 만들기&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSH&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTPS&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;인스턴스 내부로 접근하려면?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- connect&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅섹션 1: 로드밸런서 사용해보기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;ELB 설명&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 가용영역&lt;/b&gt;(Availabilty Zone): 데이터센터.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 리전&lt;/b&gt;(Region): 3개 이상의 가용역역을 논리적으로 묶음.&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;- 로드밸런서는 가용영역을 최소 2개 이상 선택해야하는 이유: 한 가용영역이 문제가 생겨도, 다른 한쪽으로 버틸 수 있기 때문.&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;&amp;lt;로드밸런서 만들기&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우선 HTTP, HTTPS rule 포함한 SecurityGroup 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 로드밸런서 만들기 전, TargetGroup 만들기. 로드밸런서가 부하를 분산해주는건데, 아무 인스턴스에게 부하를 분산해주면 안되니까!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 정해진 인스턴스에게 분산해주기 위해 그룹핑한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이제 로드밸런서를 만들자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷을 통해 트래픽을 받아서 전달하기 때문에, internet-facing 체크.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크가 중요한 부분.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서울리전은 가용영역이 4개.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 2개! 데이터센터를 2개 쓰겠다는 이야기야. (하나 붕괴되어 마비되는 것 방지)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IxGXW/btso7h5HgBc/Dum5vkyDK55YE15VCalol0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IxGXW/btso7h5HgBc/Dum5vkyDK55YE15VCalol0/img.png&quot; data-alt=&quot;내가 만든 Target Group에 라우팅 시켜주겠다!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IxGXW/btso7h5HgBc/Dum5vkyDK55YE15VCalol0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIxGXW%2Fbtso7h5HgBc%2FDum5vkyDK55YE15VCalol0%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;604&quot; height=&quot;305&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;내가 만든 Target Group에 라우팅 시켜주겠다!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Provisining: 할당. 장비를 공급받는중.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 아직, 지정한 TargetGroup에 인스턴스가 없어서, LB에 접근해봤자 의미 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅섹션 2: 오토스케일링 사용해보기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ELB가 부하 분산하는 건 알겠는데, 필요한 건 자동으로 서버가 늘어나는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AutoScaling을 해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보통 CPU 사용률을 기준으로 자동으로 늘어나고 줄어든다.&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;- Lucky Instance의 이미지가 하나 필요하다. Action에서 Create Image&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Images - AMIs 들어가면 만든 이미지가 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;- 이 때 템플릿을 만들어. EC2 launch templates. 어떤 인스턴스,운영체제,이미지 를 설정하는거야.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버전이 계속 올라간다. 처음은 1로 세팅하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HTTP, HTTPS, SSH 있는 Security Group 선택.&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;- 만든 Launch Template을 가지고, Auto Scaling을 만들거야.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC는 아직 배우지 않았으니 패스.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가용영역은 전과 같이 a,b 똑같이 선택해야함!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;- 부하가 많이 없어도 테스트 가능하도록, 일단 CPU 점유율의 Target Value는 20으로 잡는다.&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;- 만든 로드밸런서의 주소로 가보자. 잘 뜬다.&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;- 타겟그룹에서 대상을 제외해야해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 왜 인스턴스를 직접 지우면 안되냐? 실제 사용자 중 지울 인스턴스를 쓰고있는 유저가 있을 수도 있으니까.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO0S6y/btspk8NbFBh/kkIDq4smIF648odtri7DfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO0S6y/btspk8NbFBh/kkIDq4smIF648odtri7DfK/img.png&quot; data-alt=&quot;빠른 테스트를 위해, 시간을 300s -&amp;amp;gt; 20s 로 바꾸자. 원래는 5분이라 조금 기다리는게 맞다~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO0S6y/btspk8NbFBh/kkIDq4smIF648odtri7DfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO0S6y%2Fbtspk8NbFBh%2FkkIDq4smIF648odtri7DfK%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;642&quot; height=&quot;397&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;빠른 테스트를 위해, 시간을 300s -&amp;gt; 20s 로 바꾸자. 원래는 5분이라 조금 기다리는게 맞다~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;draining이 완료되면, 이제 인스턴스에서 직접 삭제할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 로드밸런서에서는 최소 2개여야 하기에, 자동으로 늘어나는지를 보면돼.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1093&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvQQRB/btspjWsFgCZ/TrJnZ6rk5zwk7nFYWOuJt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvQQRB/btspjWsFgCZ/TrJnZ6rk5zwk7nFYWOuJt1/img.png&quot; data-alt=&quot;하나가 자동으로 만들어지고 있다!!!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvQQRB/btspjWsFgCZ/TrJnZ6rk5zwk7nFYWOuJt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvQQRB%2FbtspjWsFgCZ%2FTrJnZ6rk5zwk7nFYWOuJt1%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;699&quot; height=&quot;174&quot; data-origin-width=&quot;1093&quot; data-origin-height=&quot;272&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;p data-ke-size=&quot;size16&quot;&gt;이제 다시 2개가 되었으니, 과부하를 걸어서 분산이 잘되는지를 볼까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부로 직접 들어가서 CPU 과부하를 걸어버릴 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;script실행해서 반복문을 계속 돌려볼거야!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 점유율 모니터링하고, 인스턴스 늘어나는 것을 볼 수 있음.&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;로드밸런서, 타겟그룹, 오토스케일링, AMI(deregister), AMI Snapshot, Launch Template, Security Group&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; 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;RDS: Relational Database Service&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MariaDB로 만들어보자.&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;- 인스턴스와 달리, DB는 오토스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그래서 DB는 민감하게 모니터링해야해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용량이 올라가면 scale up 등의 조치를 취해야 해.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅섹션 4: 도메인 연결하기, 도메인 HTTPS 인증하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅섹션 5: AWS의 네트워크를 이해해보기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC: AWS에서 나만의 사설 네트워크를 만들어주는 서비스.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VPC: 집에 있는 IP 공유기와 비슷해.&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;- VPC에서 쪼개진 영역을 subnet이라 하고, public과 private있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보안상, default VPC 사용은 권하지 않음.&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;CIDR&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IP주소를 관리하는 체계.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 10.0.0.0/16 이면 16이 prefix.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- {prefix}번째 숫자까지 고정하겠다는 이야기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 10.0.0.0 을 2진수로 나타내면, &lt;span style=&quot;color: #ee2323;&quot;&gt;00001010&lt;b&gt;.&lt;/b&gt;00000000&lt;/span&gt;&lt;b&gt;.&lt;/b&gt;00000000&lt;b&gt;.&lt;/b&gt;00000000 인데 여기서 앞에 16번째까지는 고정이고 나머지는 가변적이야.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그러면 2^8 * 2^8 = 2^16 개의 private ip를 사용할 수 있는 것.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OffLm/btspoldIPDF/vtkkYUr2k9miDLzyWvjLz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OffLm/btspoldIPDF/vtkkYUr2k9miDLzyWvjLz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OffLm/btspoldIPDF/vtkkYUr2k9miDLzyWvjLz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOffLm%2FbtspoldIPDF%2FvtkkYUr2k9miDLzyWvjLz1%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;1052&quot; height=&quot;399&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;399&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Internet Gateway&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 위에서 만든 Public Subnet이, 그냥 만든다고 해서 외부에서 접근 가능한게 아니라, Internet gateway를 붙이고 Route Table 설정을 해야해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하나 만들고 VPC에 달면 돼.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 게이트웨이 만들고, 인스턴스에 pulic ip가 할당되어 있어야 하고, route table을 설정해줘야 해.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bStX9H/btspl7Aq39f/BK9kxzY17btbq0LxxyxHP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bStX9H/btspl7Aq39f/BK9kxzY17btbq0LxxyxHP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bStX9H/btspl7Aq39f/BK9kxzY17btbq0LxxyxHP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbStX9H%2Fbtspl7Aq39f%2FBK9kxzY17btbq0LxxyxHP0%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;1084&quot; height=&quot;410&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRXGay/btspnjAnfuU/JyvJMKvNPI2Scj7GWzWatk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRXGay/btspnjAnfuU/JyvJMKvNPI2Scj7GWzWatk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRXGay/btspnjAnfuU/JyvJMKvNPI2Scj7GWzWatk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRXGay%2FbtspnjAnfuU%2FJyvJMKvNPI2Scj7GWzWatk%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;1081&quot; height=&quot;604&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;603&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Fd0I/btsph9supMJ/Dox3LOe3PjdsOO385zRJh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Fd0I/btsph9supMJ/Dox3LOe3PjdsOO385zRJh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Fd0I/btsph9supMJ/Dox3LOe3PjdsOO385zRJh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Fd0I%2Fbtsph9supMJ%2FDox3LOe3PjdsOO385zRJh1%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;1070&quot; height=&quot;603&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;603&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;p data-ke-size=&quot;size16&quot;&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;VPC 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Create VPC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Create Subnet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 가용영역 a: Public 1, 10.0.0.0/24&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;가용영역 a - Private 1,&lt;span&gt;&amp;nbsp;&lt;/span&gt;10.0.1.0/24&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 가용영역 b: Public 2, 10.0.2.0/24&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;가용영역 b: Private 2,&lt;span&gt;&amp;nbsp;&lt;/span&gt;10.0.3.0/24&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;이제 Public Subnet을 외부에서 접근 가능하도록 Interent Gateway를 열어줄거야.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들고 VPC 연결해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, Route Table을 만들어서, Public Subnet들이 Internet Gateway를 통해 인터넷이 되도록 설정까지 해줘야 해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 VPC를 만들면 Route Table이 하나 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Public Route Table 하나, Private Route Table 하나 만들 것이다.&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;Public RT - Routes - Edit routes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷을 통해 들어오는 트래픽을 처리하고, 다시 나가야 하는데, 이걸 설정해줄거야.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kZ8tk/btspkJ1qbKi/RRtgfBpBL4BdhrSPMkuYV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kZ8tk/btspkJ1qbKi/RRtgfBpBL4BdhrSPMkuYV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kZ8tk/btspkJ1qbKi/RRtgfBpBL4BdhrSPMkuYV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkZ8tk%2FbtspkJ1qbKi%2FRRtgfBpBL4BdhrSPMkuYV0%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;542&quot; height=&quot;389&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 0.0.0.0/0 은 모든 IP를 의미하는데, 모든 IP를 IG로 가게하면, 내부에서 돌아야 하는 패킷도 IG로 가는거야.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 근데 라우팅 테이블은 적용 우선순위가 있어. &lt;b&gt;Longest Prefix Match:&lt;/b&gt; Prefix 숫자가 클수록 네트워크 범위가 작기 때문에, 작은 것부터 적용됨. 그래서 내부에서 돌아야하는 것 빼고는 전부 IG로 간다~&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;이제 Private Subnet에서도 인터넷이 가능하도록 NAT Gateway를 만들거야~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NAT Gateway는, IP 공유기와 똑같은 역할을 해서, 고정 IP가 있어야 해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NAT Gateway를 Public Subnet 1번,2번에 만들자. 다른 가용영역에 고장나도 다른 곳에서 사용 가능하게.&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;Route Table을 만들어서 Private Subnet의 인스턴스들이 NAT를 통해 인터넷을 할 수 있도록 설정해야해.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0BAFs/btspnj1u3hs/Gmb7nlk4FNodNFSNV4u7V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0BAFs/btspnj1u3hs/Gmb7nlk4FNodNFSNV4u7V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0BAFs/btspnj1u3hs/Gmb7nlk4FNodNFSNV4u7V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0BAFs%2Fbtspnj1u3hs%2FGmb7nlk4FNodNFSNV4u7V0%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;622&quot; height=&quot;475&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690628820632&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;자습서: 조정 및 로드 밸런싱된 애플리케이션 설정 - Amazon EC2 Auto Scaling&quot; data-og-description=&quot;인스턴스에 연결해야 하는 경우 Proceed without a key pair(키 페어 없이 계속)를 선택하지 마세요.&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cjCcfn/hyTttAkJkF/bb6nKac0ImLPqMsSGdeIOk/img.png?width=610&amp;amp;height=463&amp;amp;face=0_0_610_463&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cjCcfn/hyTttAkJkF/bb6nKac0ImLPqMsSGdeIOk/img.png?width=610&amp;amp;height=463&amp;amp;face=0_0_610_463');&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;자습서: 조정 및 로드 밸런싱된 애플리케이션 설정 - Amazon EC2 Auto Scaling&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;인스턴스에 연결해야 하는 경우 Proceed without a key pair(키 페어 없이 계속)를 선택하지 마세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;- NAT gateway, Elastic IP, VPC 지우기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chQxuq/btsplaEzTXx/ch2cAMZGfcL5kvxgyUvkq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chQxuq/btsplaEzTXx/ch2cAMZGfcL5kvxgyUvkq1/img.png&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;598&quot; data-is-animation=&quot;false&quot; style=&quot;width: 46.4146%; margin-right: 10px;&quot; data-widthpercent=&quot;46.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chQxuq/btsplaEzTXx/ch2cAMZGfcL5kvxgyUvkq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchQxuq%2FbtsplaEzTXx%2Fch2cAMZGfcL5kvxgyUvkq1%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;738&quot; height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z6fy7/btsplphA0ut/DHrvRkrpNkQNipQunphJ9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z6fy7/btsplphA0ut/DHrvRkrpNkQNipQunphJ9K/img.png&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;782&quot; data-is-animation=&quot;false&quot; width=&quot;551&quot; height=&quot;395&quot; data-widthpercent=&quot;53.04&quot; style=&quot;width: 52.4226%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z6fy7/btsplphA0ut/DHrvRkrpNkQNipQunphJ9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ6fy7%2FbtsplphA0ut%2FDHrvRkrpNkQNipQunphJ9K%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;1090&quot; height=&quot;782&quot;/&gt;&lt;/span&gt;&lt;/div&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 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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lt;질문창고&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 로드밸런서: 하나의 인스턴스에 대해서도 필요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 서버를 만들면, 인스턴스, 로드밸런서, 오토스케일링, RDS, VPC 모든걸 세팅해줘야 하는 것?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/AWS</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/298</guid>
      <comments>https://coding-dahee.tistory.com/298#entry298comment</comments>
      <pubDate>Thu, 27 Jul 2023 14:54:59 +0900</pubDate>
    </item>
    <item>
      <title>Next 폴더 구조에 대한 고민: 관심분리</title>
      <link>https://coding-dahee.tistory.com/297</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 react native 프로젝트 구조는,&lt;/p&gt;
&lt;pre id=&quot;code_1690305026753&quot; class=&quot;xquery&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;├── apollo
├── assets
│   ├── gf-asset
│   │   ├── collection
│   │   ├── roubisy
│   │   └── themes
│   ├── icons
│   ├── image
├── c_components
│   ├── analysis_stack
│   ├── atom
│   │   ├── icon
│   │   └── text
│   ├── home_stack
│   ├── molecules
│   ├── my_roubit_stack
│   ├── on_alarm_stack
│   ├── onboarding_stack
│   ├── organisms
│   ├── presenter
│   ├── setting_stack
│   ├── template
│   └── universal
├── c_containers
│   ├── analysis_stack
│   ├── home_stack
│   ├── my_roubit_stack
│   ├── on_alarm_stack
│   ├── onboarding_stack
│   ├── setting_stack
│   └── universal
├── c_screens
│   ├── analysis_stack
│   ├── home_stack
│   ├── my_roubit_stack
│   ├── on_alarm_stack
│   ├── onboarding_stack
│   ├── root_tab_stack
│   ├── setting_stack
│   └── universal
├── constants
├── context
├── hook
├── lang
├── navigation
├── recoils
├── types
└── utils&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 screen,container,component로 대분류하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(`c_`를 붙인 이유는 screen,container,components 폴더를 모아서 보려고! prefix를 단 것이다.)&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;stack 별로 폴더를 구성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 container에서 사용되는 hook은 전부 root에 있는 hook에 넣었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하니까 어떤 hook이 어디에서 관리되고, 어떤 hook이 글로벌하게 쓰이고 있는지 파악이 안되었다.&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;이곳은 폴더관리를 어떻게 해야하나 고민하던 중 아래 글을 보게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690305333531&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;How to Structure Your Next.js App With the New App Router&quot; data-og-description=&quot;Learn how to organize your Next.js project using a feature-driven structure with the new App Router, allowing for greater flexibility and&amp;hellip;&quot; data-og-host=&quot;betterprogramming.pub&quot; data-og-source-url=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot; data-og-url=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btMEG3/hyTqpelzAh/o0qAbKkfUHUd84I4uYKMSk/img.png?width=843&amp;amp;height=441&amp;amp;face=0_0_843_441,https://scrap.kakaocdn.net/dn/mbd8T/hyTqEbve9j/WfMhGBSjwhQy5EJSzpagJ1/img.png?width=1216&amp;amp;height=832&amp;amp;face=0_0_1216_832,https://scrap.kakaocdn.net/dn/cuTWNV/hyTqutdbsl/NAelPb6kbD9ELxSF0uLYok/img.png?width=1012&amp;amp;height=484&amp;amp;face=0_0_1012_484&quot;&gt;&lt;a href=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btMEG3/hyTqpelzAh/o0qAbKkfUHUd84I4uYKMSk/img.png?width=843&amp;amp;height=441&amp;amp;face=0_0_843_441,https://scrap.kakaocdn.net/dn/mbd8T/hyTqEbve9j/WfMhGBSjwhQy5EJSzpagJ1/img.png?width=1216&amp;amp;height=832&amp;amp;face=0_0_1216_832,https://scrap.kakaocdn.net/dn/cuTWNV/hyTqutdbsl/NAelPb6kbD9ELxSF0uLYok/img.png?width=1012&amp;amp;height=484&amp;amp;face=0_0_1012_484');&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;How to Structure Your Next.js App With the New App Router&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn how to organize your Next.js project using a feature-driven structure with the new App Router, allowing for greater flexibility and&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;betterprogramming.pub&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;한 페이지를 구성할 때 쓰이는 component,hook 등은 모아놓자는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1690305440595&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;. 
└── 앱/ 
    ├── ... 
    └── (인증)/ 
        ├── LogoutModal/ 
        │ ├── LogoutModal.tsx 
        │ ├── LogoutModal.test.tsx 
        │ ├── LogoutModal.stories.tsx 
        │ └── LogoutModal.module.css 
        ├── useAuth.ts 
        ├── User.ts 
        ├── 가입/ 
        │ └── page.tsx 
        └── 로그인/ 
            └── page.tsx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증페이지가 있다면, 이곳에 필요한 LogoutModal, useAuth hook, User 관련 인터페이스(etc), 가입과 로그인 페이지 등을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;p data-ke-size=&quot;size16&quot;&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;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jodmsoluth/nextjs-%ED%8C%8C%EC%9D%BC%EA%B5%AC%EC%A1%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@jodmsoluth/nextjs-%ED%8C%8C%EC%9D%BC%EA%B5%AC%EC%A1%B0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&quot;&gt;https://betterprogramming.pub/how-to-structure-your-next-js-app-with-the-new-app-router-61bf2bf5a20d&lt;/a&gt;&lt;/p&gt;</description>
      <category>Solve Problem/Deep Dive</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/297</guid>
      <comments>https://coding-dahee.tistory.com/297#entry297comment</comments>
      <pubDate>Wed, 26 Jul 2023 02:19:19 +0900</pubDate>
    </item>
    <item>
      <title>파일구조 예쁘게 보는 법: 파일트리 (tree)</title>
      <link>https://coding-dahee.tistory.com/296</link>
      <description>&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;763&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lpu6n/btsoU6wl8pH/CxIoWgrVzgGxUqbLQCME8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lpu6n/btsoU6wl8pH/CxIoWgrVzgGxUqbLQCME8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lpu6n/btsoU6wl8pH/CxIoWgrVzgGxUqbLQCME8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flpu6n%2FbtsoU6wl8pH%2FCxIoWgrVzgGxUqbLQCME8K%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;763&quot; height=&quot;665&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;665&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;무슨 명령어 하나만 치면 나오는거겠지?&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_1690304668189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ brew install tree&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tree를 깔고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690304686700&quot; class=&quot;dos&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ tree&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tree 명령어를 실행하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 폴더만 트리를 보고싶다면,&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690304720068&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ tree {폴더경로}&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;p data-ke-size=&quot;size16&quot;&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;참 쉽다!!&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://macinjune.com/all-posts/mac/tip/%EB%A7%A5unix-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-tree-command%EB%A1%9C-%ED%8A%B8%EB%A6%AC-%ED%98%95%EC%8B%9D%EC%9D%98-%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0-%EB%B3%B4%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://macinjune.com/all-posts/mac/tip/%EB%A7%A5unix-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-tree-command%EB%A1%9C-%ED%8A%B8%EB%A6%AC-%ED%98%95%EC%8B%9D%EC%9D%98-%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0-%EB%B3%B4%EA%B8%B0/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Solve Problem/Guide | Tip</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/296</guid>
      <comments>https://coding-dahee.tistory.com/296#entry296comment</comments>
      <pubDate>Wed, 26 Jul 2023 02:05:36 +0900</pubDate>
    </item>
    <item>
      <title>개념 정리: CSR, SSR, 돔트리, HOC, Hook</title>
      <link>https://coding-dahee.tistory.com/295</link>
      <description>&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;CSR: Client Side Rendering&lt;/b&gt;&lt;span&gt;&lt;br /&gt;- 렌더링이&amp;nbsp;클라이언트&amp;nbsp;쪽에서&amp;nbsp;일어난다.&lt;br /&gt;- 서버는 요청을 받으면 클라이언트에 HTML과 JS를 보내준다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 클라이언트는 그것을 받아 렌더링을 시작한다.&lt;/span&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;SSR&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SEO 최적화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SSR이 서버 자원을 더 많이 사용한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;돔트리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 왜 hook이 바뀔 때 돔트리가 바뀌는건지&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;HOC: High Order Component&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;&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;- HOC(&lt;/span&gt;H&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;igher-&lt;/span&gt;O&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;rder-&lt;/span&gt;C&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;omponents)은 컴포넌트를 개발하는 하나의 패턴으로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;컴포넌트를 인자로 받아 새로운 컴포넌트로 변환해 반환하는 함수&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;이다.&lt;/span&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;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;고차 컴포넌트는 사이드 이펙트가 전혀 없는 순수 함수.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 그냥 Custom Hook을 사용하자.&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690279718938&quot; style=&quot;color: #333333; text-align: start;&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;컴포넌트에 날개를 달아줘, 리액트 Higher-order Component (HoC) | VELOPERT.LOG&quot; data-og-description=&quot;리액트 Higher-order Component (HOC) 코드를 작성하다보면, 자주 반복해서 작성하게 되는 코드들이 있습니다. 우리는 주로 그러한 것들을 함수화하여 재사용 하곤 하죠. 컴포넌트 또한 비슷하죠. 같은 U&quot; data-og-host=&quot;velopert.com&quot; data-og-source-url=&quot;https://velopert.com/3537&quot; data-og-url=&quot;https://velopert.com/3537&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/XqMMa/hyTqusQ1kx/Lfw6U2HmGEttNlkIkrNbT1/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600,https://scrap.kakaocdn.net/dn/dJ7Wxu/hyTqqxdmfG/KpT5KJsBKDj4dl5BiSk9w0/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600,https://scrap.kakaocdn.net/dn/egs3cC/hyTqDwzWMk/V0J51nJeJSuoGhg4iwjGz1/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://velopert.com/3537&quot; data-source-url=&quot;https://velopert.com/3537&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/XqMMa/hyTqusQ1kx/Lfw6U2HmGEttNlkIkrNbT1/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600,https://scrap.kakaocdn.net/dn/dJ7Wxu/hyTqqxdmfG/KpT5KJsBKDj4dl5BiSk9w0/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600,https://scrap.kakaocdn.net/dn/egs3cC/hyTqDwzWMk/V0J51nJeJSuoGhg4iwjGz1/img.jpg?width=950&amp;amp;height=600&amp;amp;face=0_0_950_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트에 날개를 달아줘, 리액트 Higher-order Component (HoC) | VELOPERT.LOG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;리액트 Higher-order Component (HOC) 코드를 작성하다보면, 자주 반복해서 작성하게 되는 코드들이 있습니다. 우리는 주로 그러한 것들을 함수화하여 재사용 하곤 하죠. 컴포넌트 또한 비슷하죠. 같은 U&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;velopert.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&lt;b&gt;Hook&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클래스 컴포넌트에서만 사용할 수 있던 상태 변화와 라이프 사이클을 hook에서도 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층의 변화 없이 상태 관련 로직을 재사용 할 수 있다. (클래스 컴포넌트라면 HOC 지옥에 빠졌을 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 간결한 코드 / 가독성 향상 / HOC 지옥 해결 / 불필요한 보일러플레이트 코드 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컴포넌트 사이에서 상태로직을 재사용하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Hook을 사용하면 컴포넌트로부터 상태 관련 로직을 추상화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 독립적인 테스트와 재사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Hook은 계층의 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와줍니다.&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;&amp;nbsp;&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;참고&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.hwahae.co.kr/all/tech/11631&quot;&gt;https://blog.hwahae.co.kr/all/tech/11631&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hahahoho5915.tistory.com/52&quot;&gt;https://hahahoho5915.tistory.com/52&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://react.dev/reference/react&quot;&gt;https://react.dev/reference/react&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://surviveasdev.tistory.com/entry/React-hook%EC%9D%B4-%EB%82%98%EC%98%A8-%EC%9D%B4%EC%9C%A0%EC%99%80-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0&quot;&gt;https://surviveasdev.tistory.com/entry/React-hook%EC%9D%B4-%EB%82%98%EC%98%A8-%EC%9D%B4%EC%9C%A0%EC%99%80-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://overreacted.io/ko/a-complete-guide-to-useeffect/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://overreacted.io/ko/a-complete-guide-to-useeffect/&lt;/a&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;&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;&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;&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;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Frontend</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/295</guid>
      <comments>https://coding-dahee.tistory.com/295#entry295comment</comments>
      <pubDate>Tue, 25 Jul 2023 19:10:29 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] 기기에 맞게 폰트 사이즈 대응하는 방법!</title>
      <link>https://coding-dahee.tistory.com/294</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React Native에서 폰트 사이즈는 어떻게 관리할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 피그마에서 본 폰트크기가 10이라면, fontSize: 10 으로 하면 될까?&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;p data-ke-size=&quot;size16&quot;&gt;디바이스의 가로가 (a~b)px: 8, (b~c)px: 10, (c~d)px: 12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 나눌 수도 있겠다. 그러나 그렇게까지는 세세하게 나눈 상황은 아니라서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 폰트사이즈르 계산할 때 하나의 함수를 통하고, 그 안에서 PixelRatio를 이용하기로 한다.&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;a href=&quot;https://reactnative.dev/docs/pixelratio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;PixelRatio란?&lt;/b&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글꼴 크기에 대한 축척 비율을 반환합니다.&lt;br /&gt;이 비율은 절대적인 글꼴 크기를 계산하는 데 사용되므로 이에 크게 의존하는 모든 요소는 이 비율을 사용해서 계산해야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;안드로이드: Settings &amp;gt; Display &amp;gt; Font Size 에서 설정된 사용자 기본 설정을 반영합니다.&lt;/li&gt;
&lt;li&gt;iOS: Settings &amp;gt; Display &amp;amp; Brightness &amp;gt; Text Size 에서 설정된 사용자 기본 설정을 반영하며, Settings &amp;gt; Accessibility &amp;gt; Display &amp;amp; Font Size &amp;gt; Large Text에서도 값을 업데이트할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 글꼴 축척이 설정되지 않은 경우, 디바이스의 pixel ratio가 반환됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1689835412452&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { PixelRatio } from 'react-native';

export const font = (size: number) =&amp;gt; {
  /*
  - 230720: `pixel(size)` 말고, size를 fontScale로 나눈다.
  - 폰트사이즈 참고 아티클: https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694
  */
  return size / PixelRatio.getFontScale();
};&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;&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;&lt;a href=&quot;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689835302897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Make Responsive React Native Text for any device&quot; data-og-description=&quot;As we faced problems related to text responsiveness in a way that sometimes it looks bigger on low end devices and smaller on modern&amp;hellip;&quot; data-og-host=&quot;muhammadrafeh.medium.com&quot; data-og-source-url=&quot;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&quot; data-og-url=&quot;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gVxpf/hyTmsW5RBu/0HnLULsGBoVEhwt7hT2cI1/img.png?width=260&amp;amp;height=462&amp;amp;face=0_0_260_462,https://scrap.kakaocdn.net/dn/nIlDM/hyTnTlfLlY/EIssTIMzRd9RRVKmKwcs2k/img.png?width=1358&amp;amp;height=849&amp;amp;face=0_0_1358_849,https://scrap.kakaocdn.net/dn/KkBiX/hyTnS0WCda/p2LILDdkaJhoe66UrFgKmk/img.png?width=1358&amp;amp;height=826&amp;amp;face=0_0_1358_826&quot;&gt;&lt;a href=&quot;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://muhammadrafeh.medium.com/make-responsive-react-native-text-for-any-device-f8301b006694&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gVxpf/hyTmsW5RBu/0HnLULsGBoVEhwt7hT2cI1/img.png?width=260&amp;amp;height=462&amp;amp;face=0_0_260_462,https://scrap.kakaocdn.net/dn/nIlDM/hyTnTlfLlY/EIssTIMzRd9RRVKmKwcs2k/img.png?width=1358&amp;amp;height=849&amp;amp;face=0_0_1358_849,https://scrap.kakaocdn.net/dn/KkBiX/hyTnS0WCda/p2LILDdkaJhoe66UrFgKmk/img.png?width=1358&amp;amp;height=826&amp;amp;face=0_0_1358_826');&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;Make Responsive React Native Text for any device&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;As we faced problems related to text responsiveness in a way that sometimes it looks bigger on low end devices and smaller on modern&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;muhammadrafeh.medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reactnative.dev/docs/pixelratio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactnative.dev/docs/pixelratio&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/React Native</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/294</guid>
      <comments>https://coding-dahee.tistory.com/294#entry294comment</comments>
      <pubDate>Thu, 20 Jul 2023 15:50:34 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] react native typescript 환경에서 env 파일 사용하기</title>
      <link>https://coding-dahee.tistory.com/293</link>
      <description>&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yong-nyong.tistory.com/46#--%--env-d-ts&quot;&gt;https://yong-nyong.tistory.com/46#--%--env-d-ts&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/React Native</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/293</guid>
      <comments>https://coding-dahee.tistory.com/293#entry293comment</comments>
      <pubDate>Sun, 16 Jul 2023 23:53:28 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] 렌더링 수 줄이기 대작전   : apollo client -  useMutation 에 ignoreResults 옵션 사용하기</title>
      <link>https://coding-dahee.tistory.com/292</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;react native에서 apollo 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;클릭 이벤트가 발생할 때마다 특정 mutation을 호출하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 mutation이 호출될 때마다 재렌더링이 2번 되는 것을 발견했다.&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;바로 이 mutation이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kSfyK/btsnpjCYjvU/H5BRuFwjD592D8MEk1ABE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kSfyK/btsnpjCYjvU/H5BRuFwjD592D8MEk1ABE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kSfyK/btsnpjCYjvU/H5BRuFwjD592D8MEk1ABE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkSfyK%2FbtsnpjCYjvU%2FH5BRuFwjD592D8MEk1ABE1%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;700&quot; height=&quot;100&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;62 line에서 return값 배열의 두번째 원소에는 loading, data 등이 들어가는데,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;mutation을 호출하면 이 loading과 data값이 업데이트되면서 총 2번의 렌더링이 더 진행되는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 결과값은 필요없다고 알려주고 재렌더링을 방지하는 옵션이 있지 않을까? 해서 찾아봤는데,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;역시나 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.apollographql.com/docs/react/data/mutations/#ignoreresults&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.apollographql.com/docs/react/data/mutations/#ignoreresults&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689171936266&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;Mutations in Apollo Client&quot; data-og-description=&quot;Modify data with the useMutation hook&quot; data-og-host=&quot;www.apollographql.com&quot; data-og-source-url=&quot;https://www.apollographql.com/docs/react/data/mutations/#ignoreresults&quot; data-og-url=&quot;https://www.apollographql.com/docs/react/data/mutations/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/5Aptd/hyTiBTfhhV/Fk1TkxNFEKZSyKWdnDQ2z1/img.jpg?width=1280&amp;amp;height=669&amp;amp;face=0_0_1280_669&quot;&gt;&lt;a href=&quot;https://www.apollographql.com/docs/react/data/mutations/#ignoreresults&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.apollographql.com/docs/react/data/mutations/#ignoreresults&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/5Aptd/hyTiBTfhhV/Fk1TkxNFEKZSyKWdnDQ2z1/img.jpg?width=1280&amp;amp;height=669&amp;amp;face=0_0_1280_669');&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;Mutations in Apollo Client&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Modify data with the useMutation hook&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.apollographql.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;707&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K1Sj5/btsnpiKRqhj/HIpsDgPoiVvdeEwqL4dVEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K1Sj5/btsnpiKRqhj/HIpsDgPoiVvdeEwqL4dVEK/img.png&quot; data-alt=&quot;63 line: `ignoreResults: true`를 넣으면 재렌더링을 방지할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K1Sj5/btsnpiKRqhj/HIpsDgPoiVvdeEwqL4dVEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK1Sj5%2FbtsnpiKRqhj%2FHIpsDgPoiVvdeEwqL4dVEK%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;707&quot; height=&quot;150&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;63 line: `ignoreResults: true`를 넣으면 재렌더링을 방지할 수 있다.&lt;/figcaption&gt;
&lt;/figure&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;p data-ke-size=&quot;size16&quot;&gt;이 mutation을 호출해도 재렌더링은 되지 않았다. 얏호!!!!!!!!!!&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;useMutation 쓰는 곳에서, result가 필요없는 경우라면 전부 저 옵션을 추가해줬다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;렌더링은 어떻게 확인했냐?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( 이런 hook을 만들어서 확인하고 싶은 컴포넌트에서 호출해서 사용했다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkXjWg/btsnoJBVslw/4TTk57lYCNKbp8H1w0qsH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkXjWg/btsnoJBVslw/4TTk57lYCNKbp8H1w0qsH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkXjWg/btsnoJBVslw/4TTk57lYCNKbp8H1w0qsH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkXjWg%2FbtsnoJBVslw%2F4TTk57lYCNKbp8H1w0qsH1%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;804&quot; height=&quot;334&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;334&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;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;useQuery와 useLazyQuery도 적용 가능하냐?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;query는 애초에 값을 불러오기 위한 용도라... 옵션이 없다.&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;&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;&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;&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;역시 코드는 파도파도 재밌는 게 계속 나온다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Solve Problem/Troubleshooting</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/292</guid>
      <comments>https://coding-dahee.tistory.com/292#entry292comment</comments>
      <pubDate>Wed, 12 Jul 2023 23:26:47 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] Dimension height 뿌시기 (안드로이드)</title>
      <link>https://coding-dahee.tistory.com/291</link>
      <description>&lt;pre id=&quot;code_1688812639057&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { getStatusBarHeight } from 'react-native-status-bar-height';

const statusBarHeight = getStatusBarHeight(false); // skip android = false;

const deviceHeight = Dimensions.get('screen').height;
const windowHeight = Dimensions.get('window').height;&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;deviceHeight: 기기 전체 세로길이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;windowHeight: 앱이 차지하는 만큼의 세로길이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;statusBarHeight는 상태바의 세로길이&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;공식문서 링크:&amp;nbsp;&lt;a href=&quot;https://reactnative.dev/docs/dimensions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactnative.dev/docs/dimensions&lt;/a&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;문제는 windowHeight가 삼성/구글 폰 별로 다른 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m7crv/btsmOMNImbT/vMyAOW6rfgCOHRN7XimaJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m7crv/btsmOMNImbT/vMyAOW6rfgCOHRN7XimaJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m7crv/btsmOMNImbT/vMyAOW6rfgCOHRN7XimaJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm7crv%2FbtsmOMNImbT%2FvMyAOW6rfgCOHRN7XimaJk%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;885&quot; height=&quot;393&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼성폰은 window height가 statusBarHeight를 포함하지 않고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글폰은 window height가 statusBarHeight를 포함한다.&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;보통 bottomNavHeight가 48인데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;device height에서 window height를 뺐을 때 48이 나오면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;window height가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;statusBarHeight를 포함한다는 뜻이다.&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;그래서 statusBarHeight를 뺀  진짜 windowHeight의 길이를 알고싶다면,&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;pre id=&quot;code_1688812767234&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const isWindowHeightIncludeStatusBarHeight = ({
  windowH,
  deviceH,
}: {
  windowH: number;
  deviceH: number;
}): boolean =&amp;gt; {
  const tempDeviceH = windowH + bottomNavBarH;

  /**
   갤럭시 S22
    &quot;_statusBarHeight&quot;: 27
    &quot;windowH&quot;: 753
    &quot;deviceH&quot;: 780
   */
  if (deviceH - tempDeviceH &amp;lt; 0) return false; // 오차가 0보다 작으면, bottomNavBarH는 없다는 뜻이야.


  if (deviceH - tempDeviceH &amp;gt;= 3) {
    // 오차 3정도 있다고 치고, 그래도 남는다 싶으면, windowH에는 statusBarHeight가 포함되지 않았다는 뜻이야.
    return false;
  }
  return true;
};&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;갤럭시 S22 같이 bottomNavBar가 존재하지 않는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;deviceH - tempDeviceH가 음수인 것을 통해 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;deviceH - tempDeviceH가 음수인 경우는, windowH = deviceH + statusBarHeight 이므로,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;return false로 예외처리 해준다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 주의: 갤럭시 S22같은 경우는 bottomNavBar가 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 주의: iOS는 windowHeight에 항상 statusBarHeight까지 포함한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kjwsx23/ReactNative-Dimension%EA%B3%BC-%EC%A2%8C%ED%91%9C%EA%B0%92&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@kjwsx23/ReactNative-Dimension%EA%B3%BC-%EC%A2%8C%ED%91%9C%EA%B0%92&lt;/a&gt;&lt;/p&gt;</description>
      <category>Solve Problem/React Native</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/291</guid>
      <comments>https://coding-dahee.tistory.com/291#entry291comment</comments>
      <pubDate>Sat, 8 Jul 2023 19:41:16 +0900</pubDate>
    </item>
    <item>
      <title>react-native-push-notification 사용 시 주의점 (안드로이드 id)</title>
      <link>https://coding-dahee.tistory.com/290</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/zo0r/react-native-push-notification&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/zo0r/react-native-push-notification&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686298094710&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - zo0r/react-native-push-notification: React Native Local and Remote Notifications&quot; data-og-description=&quot;React Native Local and Remote Notifications. Contribute to zo0r/react-native-push-notification development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/zo0r/react-native-push-notification&quot; data-og-url=&quot;https://github.com/zo0r/react-native-push-notification&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dKmfxt/hySWoNcMv8/EtN8dlKgpuwxnKroNd1CWk/img.png?width=1200&amp;amp;height=600&amp;amp;face=986_136_1051_207&quot;&gt;&lt;a href=&quot;https://github.com/zo0r/react-native-push-notification&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/zo0r/react-native-push-notification&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dKmfxt/hySWoNcMv8/EtN8dlKgpuwxnKroNd1CWk/img.png?width=1200&amp;amp;height=600&amp;amp;face=986_136_1051_207');&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;GitHub - zo0r/react-native-push-notification: React Native Local and Remote Notifications&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;React Native Local and Remote Notifications. Contribute to zo0r/react-native-push-notification development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;962&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFZCBh/btsjjBHrizq/yOd5bupSzvBTKbEYKHNK8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFZCBh/btsjjBHrizq/yOd5bupSzvBTKbEYKHNK8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFZCBh/btsjjBHrizq/yOd5bupSzvBTKbEYKHNK8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFZCBh%2FbtsjjBHrizq%2FyOd5bupSzvBTKbEYKHNK8k%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;816&quot; height=&quot;962&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;962&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보다시피 id를 설정할 수 있는데, 한번 지정된 id는 다시 사용하지 않는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안그러면 이 푸시에 넣은 데이터를 꺼내올 때 예전 id의 데이터를 꺼내오기 때문이다.&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;&lt;b&gt;부디 항상 새로운 id를 부여하시길!!!!&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는, id가 optional이기 때문에 아예 부여 안하면 이렇게 알아서부여해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 데이터는 이 함수로 가져왔다.&lt;/p&gt;
&lt;div style=&quot;background-color: #1f1f1f; color: #cccccc;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;PushNotification&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;getScheduledLocalNotifications&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3yXci/btsjllD8BVU/KTbNkqbaH1R0RtftJxkX2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3yXci/btsjllD8BVU/KTbNkqbaH1R0RtftJxkX2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3yXci/btsjllD8BVU/KTbNkqbaH1R0RtftJxkX2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3yXci%2FbtsjllD8BVU%2FKTbNkqbaH1R0RtftJxkX2K%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;714&quot; height=&quot;516&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;516&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;p data-ke-size=&quot;size16&quot;&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;&lt;a href=&quot;https://github.com/zo0r/react-native-push-notification/issues/2368&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/zo0r/react-native-push-notification/issues/2368&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686299096274&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;[FYI] If the ID used once is given again, the old data is loaded. Be careful. &amp;middot; Issue #2368 &amp;middot; zo0r/react-native-push-notificat&quot; data-og-description=&quot;Give this id an unused id. Otherwise, the old data comes from the cached data that was used in the past.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/zo0r/react-native-push-notification/issues/2368&quot; data-og-url=&quot;https://github.com/zo0r/react-native-push-notification/issues/2368&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fiYNd/hySVAucjxB/wQN7sHKNYr91PND5CzDnZ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/zo0r/react-native-push-notification/issues/2368&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/zo0r/react-native-push-notification/issues/2368&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fiYNd/hySVAucjxB/wQN7sHKNYr91PND5CzDnZ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;[FYI] If the ID used once is given again, the old data is loaded. Be careful. &amp;middot; Issue #2368 &amp;middot; zo0r/react-native-push-notificat&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Give this id an unused id. Otherwise, the old data comes from the cached data that was used in the past.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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>Solve Problem/Troubleshooting</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/290</guid>
      <comments>https://coding-dahee.tistory.com/290#entry290comment</comments>
      <pubDate>Fri, 9 Jun 2023 17:09:51 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] Admob 보상형 영상 광고 다 보고 X 버튼 클릭 안되는 오류 해결 : 상태바 숨기기!</title>
      <link>https://coding-dahee.tistory.com/288</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;어느날... 이러한 CS가 왔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZI4UQ/btsa6cCeyI1/n8ELPETbAJACZo5AwRHID0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZI4UQ/btsa6cCeyI1/n8ELPETbAJACZo5AwRHID0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZI4UQ/btsa6cCeyI1/n8ELPETbAJACZo5AwRHID0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZI4UQ%2Fbtsa6cCeyI1%2Fn8ELPETbAJACZo5AwRHID0%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;546&quot; height=&quot;109&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2QBDj/btsa5UBE9yZ/CLoJio67h2JK0rhHijZADK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2QBDj/btsa5UBE9yZ/CLoJio67h2JK0rhHijZADK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2QBDj/btsa5UBE9yZ/CLoJio67h2JK0rhHijZADK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2QBDj%2Fbtsa5UBE9yZ%2FCLoJio67h2JK0rhHijZADK%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;185&quot; height=&quot;401&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광고를 다 봤는데도 상태바에 가려져서 X버튼을 누르지 못했다는 것!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 react native에서 보상형 영상 광고를 띄워주기 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@react-native-firebase/admob:&amp;nbsp;11.5.0&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;서드파티... admob을 원망하며 admob+statusbar를 키워드로 이슈를 찾아봤는데 마땅히 해결책이 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;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;당장 react-native에서&amp;nbsp; StatusBar를 이용해 숨겨보았다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/437367696&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cgW8BG/hySkNGhhQr/031xKPM8I7HzHnGISKRe30/img.jpg?width=1752&amp;amp;height=870&amp;amp;face=0_0_1752_870,https://scrap.kakaocdn.net/dn/gxOP3/hySiVspjsn/6h8N87V1rwaZ7a5QWWKQhK/img.jpg?width=1752&amp;amp;height=870&amp;amp;face=0_0_1752_870&quot; data-video-width=&quot;860&quot; data-video-height=&quot;427&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;427&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/437367696?service=daum_tistory&quot; width=&quot;860&quot; height=&quot;427&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;p data-ke-size=&quot;size16&quot;&gt;참고로, statusBar의 height는 react-native-status-bar-height 라이브러리에서 얻을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1681798194895&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { StatusBar } from 'react-native';
import { getStatusBarHeight } from 'react-native-status-bar-height';

export default () =&amp;gt; {
    return (
      &amp;lt;View style={{ flex: 1, backgroundColor: 'lightgreen' }}&amp;gt;
        &amp;lt;TouchableOpacity
          style={{
            height: getStatusBarHeight(),
            backgroundColor: 'lightcoral',
          }} /&amp;gt;
        &amp;lt;TouchableOpacity
          onPress={() =&amp;gt; {
            StatusBar.setHidden(true);
          }}&amp;gt;
        	&amp;lt;Text&amp;gt;상태바 숨기기&amp;lt;/Text&amp;gt;
        &amp;lt;/TouchableOpacity&amp;gt;
        &amp;lt;TouchableOpacity
          onPress={() =&amp;gt; {
            StatusBar.setHidden(false);
          }}&amp;gt;
        	&amp;lt;Text&amp;gt;상태바 보이기&amp;lt;/Text&amp;gt;
        &amp;lt;/TouchableOpacity&amp;gt;
      &amp;lt;/View&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&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;-&amp;gt; 상태바를 숨기면  상태바가 있었던 부분도 클릭이 가능해진다!&lt;/b&gt;&lt;/h3&gt;</description>
      <category>Solve Problem/Troubleshooting</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/288</guid>
      <comments>https://coding-dahee.tistory.com/288#entry288comment</comments>
      <pubDate>Tue, 18 Apr 2023 15:13:32 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] linkTo 사용 시, The 'navigation' object hasn't been initialized yet 문제 해결 방법 (react-navigation NavigationContainer 마운팅된 직후를 onReady로 감지하기)</title>
      <link>https://coding-dahee.tistory.com/287</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[React&amp;nbsp;Native]&amp;nbsp;linkTo&amp;nbsp;사용&amp;nbsp;시,&amp;nbsp;The&amp;nbsp;'navigation'&amp;nbsp;object&amp;nbsp;hasn't&amp;nbsp;been&amp;nbsp;initialized&amp;nbsp;yet&amp;nbsp;문제&amp;nbsp;해결&amp;nbsp;방법&amp;nbsp;(react-navigation&amp;nbsp;NavigationContainer&amp;nbsp;마운팅된&amp;nbsp;직후를&amp;nbsp;onReady로&amp;nbsp;감지하기)&lt;/b&gt;&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;특정 페이지에 도달 할 수 있는 링크인 &lt;b&gt;딥링크&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Android의 경우) Linking.getInitialURL 로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(iOS의 경우) Linking.addEventListener('url', handleOpenUrl) 로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 열게 한 &lt;b&gt;url 장본인(?)&lt;/b&gt;을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;(이 글은 Android 기준으로 코드를 작성했습니다.)&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1680885119360&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const url = &quot;roubitapp://root-tab/setting&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 url로 앱을 열면 SettingScreen이라는 화면으로 navigate해야한다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 아래와 같이 짤 수 있다. &lt;a href=&quot;https://reactnavigation.org/docs/deep-linking/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(자세한 딥링크 세팅은 이곳을 참고)&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680885369897&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useState } from 'react';
import { Linking } from 'react-native';
import { NavigationContainer, useLinkTo } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

export default () =&amp;gt; {
  const linkTo = useLinkTo()

  useEffect(() =&amp;gt; {
      Linking.getInitialURL()?.then(url =&amp;gt; {
        if (url) {
          const deepLink = getDeepLinkByUrl(url); // ex. '/setting'
          linkTo(deepLink)
        }
      });
  }, [])

  return (
    &amp;lt;NavigationContainer
      linking={{
        prefixes: ['roubitapp://'],
        config: {
         // ...,
         SettingScreen: {
         	path: &quot;setting&quot;
         }
        }
      }}
      &amp;gt;
      &amp;lt;Stack.Navigator&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
      &amp;lt;/Stack.Navigator&amp;gt;
    &amp;lt;/NavigationContainer&amp;gt;
   );
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, linkTo를 사용하면 아래와 같은 오류가 난다.&lt;/p&gt;
&lt;pre id=&quot;code_1680885609797&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ERROR  The 'navigation' object hasn't been initialized yet. 
// This might happen if you don't have a navigator mounted, 
// or if the navigator hasn't finished mounting. 
// See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 navigation이 세팅되지 않았는데 사용하려고 해서 생기는 문제다.&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;a href=&quot;https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에러에 친절하게 안내되어있는 링크&lt;/a&gt;를 따라가본다. &lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(웬만한 에러는 에러내용 잘 읽으면 해결됨. 떠먹여주는대로 받아먹자!)&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;navigation이 세팅되었는지를 아는 방법에 대해 안내해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpyAv4/btr8KJ39VQD/N9TUbwJW6hxsfWuW0JpFck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpyAv4/btr8KJ39VQD/N9TUbwJW6hxsfWuW0JpFck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpyAv4/btr8KJ39VQD/N9TUbwJW6hxsfWuW0JpFck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpyAv4%2Fbtr8KJ39VQD%2FN9TUbwJW6hxsfWuW0JpFck%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;971&quot; height=&quot;382&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Linking.getInitialURL()을 실행하는 시점에 navigationRef.isReady()가 여전히 false라면 쓰나마나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 navigation이 세팅되는 순간을 알아야 한다. 그래야 그 이후에 linkTo를 사용할 수 있기 때문이다.&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;a href=&quot;https://reactnavigation.org/docs/navigation-container/#onready&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 링크를 보자.&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavigationContainer에 onReady라는 prop을 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #1c1e21; text-align: start;&quot;&gt;문서에서는 아래와 같이 설명하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680885986277&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Function which is called after the navigation container and all its children finish mounting for the first time.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavigationContainer와 하위 컴포넌트가 모두 마운팅을 마친 시점에 onReady가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 점을 이용하여 아래와 같이 코드를 추가했다.&lt;/p&gt;
&lt;pre id=&quot;code_1680884431046&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useState } from 'react';
import { Linking } from 'react-native';
import { NavigationContainer, useLinkTo } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator&amp;lt;RootTabStackParams&amp;gt;();

export default () =&amp;gt; {
  const [isNavMounted, setIsNavMounted] = useState&amp;lt;boolean&amp;gt;(false);
  const linkTo = useLinkTo()

  useEffect(() =&amp;gt; {
    if (isNavMounted) {
      Linking.getInitialURL()?.then(url =&amp;gt; {
        if (url) {
          const deepLink = getDeepLinkByUrl(url); // ex. '/setting';
          linkTo(deepLink)
        }
      });
    }
  }, [isNavMounted])

  return (
    &amp;lt;NavigationContainer
   	  onReady={() =&amp;gt; {
        setIsNavMounted(true)
      }}
      linking={{
        prefixes: ['roubitapp://'],
        config: {
         // ...,
         SettingScreen: {
         	path: &quot;setting&quot;
         }
        }
      }}
      &amp;gt;
      &amp;lt;Stack.Navigator&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
        &amp;lt;Stack.Screen /&amp;gt;
      &amp;lt;/Stack.Navigator&amp;gt;
    &amp;lt;/NavigationContainer&amp;gt;
   );
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 isNavMounted를 이용하여 navigation 세팅이 완료되었음을 확신하고 linkTo를 사용할 수 있게 되었다. &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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@beanlove97/NavigationContainer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@beanlove97/NavigationContainer&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reactnavigation.org/docs/navigating-without-navigation-prop/#handling-initialization&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactnavigation.org/docs/navigating-without-navigation-prop/#handling-initialization&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://reactnavigation.org/docs/navigation-container/#onready&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactnavigation.org/docs/navigation-container/#onready&lt;/a&gt;&lt;/p&gt;</description>
      <category>Solve Problem/Troubleshooting</category>
      <author>안다희</author>
      <guid isPermaLink="true">https://coding-dahee.tistory.com/287</guid>
      <comments>https://coding-dahee.tistory.com/287#entry287comment</comments>
      <pubDate>Sat, 8 Apr 2023 01:51:57 +0900</pubDate>
    </item>
  </channel>
</rss>