<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>IT의 IT 블로그</title>
    <link>https://dlsxo.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 25 Jun 2026 17:44:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>IT의 IT 블로그</managingEditor>
    <image>
      <title>IT의 IT 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/8415068/attach/e3b6493e1bb44f9bac0ea63394af18d6</url>
      <link>https://dlsxo.tistory.com</link>
    </image>
    <item>
      <title>사이드 프로젝트 | NBA Game Picker (4) - Matchup Score 설명 페이지 구성</title>
      <link>https://dlsxo.tistory.com/19</link>
      <description>&lt;p data-end=&quot;287&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-end=&quot;287&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;321&quot; data-start=&quot;289&quot; data-ke-size=&quot;size16&quot;&gt;지난 글에서는&lt;br /&gt;NBA Game Picker 프로젝트에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;353&quot; data-start=&quot;323&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;329&quot; data-start=&quot;323&quot; data-section-id=&quot;b4ti00&quot;&gt;홈 화면&lt;/li&gt;
&lt;li data-end=&quot;341&quot; data-start=&quot;330&quot; data-section-id=&quot;13ej1b1&quot;&gt;경기 목록 페이지&lt;/li&gt;
&lt;li data-end=&quot;353&quot; data-start=&quot;342&quot; data-section-id=&quot;14hvvps&quot;&gt;경기 상세 페이지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;375&quot; data-start=&quot;355&quot; data-ke-size=&quot;size16&quot;&gt;까지 어떻게 확장했는지 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;375&quot; data-start=&quot;355&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;396&quot; data-start=&quot;377&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 그다음 단계로 진행한&lt;/p&gt;
&lt;p data-end=&quot;449&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; Matchup Score &amp;nbsp;설명 페이지(/about-score) 구성 과정&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;464&quot; data-start=&quot;451&quot; data-ke-size=&quot;size16&quot;&gt;을 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;464&quot; data-start=&quot;451&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;466&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 단순히 NBA 경기 일정을 보여주는 것이 아니라,&lt;br /&gt;&lt;b&gt;오늘 가장 볼 만한 경기를 추천하는 것&lt;/b&gt;이 핵심입니다.&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;466&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;611&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;그래서 추천 점수를 보여주는 것만으로는 부족했고,&lt;br /&gt;사용자가 그 점수를 &lt;b&gt;이해할 수 있는 페이지&lt;/b&gt;가 필요하다고 생각했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;616&quot; data-start=&quot;613&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;650&quot; data-start=&quot;618&quot; data-section-id=&quot;1cakp69&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. /about-score 페이지가 필요했던 이유 &lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;703&quot; data-start=&quot;652&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면과 상세 페이지에는&lt;br /&gt;Watchability Score가 이미 표시되고 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FtOBL/dJMcadIJRp5/nlvElJ4f7eM9AKakVlEZYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FtOBL/dJMcadIJRp5/nlvElJ4f7eM9AKakVlEZYK/img.png&quot; data-alt=&quot;표시된 점수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FtOBL/dJMcadIJRp5/nlvElJ4f7eM9AKakVlEZYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFtOBL%2FdJMcadIJRp5%2FnlvElJ4f7eM9AKakVlEZYK%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;309&quot; height=&quot;228&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표시된 점수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;751&quot; data-start=&quot;705&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 사용자는 홈에서 추천 경기를 보면서&lt;br /&gt;이런 궁금증을 가질 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;841&quot; data-start=&quot;753&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;768&quot; data-start=&quot;753&quot; data-section-id=&quot;1sub9f1&quot;&gt;왜 이 경기가 91점인지&lt;/li&gt;
&lt;li data-end=&quot;791&quot; data-start=&quot;769&quot; data-section-id=&quot;h1um3m&quot;&gt;이 점수는 어떤 기준으로 붙은 것인지&lt;/li&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;792&quot; data-section-id=&quot;pjh854&quot;&gt;단순히 인기 팀 경기라서 높은 것인지&lt;/li&gt;
&lt;li data-end=&quot;841&quot; data-start=&quot;815&quot; data-section-id=&quot;1fcibc6&quot;&gt;점수가 높다는 것이 정확히 무엇을 의미하는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;883&quot; data-start=&quot;843&quot; data-ke-size=&quot;size16&quot;&gt;이런 질문에 답하지 못하면&lt;br /&gt;점수는 결국 그냥 숫자로만 보이게 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;883&quot; data-start=&quot;843&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;926&quot; data-start=&quot;885&quot; data-ke-size=&quot;size16&quot;&gt;그래서 /about-score 페이지는&lt;br /&gt;단순한 보조 페이지라기보다,&lt;/p&gt;
&lt;p data-end=&quot;955&quot; data-start=&quot;928&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 점수를 해석할 수 있게 만드는 페이지&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;975&quot; data-start=&quot;957&quot; 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;1641&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brFHOx/dJMcajoEVSN/ekEwHKlnS80Rcc4wEf8ATk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brFHOx/dJMcajoEVSN/ekEwHKlnS80Rcc4wEf8ATk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brFHOx/dJMcajoEVSN/ekEwHKlnS80Rcc4wEf8ATk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrFHOx%2FdJMcajoEVSN%2FekEwHKlnS80Rcc4wEf8ATk%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;1641&quot; height=&quot;904&quot; data-origin-width=&quot;1641&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;975&quot; data-start=&quot;957&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;989&quot; data-start=&quot;977&quot; data-ke-size=&quot;size16&quot;&gt;즉 이 페이지의 목적은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1073&quot; data-start=&quot;991&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1022&quot; data-start=&quot;991&quot; data-section-id=&quot;14ipruh&quot;&gt;Watchability Score가 무엇인지 설명하고&lt;/li&gt;
&lt;li data-end=&quot;1046&quot; data-start=&quot;1023&quot; data-section-id=&quot;15wlfj5&quot;&gt;어떤 요소로 점수가 구성되는지 보여주고&lt;/li&gt;
&lt;li data-end=&quot;1073&quot; data-start=&quot;1047&quot; data-section-id=&quot;11pze80&quot;&gt;사용자가 그 숫자를 읽을 수 있게 만드는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1075&quot; data-ke-size=&quot;size16&quot;&gt;이었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1086&quot; data-start=&quot;1083&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1103&quot; data-start=&quot;1088&quot; data-section-id=&quot;1x904ql&quot; data-ke-size=&quot;size26&quot;&gt;2. 페이지 설계 전 정리한 핵심 내용&lt;/h2&gt;
&lt;p data-end=&quot;1155&quot; data-start=&quot;1105&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지를 만들기 전에&lt;br /&gt;먼저 &amp;ldquo;사용자가 여기서 무엇을 알아야 하는가&amp;rdquo;를 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1155&quot; data-start=&quot;1105&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1172&quot; data-start=&quot;1157&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 크게 4가지였습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1203&quot; data-start=&quot;1174&quot; data-section-id=&quot;1k6xgw8&quot; data-ke-size=&quot;size23&quot;&gt;1) Watchability Score의 역할&lt;/h3&gt;
&lt;p data-end=&quot;1250&quot; data-start=&quot;1204&quot; data-ke-size=&quot;size16&quot;&gt;이 점수가 단순 수치가 아니라&lt;br /&gt;오늘 볼 경기를 빠르게 고르기 위한 기준이라는 점&lt;/p&gt;
&lt;h3 data-end=&quot;1270&quot; data-start=&quot;1252&quot; data-section-id=&quot;1mstq5c&quot; data-ke-size=&quot;size23&quot;&gt;2) 점수를 구성하는 요소&lt;/h3&gt;
&lt;p data-end=&quot;1301&quot; data-start=&quot;1271&quot; data-ke-size=&quot;size16&quot;&gt;현재 기준으로는 다음 3가지를 핵심 요소로 잡았습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1335&quot; data-start=&quot;1303&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1314&quot; data-start=&quot;1303&quot; data-section-id=&quot;1ep0vp&quot;&gt;Closeness&lt;/li&gt;
&lt;li data-end=&quot;1324&quot; data-start=&quot;1315&quot; data-section-id=&quot;1u0son9&quot;&gt;Scoring&lt;/li&gt;
&lt;li data-end=&quot;1335&quot; data-start=&quot;1325&quot; data-section-id=&quot;htjs68&quot;&gt;Momentum&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TZJVp/dJMcagZO1Vj/4RClIMNmibTVo4OVZxiJEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TZJVp/dJMcagZO1Vj/4RClIMNmibTVo4OVZxiJEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TZJVp/dJMcagZO1Vj/4RClIMNmibTVo4OVZxiJEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTZJVp%2FdJMcagZO1Vj%2F4RClIMNmibTVo4OVZxiJEk%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;1233&quot; height=&quot;456&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;1352&quot; data-start=&quot;1337&quot; data-section-id=&quot;1iassf1&quot; data-ke-size=&quot;size23&quot;&gt;3) 각 요소의 의미&lt;/h3&gt;
&lt;p data-end=&quot;1358&quot; data-start=&quot;1353&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1418&quot; data-start=&quot;1360&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1380&quot; data-start=&quot;1360&quot; data-section-id=&quot;1pctmp2&quot;&gt;Closeness &amp;rarr; 접전 가능성&lt;/li&gt;
&lt;li data-end=&quot;1399&quot; data-start=&quot;1381&quot; data-section-id=&quot;mxzwk2&quot;&gt;Scoring &amp;rarr; 득점 기대치&lt;/li&gt;
&lt;li data-end=&quot;1418&quot; data-start=&quot;1400&quot; data-section-id=&quot;d5ovxi&quot;&gt;Momentum &amp;rarr; 최근 흐름&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1438&quot; data-start=&quot;1420&quot; data-ke-size=&quot;size16&quot;&gt;처럼 해석할 수 있어야 했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1455&quot; data-start=&quot;1440&quot; data-section-id=&quot;1vxty22&quot; data-ke-size=&quot;size23&quot;&gt;4) 점수 해석 기준&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8r0cp/dJMcaf7GI6N/uk9DQqB3iy2GUvZx1IpP7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8r0cp/dJMcaf7GI6N/uk9DQqB3iy2GUvZx1IpP7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8r0cp/dJMcaf7GI6N/uk9DQqB3iy2GUvZx1IpP7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8r0cp%2FdJMcaf7GI6N%2Fuk9DQqB3iy2GUvZx1IpP7k%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;583&quot; height=&quot;535&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1461&quot; data-start=&quot;1456&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1540&quot; data-start=&quot;1463&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1487&quot; data-start=&quot;1463&quot; data-section-id=&quot;9zgzla&quot;&gt;90점 이상 &amp;rarr; 가장 먼저 볼 만한 경기&lt;/li&gt;
&lt;li data-end=&quot;1512&quot; data-start=&quot;1488&quot; data-section-id=&quot;5w5kqm&quot;&gt;80점대 &amp;rarr; 충분히 기대할 수 있는 경기&lt;/li&gt;
&lt;li data-end=&quot;1540&quot; data-start=&quot;1513&quot; data-section-id=&quot;b0tma4&quot;&gt;70점대 &amp;rarr; 상황에 따라 볼 가치가 있는 경기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1568&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;처럼 점수를 읽을 수 있도록 정리해야 했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1568&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1595&quot; data-start=&quot;1570&quot; data-ke-size=&quot;size16&quot;&gt;즉 이 페이지는&lt;br /&gt;긴 설명을 읽는 페이지보다&lt;/p&gt;
&lt;p data-end=&quot;1620&quot; data-start=&quot;1597&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;점수 구조를 빠르게 이해하는 페이지&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1639&quot; data-start=&quot;1622&quot; data-ke-size=&quot;size16&quot;&gt;가 되어야 한다고 생각했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1644&quot; data-start=&quot;1641&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1665&quot; data-start=&quot;1646&quot; data-section-id=&quot;18wjxwt&quot; data-ke-size=&quot;size26&quot;&gt;3. 초기 구성에서 아쉬웠던 부분&lt;/h2&gt;
&lt;p data-end=&quot;1696&quot; data-start=&quot;1667&quot; data-ke-size=&quot;size16&quot;&gt;초기에는 설명문과 카드 위주로 페이지를 구성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1703&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1783&quot; data-start=&quot;1705&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1728&quot; data-start=&quot;1705&quot; data-section-id=&quot;r3yj37&quot;&gt;Watchability Score 개요&lt;/li&gt;
&lt;li data-end=&quot;1764&quot; data-start=&quot;1729&quot; data-section-id=&quot;fdshe9&quot;&gt;Closeness / Scoring / Momentum 설명&lt;/li&gt;
&lt;li data-end=&quot;1775&quot; data-start=&quot;1765&quot; data-section-id=&quot;2ked1c&quot;&gt;샘플 점수 계산&lt;/li&gt;
&lt;li data-end=&quot;1783&quot; data-start=&quot;1776&quot; data-section-id=&quot;1nxoa5t&quot;&gt;해석 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1799&quot; data-start=&quot;1785&quot; data-ke-size=&quot;size16&quot;&gt;이런 구조로 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1838&quot; data-start=&quot;1801&quot; data-ke-size=&quot;size16&quot;&gt;정보 자체는 충분했지만, 실제로 구현해보니 아쉬운 점도 있었습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1858&quot; data-start=&quot;1840&quot; data-section-id=&quot;e3oiqd&quot; data-ke-size=&quot;size23&quot;&gt;1) 텍스트가 많아 보였다&lt;/h3&gt;
&lt;p data-end=&quot;1907&quot; data-start=&quot;1859&quot; data-ke-size=&quot;size16&quot;&gt;내용은 맞았지만&lt;br /&gt;전체적으로 읽어야 이해되는 구조라서&lt;br /&gt;가독성이 조금 떨어졌습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1935&quot; data-start=&quot;1909&quot; data-section-id=&quot;1ix8ngq&quot; data-ke-size=&quot;size23&quot;&gt;2) 프로젝트 성격이 잘 드러나지 않았다&lt;/h3&gt;
&lt;p data-end=&quot;1985&quot; data-start=&quot;1936&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 설명 페이지처럼 보였고,&lt;br /&gt;NBA 프로젝트 특유의 분위기나 개성이 약했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2006&quot; data-start=&quot;1987&quot; data-section-id=&quot;1b0tnp9&quot; data-ke-size=&quot;size23&quot;&gt;3) 카드 구성이 단조로웠다&lt;/h3&gt;
&lt;p data-end=&quot;2062&quot; data-start=&quot;2007&quot; data-ke-size=&quot;size16&quot;&gt;정보는 나뉘어 있었지만&lt;br /&gt;시각적인 위계가 약해서&lt;br /&gt;어디부터 봐야 할지 바로 들어오지 않았습니다.&lt;/p&gt;
&lt;p data-end=&quot;2062&quot; data-start=&quot;2007&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2117&quot; data-start=&quot;2064&quot; data-ke-size=&quot;size16&quot;&gt;즉, 설명은 가능했지만&lt;br /&gt;프로젝트의 성격을 더 잘 보여주는 방식으로 정리할 필요가 있었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2122&quot; data-start=&quot;2119&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2142&quot; data-start=&quot;2124&quot; data-section-id=&quot;1fmj34r&quot; data-ke-size=&quot;size26&quot;&gt;4. 설명 페이지의 방향성 정리&lt;/h2&gt;
&lt;p data-end=&quot;2228&quot; data-start=&quot;2144&quot; data-ke-size=&quot;size16&quot;&gt;이후에는 /about-score 페이지를&lt;br /&gt;단순 설명 카드 모음이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;2228&quot; data-start=&quot;2144&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;프로젝트의 핵심 컨셉을 더 잘 보여주는 구조로 정리하려고 했습니다.&lt;/p&gt;
&lt;p data-end=&quot;2258&quot; data-start=&quot;2230&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업에서 중요하게 본 기준은 다음과 같습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2285&quot; data-start=&quot;2260&quot; data-section-id=&quot;18fkiz7&quot; data-ke-size=&quot;size23&quot;&gt;1) 설명보다 구조가 먼저 보여야 한다&lt;/h3&gt;
&lt;p data-end=&quot;2334&quot; data-start=&quot;2286&quot; data-ke-size=&quot;size16&quot;&gt;사용자가 긴 문장을 읽기 전에&lt;br /&gt;이 페이지가 무엇을 설명하는지 먼저 보여야 했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2361&quot; data-start=&quot;2336&quot; data-section-id=&quot;owqsm5&quot; data-ke-size=&quot;size23&quot;&gt;2) 점수 요소가 한눈에 들어와야 한다&lt;/h3&gt;
&lt;p data-end=&quot;2422&quot; data-start=&quot;2362&quot; data-ke-size=&quot;size16&quot;&gt;Closeness, Scoring, Momentum&lt;br /&gt;이 세 가지가 핵심이라는 점이 바로 보여야 했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2447&quot; data-start=&quot;2424&quot; data-section-id=&quot;dmwgto&quot; data-ke-size=&quot;size23&quot;&gt;3) 샘플 점수 예시가 있어야 한다&lt;/h3&gt;
&lt;p data-end=&quot;2491&quot; data-start=&quot;2448&quot; data-ke-size=&quot;size16&quot;&gt;실제 경기 예시를 통해&lt;br /&gt;점수가 어떻게 구성되는지 보여줄 필요가 있었습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2518&quot; data-start=&quot;2493&quot; data-section-id=&quot;6z0ebi&quot; data-ke-size=&quot;size23&quot;&gt;4) 프로젝트 분위기와 연결되어야 한다&lt;/h3&gt;
&lt;p data-end=&quot;2585&quot; data-start=&quot;2519&quot; data-ke-size=&quot;size16&quot;&gt;NBA 기반 프로젝트인 만큼&lt;br /&gt;단순 문서형 설명 페이지보다는&lt;br /&gt;스포츠 서비스에 가까운 분위기를 유지하고 싶었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2590&quot; data-start=&quot;2587&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2610&quot; data-start=&quot;2592&quot; data-section-id=&quot;lg0s8v&quot; data-ke-size=&quot;size26&quot;&gt;5. 최종 페이지 구조&lt;/h2&gt;
&lt;p data-end=&quot;2659&quot; data-start=&quot;2612&quot; data-ke-size=&quot;size16&quot;&gt;최종적으로 /about-score 페이지는&lt;br /&gt;다음과 같은 흐름으로 구성했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2676&quot; data-start=&quot;2661&quot; data-section-id=&quot;17ekqtn&quot; data-ke-size=&quot;size23&quot;&gt;1) 상단 소개 영역&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXLRfk/dJMcaipQeyt/SBcze4E1gJ9TpJs7LjIRr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXLRfk/dJMcaipQeyt/SBcze4E1gJ9TpJs7LjIRr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXLRfk/dJMcaipQeyt/SBcze4E1gJ9TpJs7LjIRr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXLRfk%2FdJMcaipQeyt%2FSBcze4E1gJ9TpJs7LjIRr1%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;1209&quot; height=&quot;357&quot; data-origin-width=&quot;1209&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2739&quot; data-start=&quot;2677&quot; data-ke-size=&quot;size16&quot;&gt;Watchability Score가 무엇인지 간단히 설명하고,&lt;br /&gt;이 페이지가 어떤 역할을 하는지 보여주는 영역&lt;/p&gt;
&lt;h3 data-end=&quot;2757&quot; data-start=&quot;2741&quot; data-section-id=&quot;1r77lov&quot; data-ke-size=&quot;size23&quot;&gt;2) 핵심 요소 3가지&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ri29a/dJMcadBYi1R/ZGCKcgu788YdUkcwlR2gm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ri29a/dJMcadBYi1R/ZGCKcgu788YdUkcwlR2gm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ri29a/dJMcadBYi1R/ZGCKcgu788YdUkcwlR2gm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRi29a%2FdJMcadBYi1R%2FZGCKcgu788YdUkcwlR2gm1%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;1201&quot; height=&quot;455&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2790&quot; data-start=&quot;2758&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2769&quot; data-start=&quot;2758&quot; data-section-id=&quot;1ep0vp&quot;&gt;Closeness&lt;/li&gt;
&lt;li data-end=&quot;2779&quot; data-start=&quot;2770&quot; data-section-id=&quot;1u0son9&quot;&gt;Scoring&lt;/li&gt;
&lt;li data-end=&quot;2790&quot; data-start=&quot;2780&quot; data-section-id=&quot;htjs68&quot;&gt;Momentum&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2818&quot; data-start=&quot;2792&quot; data-ke-size=&quot;size16&quot;&gt;각 요소의 의미와 반영 예시를 카드 형태로 정리&lt;/p&gt;
&lt;h3 data-end=&quot;2838&quot; data-start=&quot;2820&quot; data-section-id=&quot;1p6gqxl&quot; data-ke-size=&quot;size23&quot;&gt;3) 샘플 경기 점수 예시&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W74w5/dJMcacwpsmh/GbZ2cO1ugJZa9ZjdPhVXX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W74w5/dJMcacwpsmh/GbZ2cO1ugJZa9ZjdPhVXX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W74w5/dJMcacwpsmh/GbZ2cO1ugJZa9ZjdPhVXX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW74w5%2FdJMcacwpsmh%2FGbZ2cO1ugJZa9ZjdPhVXX0%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;636&quot; height=&quot;535&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2890&quot; data-start=&quot;2839&quot; data-ke-size=&quot;size16&quot;&gt;특정 경기의 점수를 예시로 보여주고,&lt;br /&gt;각 항목이 점수에 어떻게 반영되는지 시각적으로 설명&lt;/p&gt;
&lt;h3 data-end=&quot;2907&quot; data-start=&quot;2892&quot; data-section-id=&quot;1vxty22&quot; data-ke-size=&quot;size23&quot;&gt;4) 점수 해석 기준&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PNA2I/dJMcahkcRKe/DUXCtk5HK4G8x21BroYAl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PNA2I/dJMcahkcRKe/DUXCtk5HK4G8x21BroYAl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PNA2I/dJMcahkcRKe/DUXCtk5HK4G8x21BroYAl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPNA2I%2FdJMcahkcRKe%2FDUXCtk5HK4G8x21BroYAl1%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;573&quot; height=&quot;526&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2950&quot; data-start=&quot;2908&quot; data-ke-size=&quot;size16&quot;&gt;90+, 80s, 70s, 60&amp;darr;&lt;br /&gt;처럼 점수를 어떻게 읽으면 되는지 정리&lt;/p&gt;
&lt;h3 data-end=&quot;2970&quot; data-start=&quot;2952&quot; data-section-id=&quot;8z7zse&quot; data-ke-size=&quot;size23&quot;&gt;5) 페이지가 필요한 이유&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0IN0j/dJMcaiDmFJ9/fsQrPx1oWQiCDGYyvgVkx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0IN0j/dJMcaiDmFJ9/fsQrPx1oWQiCDGYyvgVkx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0IN0j/dJMcaiDmFJ9/fsQrPx1oWQiCDGYyvgVkx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0IN0j%2FdJMcaiDmFJ9%2FfsQrPx1oWQiCDGYyvgVkx0%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;1205&quot; height=&quot;202&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;3025&quot; data-start=&quot;2971&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트가 단순 일정 서비스가 아니라&lt;br /&gt;추천 중심 서비스라는 점을 다시 정리하는 마무리 섹션&lt;/p&gt;
&lt;p data-end=&quot;3060&quot; data-start=&quot;3027&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 정리하고 나니&lt;br /&gt;페이지 역할이 훨씬 분명해졌습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3065&quot; data-start=&quot;3062&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3087&quot; data-start=&quot;3067&quot; data-section-id=&quot;onelbw&quot; data-ke-size=&quot;size26&quot;&gt;6. 이번 작업의 핵심 포인트&lt;/h2&gt;
&lt;h3 data-end=&quot;3118&quot; data-start=&quot;3089&quot; data-section-id=&quot;kdjvtb&quot; data-ke-size=&quot;size23&quot;&gt;1) 설명문을 줄이고 구조를 먼저 보이게 했다&lt;/h3&gt;
&lt;p data-end=&quot;3187&quot; data-start=&quot;3119&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지에서 가장 중요했던 것은&lt;br /&gt;정보를 많이 넣는 것이 아니라&lt;br /&gt;&lt;b&gt;한눈에 이해되는 구조를 만드는 것&lt;/b&gt;이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;3210&quot; data-start=&quot;3189&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 긴 문단으로 설명하는 것보다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3254&quot; data-start=&quot;3212&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3222&quot; data-start=&quot;3212&quot; data-section-id=&quot;jtdapy&quot;&gt;핵심 요소 3개&lt;/li&gt;
&lt;li data-end=&quot;3230&quot; data-start=&quot;3223&quot; data-section-id=&quot;1sejdji&quot;&gt;짧은 설명&lt;/li&gt;
&lt;li data-end=&quot;3238&quot; data-start=&quot;3231&quot; data-section-id=&quot;6mz6xx&quot;&gt;반영 예시&lt;/li&gt;
&lt;li data-end=&quot;3246&quot; data-start=&quot;3239&quot; data-section-id=&quot;mq5bdg&quot;&gt;샘플 점수&lt;/li&gt;
&lt;li data-end=&quot;3254&quot; data-start=&quot;3247&quot; data-section-id=&quot;1nxoa5t&quot;&gt;해석 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3282&quot; data-start=&quot;3256&quot; data-ke-size=&quot;size16&quot;&gt;처럼 나눠 보여주는 방식이 더 효과적이었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3287&quot; data-start=&quot;3284&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3313&quot; data-start=&quot;3289&quot; data-section-id=&quot;aekcu6&quot; data-ke-size=&quot;size23&quot;&gt;2) 점수는 숫자보다 해석이 중요했다&lt;/h3&gt;
&lt;p data-end=&quot;3378&quot; data-start=&quot;3314&quot; data-ke-size=&quot;size16&quot;&gt;점수 자체를 붙이는 것은 어렵지 않지만,&lt;br /&gt;그 점수를 사용자가 이해하고 받아들이게 만드는 것은 다른 문제였습니다.&lt;/p&gt;
&lt;p data-end=&quot;3378&quot; data-start=&quot;3314&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3412&quot; data-start=&quot;3380&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번 작업은&lt;br /&gt;단순히 UI를 추가한 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;3441&quot; data-start=&quot;3414&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 로직을 사용자 관점에서 설명하는 작업&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3454&quot; data-start=&quot;3443&quot; data-ke-size=&quot;size16&quot;&gt;에 더 가까웠습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3459&quot; data-start=&quot;3456&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3487&quot; data-start=&quot;3461&quot; data-section-id=&quot;2rmand&quot; data-ke-size=&quot;size23&quot;&gt;3) 프로젝트 성격이 드러나도록 정리했다&lt;/h3&gt;
&lt;p data-end=&quot;3566&quot; data-start=&quot;3488&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지는 설명용 페이지이지만,&lt;br /&gt;프로젝트 전체 흐름 안에서 보면&lt;br /&gt;서비스의 핵심 개념을 가장 직접적으로 보여주는 페이지이기도 합니다.&lt;/p&gt;
&lt;p data-end=&quot;3566&quot; data-start=&quot;3488&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3639&quot; data-start=&quot;3568&quot; data-ke-size=&quot;size16&quot;&gt;그래서 일반적인 문서형 페이지보다는&lt;br /&gt;NBA 프로젝트 안에 들어 있는 페이지처럼 보이도록&lt;br /&gt;색감과 구조도 함께 정리했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3644&quot; data-start=&quot;3641&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3662&quot; data-start=&quot;3646&quot; data-section-id=&quot;emj204&quot; data-ke-size=&quot;size26&quot;&gt;7. 구현 과정에서 느낀 점&lt;/h2&gt;
&lt;h3 data-end=&quot;3696&quot; data-start=&quot;3664&quot; data-section-id=&quot;19d98v6&quot; data-ke-size=&quot;size23&quot;&gt;1) 추천 서비스는 설명 가능한 구조가 있어야 한다&lt;/h3&gt;
&lt;p data-end=&quot;3761&quot; data-start=&quot;3697&quot; data-ke-size=&quot;size16&quot;&gt;홈에서 추천 경기를 보여주고,&lt;br /&gt;상세 페이지에서 추천 이유를 보여주는 것도 중요하지만,&lt;br /&gt;그보다 더 중요한 것은&lt;/p&gt;
&lt;p data-end=&quot;3789&quot; data-start=&quot;3763&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 추천 기준을 별도로 설명할 수 있느냐&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3796&quot; data-start=&quot;3791&quot; data-ke-size=&quot;size16&quot;&gt;였습니다.&lt;/p&gt;
&lt;p data-end=&quot;3796&quot; data-start=&quot;3791&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3877&quot; data-start=&quot;3798&quot; data-ke-size=&quot;size16&quot;&gt;/about-score 페이지를 만들고 나니&lt;br /&gt;프로젝트가 단순한 UI 중심이 아니라&lt;br /&gt;추천 기준을 가진 서비스처럼 보이기 시작했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3882&quot; data-start=&quot;3879&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3918&quot; data-start=&quot;3884&quot; data-section-id=&quot;17ccniq&quot; data-ke-size=&quot;size23&quot;&gt;2) 설명 페이지가 프로젝트 흐름을 더 또렷하게 만든다&lt;/h3&gt;
&lt;p data-end=&quot;3981&quot; data-start=&quot;3919&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이 페이지가 꼭 필요할까 싶었지만,&lt;br /&gt;실제로 만들고 나니 프로젝트의 핵심 컨셉이 훨씬 분명해졌습니다.&lt;/p&gt;
&lt;p data-end=&quot;3981&quot; data-start=&quot;3919&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4014&quot; data-start=&quot;3983&quot; data-ke-size=&quot;size16&quot;&gt;홈과 상세 페이지는&lt;br /&gt;&amp;ldquo;무엇을 추천하는지&amp;rdquo;를 보여주고,&lt;/p&gt;
&lt;p data-end=&quot;4067&quot; data-start=&quot;4016&quot; data-ke-size=&quot;size16&quot;&gt;/about-score는&lt;br /&gt;&amp;ldquo;왜 이렇게 추천하는지&amp;rdquo;를 설명하는 역할을 하게 되었습니다.&lt;/p&gt;
&lt;p data-end=&quot;4067&quot; data-start=&quot;4016&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4113&quot; data-start=&quot;4069&quot; data-ke-size=&quot;size16&quot;&gt;즉 이 페이지가 추가되면서&lt;br /&gt;프로젝트 전체 흐름이 더 명확해졌다고 느꼈습니다.&lt;/p&gt;
&lt;hr data-end=&quot;4118&quot; data-start=&quot;4115&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4134&quot; data-start=&quot;4120&quot; data-section-id=&quot;1rpxc57&quot; data-ke-size=&quot;size26&quot;&gt;8. 현재까지의 프로젝트 흐름&lt;/h2&gt;
&lt;p data-end=&quot;4158&quot; data-start=&quot;4136&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 정리된 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;4167&quot; data-start=&quot;4160&quot; data-section-id=&quot;1xwnzx7&quot; data-ke-size=&quot;size23&quot;&gt;1단계&lt;/h3&gt;
&lt;p data-end=&quot;4186&quot; data-start=&quot;4168&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 기획과 서비스 방향 정리&lt;/p&gt;
&lt;h3 data-end=&quot;4195&quot; data-start=&quot;4188&quot; data-section-id=&quot;1xwo3vc&quot; data-ke-size=&quot;size23&quot;&gt;2단계&lt;/h3&gt;
&lt;p data-end=&quot;4212&quot; data-start=&quot;4196&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면 구조와 컴포넌트 분리&lt;/p&gt;
&lt;h3 data-end=&quot;4221&quot; data-start=&quot;4214&quot; data-section-id=&quot;1xwnyc9&quot; data-ke-size=&quot;size23&quot;&gt;3단계&lt;/h3&gt;
&lt;p data-end=&quot;4238&quot; data-start=&quot;4222&quot; data-ke-size=&quot;size16&quot;&gt;경기 목록과 상세 페이지 설계&lt;/p&gt;
&lt;h3 data-end=&quot;4247&quot; data-start=&quot;4240&quot; data-section-id=&quot;1xwnqu6&quot; data-ke-size=&quot;size23&quot;&gt;4단계&lt;/h3&gt;
&lt;p data-end=&quot;4276&quot; data-start=&quot;4248&quot; data-ke-size=&quot;size16&quot;&gt;Watchability Score 설명 페이지 구성&lt;/p&gt;
&lt;p data-end=&quot;4307&quot; data-start=&quot;4278&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이제는 단순히 홈 화면이 있는 프로젝트가 아니라&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4330&quot; data-start=&quot;4309&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4312&quot; data-start=&quot;4309&quot; data-section-id=&quot;3752ao&quot;&gt;홈&lt;/li&gt;
&lt;li data-end=&quot;4317&quot; data-start=&quot;4313&quot; data-section-id=&quot;yhylbw&quot;&gt;목록&lt;/li&gt;
&lt;li data-end=&quot;4322&quot; data-start=&quot;4318&quot; data-section-id=&quot;yiluwh&quot;&gt;상세&lt;/li&gt;
&lt;li data-end=&quot;4330&quot; data-start=&quot;4323&quot; data-section-id=&quot;1ftl5lt&quot;&gt;점수 설명&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4357&quot; data-start=&quot;4332&quot; data-ke-size=&quot;size16&quot;&gt;까지 이어지는 기본 구조가 갖춰진 상태입니다.&lt;/p&gt;
&lt;hr data-end=&quot;4362&quot; data-start=&quot;4359&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4375&quot; data-start=&quot;4364&quot; data-section-id=&quot;vmwh5i&quot; data-ke-size=&quot;size26&quot;&gt;9. 다음 단계&lt;/h2&gt;
&lt;p data-end=&quot;4389&quot; data-start=&quot;4377&quot; data-ke-size=&quot;size16&quot;&gt;현재까지는 추천 점수를&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4433&quot; data-start=&quot;4391&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4401&quot; data-start=&quot;4391&quot; data-section-id=&quot;lz3g5k&quot;&gt;홈에서 보여주고&lt;/li&gt;
&lt;li data-end=&quot;4413&quot; data-start=&quot;4402&quot; data-section-id=&quot;14d51ps&quot;&gt;상세에서 활용하고&lt;/li&gt;
&lt;li data-end=&quot;4433&quot; data-start=&quot;4414&quot; data-section-id=&quot;14wo5uk&quot;&gt;설명 페이지에서 해석할 수 있게&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4445&quot; data-start=&quot;4435&quot; data-ke-size=&quot;size16&quot;&gt;정리한 상태입니다.&lt;/p&gt;
&lt;p data-end=&quot;4455&quot; data-start=&quot;4447&quot; data-ke-size=&quot;size16&quot;&gt;다음 단계에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4547&quot; data-start=&quot;4457&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4472&quot; data-start=&quot;4457&quot; data-section-id=&quot;q9tcvt&quot;&gt;상세 페이지 데이터 확장&lt;/li&gt;
&lt;li data-end=&quot;4487&quot; data-start=&quot;4473&quot; data-section-id=&quot;b7g5zu&quot;&gt;favorites 기능&lt;/li&gt;
&lt;li data-end=&quot;4501&quot; data-start=&quot;4488&quot; data-section-id=&quot;xjb4os&quot;&gt;상태 관리 구조 정리&lt;/li&gt;
&lt;li data-end=&quot;4516&quot; data-start=&quot;4502&quot; data-section-id=&quot;13fzawc&quot;&gt;실제 API 연결 준비&lt;/li&gt;
&lt;li data-end=&quot;4547&quot; data-start=&quot;4517&quot; data-section-id=&quot;1y4z8uq&quot;&gt;Watchability Score 계산 로직 고도화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4564&quot; data-start=&quot;4549&quot; data-ke-size=&quot;size16&quot;&gt;등으로 확장해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;4647&quot; data-start=&quot;4566&quot; data-ke-size=&quot;size16&quot;&gt;특히 다음부터는&lt;br /&gt;점수를 &amp;ldquo;보여주는 단계&amp;rdquo;를 넘어서,&lt;br /&gt;점수 계산에 들어가는 데이터 구조를 더 구체적으로 정리하는 것이 중요하다고 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;4652&quot; data-start=&quot;4649&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4664&quot; data-start=&quot;4654&quot; data-section-id=&quot;3njy8q&quot; data-ke-size=&quot;size26&quot;&gt;10. Watchability Score 페이지를 만들며 느낀 점&lt;/h2&gt;
&lt;p data-end=&quot;4743&quot; data-start=&quot;4666&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업을 통해 느낀 점은&lt;br /&gt;추천 서비스에서 점수는 단순 숫자가 아니라&lt;br /&gt;&lt;b&gt;사용자의 선택을 돕는 기준&lt;/b&gt;이어야 한다는 것이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;4743&quot; data-start=&quot;4666&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4828&quot; data-start=&quot;4745&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 기준이 제대로 전달되려면&lt;br /&gt;점수를 보여주는 것만으로는 부족하고,&lt;br /&gt;그 점수를 &lt;b&gt;설명할 수 있는 구조&lt;/b&gt;가 필요하다는 것도 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;4828&quot; data-start=&quot;4745&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4917&quot; data-start=&quot;4830&quot; data-ke-size=&quot;size16&quot;&gt;/about-score 페이지는&lt;br /&gt;그런 의미에서 프로젝트의 보조 페이지이면서도,&lt;br /&gt;프로젝트 핵심 개념을 가장 분명하게 보여주는 페이지라고 생각합니다.&lt;/p&gt;
&lt;p data-end=&quot;4917&quot; data-start=&quot;4830&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4994&quot; data-start=&quot;4919&quot; data-ke-size=&quot;size16&quot;&gt;다음 글에서는&lt;br /&gt;상세 페이지 데이터를 더 확장하고,&lt;br /&gt;추천 경기의 설득력을 높이기 위해 어떤 정보를 추가했는지 정리해보려고 합니다.&lt;/p&gt;</description>
      <category>프로젝트 회고록</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/19</guid>
      <comments>https://dlsxo.tistory.com/19#entry19comment</comments>
      <pubDate>Mon, 18 May 2026 18:32:45 +0900</pubDate>
    </item>
    <item>
      <title>사이드 프로젝트 | NBA Game Picker (3) - 경기 목록과 상세 페이지 설계</title>
      <link>https://dlsxo.tistory.com/18</link>
      <description>&lt;div data-turn-start-message=&quot;true&quot; data-message-model-slug=&quot;gpt-5-4-thinking&quot; data-message-id=&quot;221a3d75-45e1-4e9c-a14e-5aa0603affb4&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;225&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;225&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;294&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;지난 글에서는&lt;br /&gt;NBA Game Picker 프로젝트를 왜 만들었고,&lt;br /&gt;어떤 방향으로 설계했는지 정리했고,&lt;/p&gt;
&lt;p data-end=&quot;294&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;338&quot; data-start=&quot;296&quot; data-ke-size=&quot;size16&quot;&gt;이후에는&lt;br /&gt;홈 화면을 어떻게 구조화하고 컴포넌트로 분리했는지 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;338&quot; data-start=&quot;296&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;359&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 그다음 단계로 진행한&lt;/p&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;361&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;경기 목록 페이지(/games)와 경기 상세 페이지(/games/[gameId]) 구현 과정&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;435&quot; data-start=&quot;422&quot; data-ke-size=&quot;size16&quot;&gt;을 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;435&quot; data-start=&quot;422&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;487&quot; data-start=&quot;437&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면이 오늘 볼 만한 경기를 빠르게 보여주는 역할이었다면,&lt;br /&gt;이번에 만든 두 페이지는&lt;/p&gt;
&lt;p data-end=&quot;487&quot; data-start=&quot;437&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;508&quot; data-start=&quot;489&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 &amp;rarr; 비교 &amp;rarr; 상세 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;534&quot; data-start=&quot;510&quot; data-ke-size=&quot;size16&quot;&gt;으로 이어지는 흐름을 만드는 작업이었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;539&quot; data-start=&quot;536&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;562&quot; data-start=&quot;541&quot; data-section-id=&quot;4p7azt&quot; data-ke-size=&quot;size26&quot;&gt;1. 홈 화면 다음에 필요했던 것&lt;/h2&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;887&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xNMgv/dJMcadWc856/uNk6yeYRQ4sk2uQDXNAiRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xNMgv/dJMcadWc856/uNk6yeYRQ4sk2uQDXNAiRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xNMgv/dJMcadWc856/uNk6yeYRQ4sk2uQDXNAiRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxNMgv%2FdJMcadWc856%2FuNk6yeYRQ4sk2uQDXNAiRK%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;1211&quot; height=&quot;887&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;887&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;638&quot; data-start=&quot;564&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면만 있을 때도&lt;br /&gt;오늘 경기, 추천 경기, 팀 순위, 득점 리더처럼&lt;br /&gt;핵심 정보는 어느 정도 한 화면에서 볼 수 있었습니다.&lt;/p&gt;
&lt;p data-end=&quot;638&quot; data-start=&quot;564&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;684&quot; data-start=&quot;640&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제로 서비스를 사용한다고 생각해보면&lt;br /&gt;아쉬운 점이 분명히 있었습니다.&lt;/p&gt;
&lt;p data-end=&quot;684&quot; data-start=&quot;640&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;701&quot; data-start=&quot;686&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 이런 흐름입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;814&quot; data-start=&quot;703&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;731&quot; data-start=&quot;703&quot; data-section-id=&quot;12s4r67&quot;&gt;오늘 경기가 여러 개 있을 때 전체를 보고 싶다&lt;/li&gt;
&lt;li data-end=&quot;760&quot; data-start=&quot;732&quot; data-section-id=&quot;1worbtd&quot;&gt;추천 점수가 높은 경기들을 빠르게 비교하고 싶다&lt;/li&gt;
&lt;li data-end=&quot;784&quot; data-start=&quot;761&quot; data-section-id=&quot;vk7s3r&quot;&gt;특정 경기 하나를 더 자세히 보고 싶다&lt;/li&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;785&quot; data-section-id=&quot;qh0rlz&quot;&gt;왜 이 경기가 추천 경기인지 근거를 확인하고 싶다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;884&quot; data-start=&quot;816&quot; data-ke-size=&quot;size16&quot;&gt;즉, 홈 화면은 &lt;b&gt;요약과 진입 역할&lt;/b&gt;에는 적합했지만&lt;br /&gt;전체를 비교하거나 하나를 깊게 확인하는 흐름까지는 부족했습니다.&lt;/p&gt;
&lt;p data-end=&quot;884&quot; data-start=&quot;816&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;896&quot; data-start=&quot;886&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다음 단계로&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;950&quot; data-start=&quot;898&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;919&quot; data-start=&quot;898&quot; data-section-id=&quot;ss1nxd&quot;&gt;/games &amp;rarr; 전체 경기 목록&lt;/li&gt;
&lt;li data-end=&quot;950&quot; data-start=&quot;920&quot; data-section-id=&quot;1k4wdpz&quot;&gt;/games/[gameId] &amp;rarr; 경기 상세 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;972&quot; data-start=&quot;952&quot; data-ke-size=&quot;size16&quot;&gt;이 두 페이지를 추가하게 되었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;977&quot; data-start=&quot;974&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;997&quot; data-start=&quot;979&quot; data-section-id=&quot;1l10v4o&quot; data-ke-size=&quot;size26&quot;&gt;2. 각 페이지의 역할 정리&lt;/h2&gt;
&lt;p data-end=&quot;1041&quot; data-start=&quot;999&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업에서는 먼저&lt;br /&gt;각 페이지가 어떤 역할을 가지는지부터 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1041&quot; data-start=&quot;999&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1054&quot; data-start=&quot;1043&quot; data-section-id=&quot;o66xq8&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;홈 (/)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1078&quot; data-start=&quot;1055&quot; data-ke-size=&quot;size16&quot;&gt;오늘 가장 볼 만한 경기와 핵심 정보 요약&lt;/p&gt;
&lt;h3 data-end=&quot;1100&quot; data-start=&quot;1080&quot; data-section-id=&quot;kjjyj0&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;경기 목록 (/games)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1128&quot; data-start=&quot;1101&quot; data-ke-size=&quot;size16&quot;&gt;오늘 경기 전체를 추천 점수 기준으로 빠르게 비교&lt;/p&gt;
&lt;h3 data-end=&quot;1159&quot; data-start=&quot;1130&quot; data-section-id=&quot;crymvf&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;경기 상세 (/games/[gameId])&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1185&quot; data-start=&quot;1160&quot; data-ke-size=&quot;size16&quot;&gt;선택한 경기를 왜 봐야 하는지 더 자세히 설명&lt;/p&gt;
&lt;p data-end=&quot;1234&quot; data-start=&quot;1187&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 나누고 나니&lt;br /&gt;페이지마다 어떤 정보를 보여줘야 하는지 기준이 분명해졌습니다.&lt;/p&gt;
&lt;p data-end=&quot;1234&quot; data-start=&quot;1187&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1275&quot; data-start=&quot;1236&quot; data-ke-size=&quot;size16&quot;&gt;특히 상세 페이지는&lt;br /&gt;단순히 경기 정보를 다시 보여주는 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;1275&quot; data-start=&quot;1236&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1300&quot; data-start=&quot;1277&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;추천의 근거를 납득시키는 페이지&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1319&quot; data-start=&quot;1302&quot; data-ke-size=&quot;size16&quot;&gt;가 되어야 한다고 생각했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1324&quot; data-start=&quot;1321&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1349&quot; data-start=&quot;1326&quot; data-section-id=&quot;1h7hoh3&quot; data-ke-size=&quot;size26&quot;&gt;3. 경기 목록 페이지에서 정리한 것&lt;/h2&gt;
&lt;p data-end=&quot;1408&quot; data-start=&quot;1351&quot; data-ke-size=&quot;size16&quot;&gt;/games 페이지는&lt;br /&gt;그냥 홈 화면의 리스트를 크게 늘려놓는 느낌으로 만들고 싶지는 않았습니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clJffg/dJMcadBRkyW/EjDSObsMK0IXbSQVf6aKrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clJffg/dJMcadBRkyW/EjDSObsMK0IXbSQVf6aKrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clJffg/dJMcadBRkyW/EjDSObsMK0IXbSQVf6aKrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclJffg%2FdJMcadBRkyW%2FEjDSObsMK0IXbSQVf6aKrK%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;1127&quot; height=&quot;327&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;327&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;1427&quot; data-start=&quot;1410&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지에서 중요하게 본 것은&lt;/p&gt;
&lt;p data-end=&quot;1461&quot; data-start=&quot;1429&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체 경기를 빠르게 훑고 우선순위를 정할 수 있느냐&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1468&quot; data-start=&quot;1463&quot; data-ke-size=&quot;size16&quot;&gt;였습니다.&lt;/p&gt;
&lt;p data-end=&quot;1468&quot; data-start=&quot;1463&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1506&quot; data-start=&quot;1470&quot; data-ke-size=&quot;size16&quot;&gt;그래서 목록 페이지에서는 아래 정보가 바로 보이도록 구성했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1544&quot; data-start=&quot;1508&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1515&quot; data-start=&quot;1508&quot; data-section-id=&quot;hpd4m5&quot;&gt;경기 시간&lt;/li&gt;
&lt;li data-end=&quot;1523&quot; data-start=&quot;1516&quot; data-section-id=&quot;1l6yk8h&quot;&gt;팀 매치업&lt;/li&gt;
&lt;li data-end=&quot;1544&quot; data-start=&quot;1524&quot; data-section-id=&quot;1q97jsb&quot;&gt;Watchability Score&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1630&quot; data-start=&quot;1546&quot; data-ke-size=&quot;size16&quot;&gt;목록 페이지의 목적은&lt;br /&gt;깊게 읽는 것이 아니라 &lt;b&gt;빠르게 비교하는 것&lt;/b&gt;이기 때문에,&lt;br /&gt;정보량을 과하게 넣기보다 핵심만 먼저 보이도록 설계했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1630&quot; data-start=&quot;1546&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1695&quot; data-start=&quot;1632&quot; data-ke-size=&quot;size16&quot;&gt;또 홈에서 사용하던 경기 데이터 구조를 그대로 재사용하면서&lt;br /&gt;홈 &amp;rarr; 목록 흐름도 자연스럽게 이어지도록 했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1695&quot; data-start=&quot;1632&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1764&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size16&quot;&gt;즉, 홈에서는 일부 경기만 요약해서 보여주고&lt;br /&gt;/games에서는 그 데이터를 전체 목록 형태로 확장하는 방식입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1769&quot; data-start=&quot;1766&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1796&quot; data-start=&quot;1771&quot; data-section-id=&quot;b1e5fe&quot; data-ke-size=&quot;size26&quot;&gt;4. 경기 상세 페이지에서 중요했던 부분&lt;/h2&gt;
&lt;p data-end=&quot;1826&quot; data-start=&quot;1798&quot; data-ke-size=&quot;size16&quot;&gt;상세 페이지는 목록보다 더 중요하다고 생각했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1826&quot; data-start=&quot;1798&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1905&quot; data-start=&quot;1828&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 핵심은&lt;br /&gt;단순히 경기 정보를 보여주는 것이 아니라&lt;br /&gt;**&amp;ldquo;오늘 어떤 경기를 보면 좋을지 추천하는 것&amp;rdquo;**이기 때문입니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEM67h/dJMcaipIYHJ/qXiq57aQX2CsrD9ATwUKLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEM67h/dJMcaipIYHJ/qXiq57aQX2CsrD9ATwUKLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEM67h/dJMcaipIYHJ/qXiq57aQX2CsrD9ATwUKLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEM67h%2FdJMcaipIYHJ%2FqXiq57aQX2CsrD9ATwUKLk%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;505&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-end=&quot;1978&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1978&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;그래서 상세 페이지에서는&lt;br /&gt;경기 시간이나 팀 이름만 보여주는 것이 아니라&lt;br /&gt;추천 근거를 설명할 수 있는 정보가 필요했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1978&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2009&quot; data-start=&quot;1980&quot; data-ke-size=&quot;size16&quot;&gt;현재 상세 페이지에는 다음과 같은 내용을 넣었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2108&quot; data-start=&quot;2011&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2018&quot; data-start=&quot;2011&quot; data-section-id=&quot;hpd4m5&quot;&gt;경기 시간&lt;/li&gt;
&lt;li data-end=&quot;2034&quot; data-start=&quot;2019&quot; data-section-id=&quot;por9d2&quot;&gt;away / home 팀&lt;/li&gt;
&lt;li data-end=&quot;2055&quot; data-start=&quot;2035&quot; data-section-id=&quot;1q97jsb&quot;&gt;Watchability Score&lt;/li&gt;
&lt;li data-end=&quot;2063&quot; data-start=&quot;2056&quot; data-section-id=&quot;17e79w4&quot;&gt;추천 이유&lt;/li&gt;
&lt;li data-end=&quot;2075&quot; data-start=&quot;2064&quot; data-section-id=&quot;iaxlac&quot;&gt;최근 5경기 비교&lt;/li&gt;
&lt;li data-end=&quot;2083&quot; data-start=&quot;2076&quot; data-section-id=&quot;wwd4lo&quot;&gt;평균 득점&lt;/li&gt;
&lt;li data-end=&quot;2091&quot; data-start=&quot;2084&quot; data-section-id=&quot;www9g5&quot;&gt;평균 실점&lt;/li&gt;
&lt;li data-end=&quot;2099&quot; data-start=&quot;2092&quot; data-section-id=&quot;ud8x29&quot;&gt;시즌 승률&lt;/li&gt;
&lt;li data-end=&quot;2108&quot; data-start=&quot;2100&quot; data-section-id=&quot;1avd2yu&quot;&gt;최근 맞대결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2145&quot; data-start=&quot;2110&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이 페이지는&lt;br /&gt;&amp;ldquo;경기 정보를 보여주는 화면&amp;rdquo;이면서 동시에&lt;/p&gt;
&lt;p data-end=&quot;2145&quot; data-start=&quot;2110&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2174&quot; data-start=&quot;2147&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;왜 이 경기가 추천되는지 설명하는 화면&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2176&quot; data-ke-size=&quot;size16&quot;&gt;이 되도록 구성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2176&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2224&quot; data-start=&quot;2191&quot; data-ke-size=&quot;size16&quot;&gt;홈에서 사용자가 가질 수 있는 질문은 보통 이런 형태입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2304&quot; data-start=&quot;2226&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2243&quot; data-start=&quot;2226&quot; data-section-id=&quot;1ssbm94&quot;&gt;왜 이 경기가 높은 점수지?&lt;/li&gt;
&lt;li data-end=&quot;2267&quot; data-start=&quot;2244&quot; data-section-id=&quot;1y8iapa&quot;&gt;단순히 인기 팀 경기라서 추천된 건가?&lt;/li&gt;
&lt;li data-end=&quot;2286&quot; data-start=&quot;2268&quot; data-section-id=&quot;2urx10&quot;&gt;실제로 접전 가능성이 높은가?&lt;/li&gt;
&lt;li data-end=&quot;2304&quot; data-start=&quot;2287&quot; data-section-id=&quot;c88q2o&quot;&gt;최근 흐름이 좋은 팀들인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2339&quot; data-start=&quot;2306&quot; data-ke-size=&quot;size16&quot;&gt;상세 페이지는 이런 질문에 답해주는 구조를 목표로 했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2344&quot; data-start=&quot;2341&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2372&quot; data-start=&quot;2346&quot; data-section-id=&quot;1qq62y4&quot; data-ke-size=&quot;size26&quot;&gt;5. App Router 기준으로 연결하기&lt;/h2&gt;
&lt;p data-end=&quot;2450&quot; data-start=&quot;2374&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업에서 기술적으로 가장 중요했던 부분 중 하나는&lt;br /&gt;Next.js App Router 기준으로 라우팅 구조를 정리한 것이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;2450&quot; data-start=&quot;2374&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2472&quot; data-start=&quot;2452&quot; data-ke-size=&quot;size16&quot;&gt;현재 페이지 구조는 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1777368882560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src/app
├─page.tsx
└─games
├─page.tsx
└─[gameId]
└─page.tsx&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2558&quot; data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2655&quot; data-start=&quot;2563&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2600&quot; data-start=&quot;2563&quot; data-section-id=&quot;my4yj&quot;&gt;src/app/games/page.tsx &amp;rarr; /games&lt;/li&gt;
&lt;li data-end=&quot;2655&quot; data-start=&quot;2601&quot; data-section-id=&quot;sfgav&quot;&gt;src/app/games/[gameId]/page.tsx &amp;rarr; /games/:gameId&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2665&quot; data-start=&quot;2657&quot; data-ke-size=&quot;size16&quot;&gt;역할을 합니다.&lt;/p&gt;
&lt;p data-end=&quot;2665&quot; data-start=&quot;2657&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2742&quot; data-start=&quot;2667&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 [gameId] 폴더를 사용하는 방식이 조금 낯설었지만,&lt;br /&gt;정리하고 나니 오히려 페이지 역할이 더 명확하게 느껴졌습니다.&lt;/p&gt;
&lt;p data-end=&quot;2742&quot; data-start=&quot;2667&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2814&quot; data-start=&quot;2744&quot; data-ke-size=&quot;size16&quot;&gt;특히 gameId를 기준으로 상세 데이터를 연결하는 흐름이 생기면서&lt;br /&gt;목록 &amp;rarr; 상세 이동 구조가 자연스럽게 이어졌습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2819&quot; data-start=&quot;2816&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2852&quot; data-start=&quot;2821&quot; data-section-id=&quot;cr32wb&quot; data-ke-size=&quot;size26&quot;&gt;6. 상세 데이터는 mock 기반으로 구성&lt;/h2&gt;
&lt;p data-end=&quot;2913&quot; data-start=&quot;2854&quot; data-ke-size=&quot;size16&quot;&gt;현재 단계에서는 아직 실제 API를 연결하지 않고&lt;br /&gt;mock 데이터 기반으로 상세 페이지를 구성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;2913&quot; data-start=&quot;2854&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2936&quot; data-start=&quot;2915&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 진행한 이유는 이전과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3026&quot; data-start=&quot;2938&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2955&quot; data-start=&quot;2938&quot; data-section-id=&quot;i1l6ll&quot;&gt;UI 구조를 먼저 잡기 위해&lt;/li&gt;
&lt;li data-end=&quot;2990&quot; data-start=&quot;2956&quot; data-section-id=&quot;f9x9ac&quot;&gt;상세 페이지에서 어떤 데이터가 필요한지 먼저 정리하기 위해&lt;/li&gt;
&lt;li data-end=&quot;3026&quot; data-start=&quot;2991&quot; data-section-id=&quot;zc0wko&quot;&gt;실제 API 형태와 무관하게 화면 흐름을 먼저 검증하기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3070&quot; data-start=&quot;3028&quot; data-ke-size=&quot;size16&quot;&gt;현재는 gameDetailMap 형태로 상세 데이터를 관리하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;3070&quot; data-start=&quot;3028&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3077&quot; data-start=&quot;3072&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3116&quot; data-start=&quot;3079&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3098&quot; data-start=&quot;3079&quot; data-section-id=&quot;1ff5i5y&quot;&gt;lakers-warriors&lt;/li&gt;
&lt;li data-end=&quot;3116&quot; data-start=&quot;3099&quot; data-section-id=&quot;c0ezou&quot;&gt;celtics-bucks&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3160&quot; data-start=&quot;3118&quot; data-ke-size=&quot;size16&quot;&gt;같은 경기 id를 기준으로&lt;br /&gt;각 경기의 상세 데이터를 연결하는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;3160&quot; data-start=&quot;3118&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3176&quot; data-start=&quot;3162&quot; data-ke-size=&quot;size16&quot;&gt;이 과정에서 중요했던 점은&lt;/p&gt;
&lt;p data-end=&quot;3219&quot; data-start=&quot;3178&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;홈 데이터, 목록 데이터, 상세 데이터의 id를 일관되게 맞추는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3227&quot; data-start=&quot;3221&quot; data-ke-size=&quot;size16&quot;&gt;이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;3227&quot; data-start=&quot;3221&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3302&quot; data-start=&quot;3229&quot; data-ke-size=&quot;size16&quot;&gt;이 부분이 정리되자&lt;br /&gt;홈에서 누른 경기 카드와 목록에서 누른 경기 카드가&lt;br /&gt;같은 상세 페이지로 자연스럽게 연결될 수 있었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3307&quot; data-start=&quot;3304&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3325&quot; data-start=&quot;3309&quot; data-section-id=&quot;emj204&quot; data-ke-size=&quot;size26&quot;&gt;7. 구현하면서 느낀 점&lt;/h2&gt;
&lt;h3 data-end=&quot;3357&quot; data-start=&quot;3327&quot; data-section-id=&quot;943762&quot; data-ke-size=&quot;size23&quot;&gt;1) 목록 페이지와 상세 페이지는 역할이 다르다&lt;/h3&gt;
&lt;p data-end=&quot;3419&quot; data-start=&quot;3359&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 둘 다 경기 데이터를 보여주는 페이지라고 생각했지만,&lt;br /&gt;직접 만들어보니 성격이 확실히 달랐습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3458&quot; data-start=&quot;3421&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3438&quot; data-start=&quot;3421&quot; data-section-id=&quot;1sjfe6m&quot;&gt;목록 페이지 &amp;rarr; 빠르게 비교&lt;/li&gt;
&lt;li data-end=&quot;3458&quot; data-start=&quot;3439&quot; data-section-id=&quot;1p26dka&quot;&gt;상세 페이지 &amp;rarr; 추천 근거 설명&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3510&quot; data-start=&quot;3460&quot; data-ke-size=&quot;size16&quot;&gt;즉, 같은 데이터라도&lt;br /&gt;어떤 페이지에서 보여주느냐에 따라 배치 방식이 달라져야 했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3515&quot; data-start=&quot;3512&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3544&quot; data-start=&quot;3517&quot; data-section-id=&quot;1jgexjl&quot; data-ke-size=&quot;size23&quot;&gt;2) 추천 근거를 설명하는 상세 화면&lt;/h3&gt;
&lt;p data-end=&quot;3597&quot; data-start=&quot;3546&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면에서 추천 경기를 강조하는 것만으로는&lt;br /&gt;추천 서비스라고 말하기 어렵다고 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;3597&quot; data-start=&quot;3546&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3644&quot; data-start=&quot;3599&quot; data-ke-size=&quot;size16&quot;&gt;진짜 중요한 것은&lt;/p&gt;
&lt;p data-end=&quot;3644&quot; data-start=&quot;3599&quot; data-ke-size=&quot;size16&quot;&gt;상세 페이지에서 그 추천을 &lt;b&gt;어떻게 설명하느냐&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;p data-end=&quot;3644&quot; data-start=&quot;3599&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3678&quot; data-start=&quot;3646&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번 작업은&lt;br /&gt;단순히 페이지를 추가한 것이 아니라&lt;/p&gt;
&lt;p data-end=&quot;3711&quot; data-start=&quot;3680&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 중심 서비스 구조를 한 단계 더 확장한 작업&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3723&quot; data-start=&quot;3713&quot; data-ke-size=&quot;size16&quot;&gt;이라고 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;3728&quot; data-start=&quot;3725&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3761&quot; data-start=&quot;3730&quot; data-section-id=&quot;12e5246&quot; data-ke-size=&quot;size23&quot;&gt;3) 목록과 상세를 연결하는 id 기준&lt;/h3&gt;
&lt;p data-end=&quot;3813&quot; data-start=&quot;3763&quot; data-ke-size=&quot;size16&quot;&gt;지금은 아직 실제 API를 연결한 단계가 아니라서,&lt;br /&gt;복잡한 식별자 체계를 만드는 것보다&lt;/p&gt;
&lt;p data-end=&quot;3813&quot; data-start=&quot;3763&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3844&quot; data-start=&quot;3815&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서로 연결되는 데이터끼리 id를 일치시키는 &lt;/b&gt;&lt;b&gt;것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3858&quot; data-start=&quot;3846&quot; data-ke-size=&quot;size16&quot;&gt;이 훨씬 중요했습니다.&lt;/p&gt;
&lt;p data-end=&quot;3858&quot; data-start=&quot;3846&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3945&quot; data-start=&quot;3860&quot; data-ke-size=&quot;size16&quot;&gt;현재는 간단한 문자열 id를 사용하고 있지만,&lt;br /&gt;이후 실제 API를 연결하게 되면&lt;br /&gt;외부 경기 id를 기준으로 더 안정적인 구조로 확장할 계획입니다.&lt;/p&gt;
&lt;hr data-end=&quot;3950&quot; data-start=&quot;3947&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3966&quot; data-start=&quot;3952&quot; data-section-id=&quot;1rpxc57&quot; data-ke-size=&quot;size26&quot;&gt;8. 현재까지의 흐름&lt;/h2&gt;
&lt;p data-end=&quot;3990&quot; data-start=&quot;3968&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 정리된 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;3999&quot; data-start=&quot;3992&quot; data-section-id=&quot;1xwnzx7&quot; data-ke-size=&quot;size23&quot;&gt;1단계&lt;/h3&gt;
&lt;p data-end=&quot;4012&quot; data-start=&quot;4000&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면 대시보드 구성&lt;/p&gt;
&lt;h3 data-end=&quot;4021&quot; data-start=&quot;4014&quot; data-section-id=&quot;1xwo3vc&quot; data-ke-size=&quot;size23&quot;&gt;2단계&lt;/h3&gt;
&lt;p data-end=&quot;4040&quot; data-start=&quot;4022&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면 구조 분리 및 컴포넌트화&lt;/p&gt;
&lt;h3 data-end=&quot;4049&quot; data-start=&quot;4042&quot; data-section-id=&quot;1xwnyc9&quot; data-ke-size=&quot;size23&quot;&gt;3단계&lt;/h3&gt;
&lt;p data-end=&quot;4062&quot; data-start=&quot;4050&quot; data-ke-size=&quot;size16&quot;&gt;경기 목록 페이지 추가&lt;/p&gt;
&lt;h3 data-end=&quot;4071&quot; data-start=&quot;4064&quot; data-section-id=&quot;1xwnqu6&quot; data-ke-size=&quot;size23&quot;&gt;4단계&lt;/h3&gt;
&lt;p data-end=&quot;4084&quot; data-start=&quot;4072&quot; data-ke-size=&quot;size16&quot;&gt;경기 상세 페이지 추가&lt;/p&gt;
&lt;p data-end=&quot;4118&quot; data-start=&quot;4086&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이제는 단순히 홈 화면 하나만 있는 프로젝트가 아니라&lt;/p&gt;
&lt;p data-end=&quot;4135&quot; data-start=&quot;4120&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;홈 &amp;rarr; 목록 &amp;rarr; 상세&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4161&quot; data-start=&quot;4137&quot; data-ke-size=&quot;size16&quot;&gt;로 이어지는 기본 흐름이 갖춰진 상태입니다.&lt;/p&gt;
&lt;hr data-end=&quot;4166&quot; data-start=&quot;4163&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4190&quot; data-start=&quot;4168&quot; data-section-id=&quot;1ct23iv&quot; data-ke-size=&quot;size26&quot;&gt;9. 현재 기준 프로젝트 구조 일부&lt;/h2&gt;
&lt;p data-end=&quot;4242&quot; data-start=&quot;4192&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업 이후 기준으로 보면&lt;br /&gt;프로젝트는 대략 다음과 같은 흐름으로 확장되고 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1777368976323&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src
├─app
│ ├─page.tsx
│ └─games
│ ├─page.tsx
│ └─[gameId]
│ └─page.tsx
│
└─features
└─nba
├─components
├─data
│ ├─home
│ └─games
├─lib
└─types&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4466&quot; data-start=&quot;4458&quot; data-ke-size=&quot;size16&quot;&gt;이 구조를 통해&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4508&quot; data-start=&quot;4468&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4480&quot; data-start=&quot;4468&quot; data-section-id=&quot;f1fz48&quot;&gt;홈에 필요한 데이터&lt;/li&gt;
&lt;li data-end=&quot;4494&quot; data-start=&quot;4481&quot; data-section-id=&quot;l89bis&quot;&gt;목록에 필요한 데이터&lt;/li&gt;
&lt;li data-end=&quot;4508&quot; data-start=&quot;4495&quot; data-section-id=&quot;1efhn95&quot;&gt;상세에 필요한 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4538&quot; data-start=&quot;4510&quot; data-ke-size=&quot;size16&quot;&gt;를 역할 기준으로 계속 확장할 수 있게 되었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;4543&quot; data-start=&quot;4540&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4557&quot; data-start=&quot;4545&quot; data-section-id=&quot;ueex66&quot; data-ke-size=&quot;size26&quot;&gt;10. 다음 단계&lt;/h2&gt;
&lt;p data-end=&quot;4610&quot; data-start=&quot;4559&quot; data-ke-size=&quot;size16&quot;&gt;현재까지 홈, 목록, 상세까지 연결하면서&lt;br /&gt;서비스의 기본 흐름은 어느 정도 정리되었습니다.&lt;/p&gt;
&lt;p data-end=&quot;4610&quot; data-start=&quot;4559&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4620&quot; data-start=&quot;4612&quot; data-ke-size=&quot;size16&quot;&gt;다음 단계에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4727&quot; data-start=&quot;4622&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4667&quot; data-start=&quot;4622&quot; data-section-id=&quot;121boy9&quot;&gt;Watchability Score를 설명하는 /about-score 페이지&lt;/li&gt;
&lt;li data-end=&quot;4683&quot; data-start=&quot;4668&quot; data-section-id=&quot;q9tcvt&quot;&gt;상세 페이지 데이터 확장&lt;/li&gt;
&lt;li data-end=&quot;4698&quot; data-start=&quot;4684&quot; data-section-id=&quot;b7g5zu&quot;&gt;favorites 기능&lt;/li&gt;
&lt;li data-end=&quot;4712&quot; data-start=&quot;4699&quot; data-section-id=&quot;xjb4os&quot;&gt;상태 관리 구조 정리&lt;/li&gt;
&lt;li data-end=&quot;4727&quot; data-start=&quot;4713&quot; data-section-id=&quot;13fzawc&quot;&gt;실제 API 연결 준비&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4744&quot; data-start=&quot;4729&quot; data-ke-size=&quot;size16&quot;&gt;등으로 확장해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;4744&quot; data-start=&quot;4729&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4782&quot; data-start=&quot;4746&quot; data-ke-size=&quot;size16&quot;&gt;특히 다음 단계에서는&lt;br /&gt;단순히 페이지를 더 만드는 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;4782&quot; data-start=&quot;4746&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4815&quot; data-start=&quot;4784&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 점수의 기준을 더 설득력 있게 보여주는 방향&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4841&quot; data-start=&quot;4817&quot; data-ke-size=&quot;size16&quot;&gt;으로 발전시키는 것이 핵심이라고 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;4846&quot; data-start=&quot;4843&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4858&quot; data-start=&quot;4848&quot; data-section-id=&quot;483su3&quot; data-ke-size=&quot;size26&quot;&gt;11. 마무리&lt;/h2&gt;
&lt;p data-end=&quot;4909&quot; data-start=&quot;4860&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업을 통해 느낀 점은&lt;br /&gt;홈 화면만으로는 서비스가 완성되지 않는다는 것이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;4909&quot; data-start=&quot;4860&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4930&quot; data-start=&quot;4911&quot; data-ke-size=&quot;size16&quot;&gt;사용자가 실제로 탐색하고 선택하려면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4978&quot; data-start=&quot;4932&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4953&quot; data-start=&quot;4932&quot; data-section-id=&quot;1xtp43w&quot;&gt;전체를 비교할 수 있는 목록 페이지&lt;/li&gt;
&lt;li data-end=&quot;4978&quot; data-start=&quot;4954&quot; data-section-id=&quot;zzezo9&quot;&gt;선택 근거를 확인할 수 있는 상세 페이지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4993&quot; data-start=&quot;4980&quot; data-ke-size=&quot;size16&quot;&gt;가 반드시 필요했습니다.&lt;/p&gt;
&lt;p data-end=&quot;4993&quot; data-start=&quot;4980&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5031&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;결국 추천 서비스의 핵심은&lt;/p&gt;
&lt;p data-end=&quot;5031&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;정보를 많이 보여주는 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;5031&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5061&quot; data-start=&quot;5033&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용자가 선택할 수 있게 흐름을 설계하는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;5079&quot; data-start=&quot;5063&quot; data-ke-size=&quot;size16&quot;&gt;이라는 점을 다시 느꼈습니다.&lt;/p&gt;
&lt;/div&gt;</description>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/18</guid>
      <comments>https://dlsxo.tistory.com/18#entry18comment</comments>
      <pubDate>Fri, 8 May 2026 14:54:07 +0900</pubDate>
    </item>
    <item>
      <title>사이드 프로젝트 | NBA Game Picker (2) - 홈 화면 구조와 컴포넌트 분리</title>
      <link>https://dlsxo.tistory.com/17</link>
      <description>&lt;p data-end=&quot;166&quot; data-start=&quot;158&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-end=&quot;166&quot; data-start=&quot;158&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;237&quot; data-start=&quot;168&quot; data-ke-size=&quot;size16&quot;&gt;지난 글에서는&lt;br /&gt;NBA Game Picker 프로젝트를 왜 만들었고,&lt;br /&gt;어떤 방향으로 설계했는지에 대해 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;237&quot; data-start=&quot;168&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;248&quot; data-start=&quot;239&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는&lt;/p&gt;
&lt;p data-end=&quot;287&quot; data-start=&quot;250&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;홈 화면을 어떻게 구조화하고, 컴포넌트로 분리했는지&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;289&quot; data-ke-size=&quot;size16&quot;&gt;그 과정을 정리해보려고 합니다.&lt;/p&gt;
&lt;hr data-end=&quot;313&quot; data-start=&quot;310&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;341&quot; data-start=&quot;315&quot; data-section-id=&quot;1da52mm&quot; data-ke-size=&quot;size26&quot;&gt;1. 왜 컴포넌트 분리를 하게 되었는가&lt;/h2&gt;
&lt;p data-end=&quot;392&quot; data-start=&quot;343&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면을 처음 구현할 때는&lt;br /&gt;모든 코드를 page.tsx 하나에 작성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;440&quot; data-start=&quot;394&quot; data-ke-size=&quot;size16&quot;&gt;초기에는 문제가 없어 보였지만&lt;br /&gt;기능이 추가되면서 점점 구조가 복잡해졌습니다.&lt;/p&gt;
&lt;p data-end=&quot;481&quot; data-start=&quot;442&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 다음과 같은 요소들이 한 파일 안에 모두 들어가 있었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;568&quot; data-start=&quot;483&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;496&quot; data-start=&quot;483&quot; data-section-id=&quot;aylp8p&quot;&gt;오늘 경기 리스트&lt;/li&gt;
&lt;li data-end=&quot;510&quot; data-start=&quot;497&quot; data-section-id=&quot;eaviy1&quot;&gt;오늘의 추천 경기&lt;/li&gt;
&lt;li data-end=&quot;519&quot; data-start=&quot;511&quot; data-section-id=&quot;1foc9ow&quot;&gt;팀 순위&lt;/li&gt;
&lt;li data-end=&quot;529&quot; data-start=&quot;520&quot; data-section-id=&quot;1t5jjwd&quot;&gt;득점 리더&lt;/li&gt;
&lt;li data-end=&quot;541&quot; data-start=&quot;530&quot; data-section-id=&quot;10k6nut&quot;&gt;매치업 데이터&lt;/li&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;542&quot; data-section-id=&quot;j4a9d0&quot;&gt;카드 UI 스타일&lt;/li&gt;
&lt;li data-end=&quot;568&quot; data-start=&quot;556&quot; data-section-id=&quot;i941at&quot;&gt;점수 관련 로직&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;570&quot; data-ke-size=&quot;size16&quot;&gt;이 상태에서는&lt;/p&gt;
&lt;p data-end=&quot;633&quot; data-start=&quot;581&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어느 하나를 수정하려고 해도 전체 파일을 같이 봐야 하는 상황&lt;/b&gt;이 발생했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;638&quot; data-start=&quot;635&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;654&quot; data-start=&quot;640&quot; data-section-id=&quot;1t95nbw&quot; data-ke-size=&quot;size26&quot;&gt;2. 문제의 핵심&lt;/h2&gt;
&lt;p data-end=&quot;680&quot; data-start=&quot;656&quot; data-ke-size=&quot;size16&quot;&gt;문제는 단순히 코드가 길어진 것이 아니라&lt;/p&gt;
&lt;p data-end=&quot;709&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할이 섞여 있다는 점&lt;/b&gt;이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;720&quot; data-start=&quot;711&quot; data-ke-size=&quot;size16&quot;&gt;하나의 파일 안에&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;743&quot; data-start=&quot;722&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;728&quot; data-start=&quot;722&quot; data-section-id=&quot;1j4h8es&quot;&gt;UI&lt;/li&gt;
&lt;li data-end=&quot;736&quot; data-start=&quot;729&quot; data-section-id=&quot;1rgp924&quot;&gt;데이터&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;737&quot; data-section-id=&quot;1v00wmt&quot;&gt;로직&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;789&quot; data-start=&quot;745&quot; data-ke-size=&quot;size16&quot;&gt;이 모두 섞여 있다 보니&lt;br /&gt;코드를 이해하고 수정하는 데 부담이 커졌습니다.&lt;/p&gt;
&lt;hr data-end=&quot;794&quot; data-start=&quot;791&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;814&quot; data-start=&quot;796&quot; data-section-id=&quot;1126q8w&quot; data-ke-size=&quot;size26&quot;&gt;3. 구조를 나누는 기준&lt;/h2&gt;
&lt;p data-end=&quot;848&quot; data-start=&quot;816&quot; data-ke-size=&quot;size16&quot;&gt;그래서 구조를 나눌 때&lt;br /&gt;기준을 명확하게 잡았습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;856&quot; data-start=&quot;850&quot; data-section-id=&quot;1hrmdfa&quot; data-ke-size=&quot;size23&quot;&gt;기준&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;920&quot; data-start=&quot;858&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;877&quot; data-start=&quot;858&quot; data-section-id=&quot;1gezsuy&quot;&gt;UI &amp;rarr; components&lt;/li&gt;
&lt;li data-end=&quot;892&quot; data-start=&quot;878&quot; data-section-id=&quot;8vyo66&quot;&gt;데이터 &amp;rarr; data&lt;/li&gt;
&lt;li data-end=&quot;905&quot; data-start=&quot;893&quot; data-section-id=&quot;1hsvvc0&quot;&gt;로직 &amp;rarr; lib&lt;/li&gt;
&lt;li data-end=&quot;920&quot; data-start=&quot;906&quot; data-section-id=&quot;778904&quot;&gt;타입 &amp;rarr; types&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;957&quot; data-start=&quot;922&quot; data-ke-size=&quot;size16&quot;&gt;이 기준을 기반으로&lt;br /&gt;기존 구조를 점진적으로 분리했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;962&quot; data-start=&quot;959&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;977&quot; data-start=&quot;964&quot; data-section-id=&quot;1uq0w3v&quot; data-ke-size=&quot;size26&quot;&gt;4. 현재 구조&lt;/h2&gt;
&lt;p data-end=&quot;1001&quot; data-start=&quot;979&quot; data-ke-size=&quot;size16&quot;&gt;현재는 다음과 같은 구조로 정리했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1777365190602&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;features/nba
├─constants
├─data
├─lib
└─types&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1071&quot; data-start=&quot;1062&quot; data-ke-size=&quot;size16&quot;&gt;여기서 핵심은&lt;/p&gt;
&lt;p data-end=&quot;1108&quot; data-start=&quot;1073&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;**&amp;ldquo;기능이 아니라 역할 기준으로 나눈 것&amp;rdquo;**입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1113&quot; data-start=&quot;1110&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1133&quot; data-start=&quot;1115&quot; data-section-id=&quot;thwpkr&quot; data-ke-size=&quot;size26&quot;&gt;5. 컴포넌트 분리 대상&lt;/h2&gt;
&lt;p data-end=&quot;1167&quot; data-start=&quot;1135&quot; data-ke-size=&quot;size16&quot;&gt;홈 화면을 기준으로&lt;br /&gt;다음 컴포넌트들을 분리했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1172&quot; data-start=&quot;1169&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1187&quot; data-start=&quot;1174&quot; data-section-id=&quot;19mc6oa&quot; data-ke-size=&quot;size23&quot;&gt;1) Card&lt;/h3&gt;
&lt;p data-end=&quot;1212&quot; data-start=&quot;1189&quot; data-ke-size=&quot;size16&quot;&gt;가장 기본이 되는 UI 컴포넌트입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1247&quot; data-start=&quot;1214&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1223&quot; data-start=&quot;1214&quot; data-section-id=&quot;12y7ay0&quot;&gt;title&lt;/li&gt;
&lt;li data-end=&quot;1234&quot; data-start=&quot;1224&quot; data-section-id=&quot;4hqj5i&quot;&gt;action&lt;/li&gt;
&lt;li data-end=&quot;1247&quot; data-start=&quot;1235&quot; data-section-id=&quot;1qvnwm3&quot;&gt;children&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1288&quot; data-start=&quot;1249&quot; data-ke-size=&quot;size16&quot;&gt;형태로 구성해서&lt;br /&gt;모든 섹션에서 재사용할 수 있도록 만들었습니다.&lt;/p&gt;
&lt;p data-end=&quot;1328&quot; data-start=&quot;1290&quot; data-ke-size=&quot;size16&quot;&gt;하나의 레이아웃을 여러 곳에서 공통으로 사용하는 역할입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1333&quot; data-start=&quot;1330&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1351&quot; data-start=&quot;1335&quot; data-section-id=&quot;fbzpmh&quot; data-ke-size=&quot;size23&quot;&gt;2) GameRow&lt;/h3&gt;
&lt;p data-end=&quot;1377&quot; data-start=&quot;1353&quot; data-ke-size=&quot;size16&quot;&gt;경기 리스트에서 사용하는 컴포넌트입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1408&quot; data-start=&quot;1379&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1388&quot; data-start=&quot;1379&quot; data-section-id=&quot;uwlpjx&quot;&gt;경기 시간&lt;/li&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1389&quot; data-section-id=&quot;1ogu2r5&quot;&gt;팀 매치업&lt;/li&gt;
&lt;li data-end=&quot;1408&quot; data-start=&quot;1399&quot; data-section-id=&quot;m1jpxk&quot;&gt;추천 점수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1457&quot; data-start=&quot;1410&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;홈 화면과 /games 페이지에서 모두 재사용할 수 있도록 설계했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1462&quot; data-start=&quot;1459&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1484&quot; data-start=&quot;1464&quot; data-section-id=&quot;rvulc8&quot; data-ke-size=&quot;size23&quot;&gt;3) RankingList&lt;/h3&gt;
&lt;p data-end=&quot;1507&quot; data-start=&quot;1486&quot; data-ke-size=&quot;size16&quot;&gt;팀 순위를 보여주는 컴포넌트입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1531&quot; data-start=&quot;1509&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1515&quot; data-start=&quot;1509&quot; data-section-id=&quot;dvhsts&quot;&gt;순위&lt;/li&gt;
&lt;li data-end=&quot;1524&quot; data-start=&quot;1516&quot; data-section-id=&quot;1fhumm0&quot;&gt;팀 이름&lt;/li&gt;
&lt;li data-end=&quot;1531&quot; data-start=&quot;1525&quot; data-section-id=&quot;dheo29&quot;&gt;승률&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1580&quot; data-start=&quot;1533&quot; data-ke-size=&quot;size16&quot;&gt;단순 테이블 구조지만&lt;br /&gt;별도 컴포넌트로 분리하면서 재사용성을 확보했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1585&quot; data-start=&quot;1582&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1610&quot; data-start=&quot;1587&quot; data-section-id=&quot;csubr2&quot; data-ke-size=&quot;size23&quot;&gt;4) ScoringLeaders&lt;/h3&gt;
&lt;p data-end=&quot;1634&quot; data-start=&quot;1612&quot; data-ke-size=&quot;size16&quot;&gt;득점 리더를 보여주는 컴포넌트입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1668&quot; data-start=&quot;1636&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1642&quot; data-start=&quot;1636&quot; data-section-id=&quot;dvhsts&quot;&gt;순위&lt;/li&gt;
&lt;li data-end=&quot;1652&quot; data-start=&quot;1643&quot; data-section-id=&quot;yb4vcw&quot;&gt;선수 이름&lt;/li&gt;
&lt;li data-end=&quot;1658&quot; data-start=&quot;1653&quot; data-section-id=&quot;2gskh4&quot;&gt;팀&lt;/li&gt;
&lt;li data-end=&quot;1668&quot; data-start=&quot;1659&quot; data-section-id=&quot;rgckng&quot;&gt;평균 득점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1704&quot; data-start=&quot;1670&quot; data-ke-size=&quot;size16&quot;&gt;이후 별도 페이지로 확장하기 쉽게 구조를 잡았습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1709&quot; data-start=&quot;1706&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1731&quot; data-start=&quot;1711&quot; data-section-id=&quot;1h6rfuo&quot; data-ke-size=&quot;size26&quot;&gt;6. 분리하면서 중요했던 점&lt;/h2&gt;
&lt;h3 data-end=&quot;1750&quot; data-start=&quot;1733&quot; data-section-id=&quot;15rpng0&quot; data-ke-size=&quot;size23&quot;&gt;1) props 설계&lt;/h3&gt;
&lt;p data-end=&quot;1776&quot; data-start=&quot;1752&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트를 나누면서 가장 중요했던 부분은&lt;/p&gt;
&lt;p data-end=&quot;1810&quot; data-start=&quot;1778&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;props를 어떻게 설계할 것인가&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;p data-end=&quot;1845&quot; data-start=&quot;1812&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 GameRow는&lt;br /&gt;필드를 하나씩 나누지 않고&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1777365214903&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface GameRowProps {
game: HomeGameItem;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1942&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1942&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;데이터 단위로 전달하는 방식&lt;/b&gt;으로 구성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1978&quot; data-start=&quot;1944&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 구조가 단순해지고 유지보수가 쉬워집니다.&lt;/p&gt;
&lt;hr data-end=&quot;1983&quot; data-start=&quot;1980&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2001&quot; data-start=&quot;1985&quot; data-section-id=&quot;14c1tep&quot; data-ke-size=&quot;size23&quot;&gt;2) 재사용성 고려&lt;/h3&gt;
&lt;p data-end=&quot;2027&quot; data-start=&quot;2003&quot; data-ke-size=&quot;size16&quot;&gt;처음부터 재사용을 고려해서 설계했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2145&quot; data-start=&quot;2029&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2048&quot; data-start=&quot;2029&quot; data-section-id=&quot;12gzo9z&quot;&gt;Card &amp;rarr; 모든 섹션 공통&lt;/li&gt;
&lt;li data-end=&quot;2079&quot; data-start=&quot;2049&quot; data-section-id=&quot;13twu7c&quot;&gt;GameRow &amp;rarr; 홈 / games 페이지 공통&lt;/li&gt;
&lt;li data-end=&quot;2110&quot; data-start=&quot;2080&quot; data-section-id=&quot;1g6r6vf&quot;&gt;RankingList &amp;rarr; 다른 페이지 확장 가능&lt;/li&gt;
&lt;li data-end=&quot;2145&quot; data-start=&quot;2111&quot; data-section-id=&quot;hsk5kq&quot;&gt;ScoringLeaders &amp;rarr; 별도 페이지로 확장 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2186&quot; data-start=&quot;2147&quot; data-ke-size=&quot;size16&quot;&gt;단순 분리가 아니라 &lt;b&gt;확장을 고려한 구조&lt;/b&gt;로 가져갔습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2191&quot; data-start=&quot;2188&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2209&quot; data-start=&quot;2193&quot; data-section-id=&quot;vw71k9&quot; data-ke-size=&quot;size23&quot;&gt;3) 스타일 일관성&lt;/h3&gt;
&lt;p data-end=&quot;2244&quot; data-start=&quot;2211&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트를 나누면서&lt;br /&gt;UI도 자연스럽게 정리되었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2308&quot; data-start=&quot;2246&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2263&quot; data-start=&quot;2246&quot; data-section-id=&quot;1xjejcl&quot;&gt;border 스타일 통일&lt;/li&gt;
&lt;li data-end=&quot;2277&quot; data-start=&quot;2264&quot; data-section-id=&quot;1a1tkbd&quot;&gt;radius 통일&lt;/li&gt;
&lt;li data-end=&quot;2292&quot; data-start=&quot;2278&quot; data-section-id=&quot;12b8o1s&quot;&gt;spacing 통일&lt;/li&gt;
&lt;li data-end=&quot;2308&quot; data-start=&quot;2293&quot; data-section-id=&quot;5a9skt&quot;&gt;다크모드 대응 일관화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2340&quot; data-start=&quot;2310&quot; data-ke-size=&quot;size16&quot;&gt;결과적으로 전체 UI의 완성도가 올라갔습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2345&quot; data-start=&quot;2342&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2363&quot; data-start=&quot;2347&quot; data-section-id=&quot;1qmna9c&quot; data-ke-size=&quot;size26&quot;&gt;7. 분리 이후 변화&lt;/h2&gt;
&lt;p data-end=&quot;2398&quot; data-start=&quot;2365&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트를 분리한 이후 가장 큰 변화는 다음과 같습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2410&quot; data-start=&quot;2400&quot; data-section-id=&quot;yovzmn&quot; data-ke-size=&quot;size23&quot;&gt;before&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2470&quot; data-start=&quot;2411&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2438&quot; data-start=&quot;2411&quot; data-section-id=&quot;1qbug2q&quot;&gt;page.tsx 하나에 모든 코드 존재&lt;/li&gt;
&lt;li data-end=&quot;2455&quot; data-start=&quot;2439&quot; data-section-id=&quot;9hizpt&quot;&gt;수정 시 영향 범위 큼&lt;/li&gt;
&lt;li data-end=&quot;2470&quot; data-start=&quot;2456&quot; data-section-id=&quot;1v8yxa1&quot;&gt;구조 파악이 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;2481&quot; data-start=&quot;2472&quot; data-section-id=&quot;7lp6iq&quot; data-ke-size=&quot;size23&quot;&gt;after&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2527&quot; data-start=&quot;2482&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2495&quot; data-start=&quot;2482&quot; data-section-id=&quot;cv0em1&quot;&gt;역할별 파일 분리&lt;/li&gt;
&lt;li data-end=&quot;2513&quot; data-start=&quot;2496&quot; data-section-id=&quot;zgqnus&quot;&gt;필요한 부분만 수정 가능&lt;/li&gt;
&lt;li data-end=&quot;2527&quot; data-start=&quot;2514&quot; data-section-id=&quot;lkv3k8&quot;&gt;코드 가독성 개선&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2529&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유지보수성과 확장성이 크게 개선되었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2566&quot; data-start=&quot;2563&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2587&quot; data-start=&quot;2568&quot; data-section-id=&quot;1h24aub&quot; data-ke-size=&quot;size26&quot;&gt;8. 현재 단계에서의 의미&lt;/h2&gt;
&lt;p data-end=&quot;2615&quot; data-start=&quot;2589&quot; data-ke-size=&quot;size16&quot;&gt;지금 단계는 단순히 UI를 만든 것이 아니라&lt;/p&gt;
&lt;p data-end=&quot;2652&quot; data-start=&quot;2617&quot; data-ke-size=&quot;size16&quot;&gt;**&amp;ldquo;서비스 구조를 설계하는 단계&amp;rdquo;**라고 생각합니다.&lt;/p&gt;
&lt;p data-end=&quot;2664&quot; data-start=&quot;2654&quot; data-ke-size=&quot;size16&quot;&gt;이 작업을 통해&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2697&quot; data-start=&quot;2666&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2676&quot; data-start=&quot;2666&quot; data-section-id=&quot;1hrmdm0&quot;&gt;데이터 흐름&lt;/li&gt;
&lt;li data-end=&quot;2688&quot; data-start=&quot;2677&quot; data-section-id=&quot;19ghf08&quot;&gt;컴포넌트 구조&lt;/li&gt;
&lt;li data-end=&quot;2697&quot; data-start=&quot;2689&quot; data-section-id=&quot;1dwe6xc&quot;&gt;재사용성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2721&quot; data-start=&quot;2699&quot; data-ke-size=&quot;size16&quot;&gt;이 세 가지를 정리할 수 있었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2726&quot; data-start=&quot;2723&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2739&quot; data-start=&quot;2728&quot; data-section-id=&quot;204f8i&quot; data-ke-size=&quot;size26&quot;&gt;9. 마무리&lt;/h2&gt;
&lt;p data-end=&quot;2758&quot; data-start=&quot;2741&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업을 통해 느낀 점은&lt;/p&gt;
&lt;p data-end=&quot;2807&quot; data-start=&quot;2760&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UI를 만드는 것보다 구조를 만드는 것이 더 중요하다&lt;/b&gt;는 것이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;2807&quot; data-start=&quot;2760&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2848&quot; data-start=&quot;2809&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 빠르게 화면을 만드는 데 집중했지만,&lt;br /&gt;기능이 늘어날수록&lt;/p&gt;
&lt;p data-end=&quot;2882&quot; data-start=&quot;2850&quot; data-ke-size=&quot;size16&quot;&gt;구조를 정리하는 작업이 필수라는 것을 느꼈습니다.&lt;/p&gt;</description>
      <category>프로젝트 회고록</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/17</guid>
      <comments>https://dlsxo.tistory.com/17#entry17comment</comments>
      <pubDate>Mon, 4 May 2026 10:47:17 +0900</pubDate>
    </item>
    <item>
      <title>사이드 프로젝트 | NBA Game Picker (1) - 프로젝트 기획과 서비스 방향</title>
      <link>https://dlsxo.tistory.com/16</link>
      <description>&lt;p data-end=&quot;204&quot; data-start=&quot;130&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;br /&gt;이번 글에서는 제가 진행하고 있는 사이드 프로젝트인&lt;br /&gt;&lt;b&gt;NBA Game Picker&lt;/b&gt;를 소개해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;204&quot; data-start=&quot;130&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;275&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는&lt;br /&gt;NBA 경기 데이터를 기반으로&lt;br /&gt;&lt;b&gt;오늘 가장 볼 만한 경기를 추천해주는 웹 서비스&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;275&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;358&quot; data-start=&quot;277&quot; data-ke-size=&quot;size16&quot;&gt;단순히 경기 일정을 나열하는 것이 아니라,&lt;br /&gt;사용자가 빠르게 경기를 선택할 수 있도록&lt;/p&gt;
&lt;p data-end=&quot;358&quot; data-start=&quot;277&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 중심의 UX로 설계한 것이 핵심입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;358&quot; data-start=&quot;277&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;1062&quot; data-origin-height=&quot;847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEbVR1/dJMcafl7IdH/ye01DLz8W0Y0CWl2zGwPnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEbVR1/dJMcafl7IdH/ye01DLz8W0Y0CWl2zGwPnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEbVR1/dJMcafl7IdH/ye01DLz8W0Y0CWl2zGwPnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEbVR1%2FdJMcafl7IdH%2Fye01DLz8W0Y0CWl2zGwPnK%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;1062&quot; height=&quot;847&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;847&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;397&quot; data-start=&quot;360&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;397&quot; data-start=&quot;360&quot; data-ke-size=&quot;size16&quot;&gt;아래 링크에서 실제 서비스와 코드를 함께 확인하실 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;402&quot; data-start=&quot;399&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;454&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;  서비스 바로가기&lt;br /&gt;&lt;a href=&quot;https://nba-game-picker.vercel.app&quot;&gt;https://nba-game-picker.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;456&quot; data-ke-size=&quot;size16&quot;&gt;  GitHub&lt;br /&gt;&lt;a href=&quot;https://github.com/Ryuintae/nba-game-picker&quot;&gt;https://github.com/Ryuintae/nba-game-picker&lt;/a&gt;&lt;/p&gt;
&lt;hr data-end=&quot;518&quot; data-start=&quot;515&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;542&quot; data-start=&quot;520&quot; data-section-id=&quot;cfuu2s&quot;&gt;1. 왜 이 프로젝트를 만들었는가&lt;/h1&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;544&quot; data-ke-size=&quot;size16&quot;&gt;NBA를 자주 보면서 항상 느꼈던 불편함이 있었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;635&quot; data-start=&quot;578&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;600&quot; data-start=&quot;578&quot; data-section-id=&quot;p7l602&quot;&gt;오늘 경기 많네&amp;hellip; 근데 뭐 보지?&lt;/li&gt;
&lt;li data-end=&quot;614&quot; data-start=&quot;601&quot; data-section-id=&quot;fqtkan&quot;&gt;접전 경기 뭐지?&lt;/li&gt;
&lt;li data-end=&quot;635&quot; data-start=&quot;615&quot; data-section-id=&quot;1hosom1&quot;&gt;득점 많이 나올 경기 어디지?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;653&quot; data-start=&quot;637&quot; data-ke-size=&quot;size16&quot;&gt;기존 스포츠 앱들은 대부분&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;680&quot; data-start=&quot;655&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;664&quot; data-start=&quot;655&quot; data-section-id=&quot;vuohrg&quot;&gt;경기 일정&lt;/li&gt;
&lt;li data-end=&quot;673&quot; data-start=&quot;665&quot; data-section-id=&quot;1g1em6h&quot;&gt;팀 정보&lt;/li&gt;
&lt;li data-end=&quot;680&quot; data-start=&quot;674&quot; data-section-id=&quot;1xev1lw&quot;&gt;결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;704&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;이 정도만 제공하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;704&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;726&quot; data-start=&quot;706&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제로 사용자가 원하는 건&lt;/p&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;728&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;오늘 가장 재미있는 경기가 무엇인지&amp;rdquo;&lt;/b&gt; 입니다.&lt;/p&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;728&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;786&quot; data-start=&quot;765&quot; data-ke-size=&quot;size16&quot;&gt;그래서 단순한 일정 서비스가 아니라&lt;/p&gt;
&lt;p data-end=&quot;832&quot; data-start=&quot;788&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;경기를 &amp;ldquo;선택&amp;rdquo;할 수 있게 도와주는 서비스&lt;/b&gt;를 만들고자 했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;837&quot; data-start=&quot;834&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;853&quot; data-start=&quot;839&quot; data-section-id=&quot;1cfbnki&quot;&gt;2. 프로젝트 목표&lt;/h1&gt;
&lt;p data-end=&quot;881&quot; data-start=&quot;855&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 핵심 목표는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;970&quot; data-start=&quot;883&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;903&quot; data-start=&quot;883&quot; data-section-id=&quot;1jxporc&quot;&gt;오늘 가장 볼 만한 경기 추천&lt;/li&gt;
&lt;li data-end=&quot;941&quot; data-start=&quot;904&quot; data-section-id=&quot;2bk10m&quot;&gt;경기별 재미 지수 (Watchability Score) 제공&lt;/li&gt;
&lt;li data-end=&quot;970&quot; data-start=&quot;942&quot; data-section-id=&quot;6e39q1&quot;&gt;여러 데이터를 한 화면에서 빠르게 비교 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;976&quot; data-start=&quot;972&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-end=&quot;1029&quot; data-start=&quot;978&quot; data-ke-size=&quot;size16&quot;&gt;**&amp;ldquo;정보 제공&amp;rdquo;이 아니라 &amp;ldquo;선택을 도와주는 서비스&amp;rdquo;**를 만드는 것이 목표입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1034&quot; data-start=&quot;1031&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1048&quot; data-start=&quot;1036&quot; data-section-id=&quot;1hzsh2q&quot;&gt;3. 기술 스택&lt;/h1&gt;
&lt;p data-end=&quot;1079&quot; data-start=&quot;1050&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트는 프론트엔드 중심으로 진행했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1090&quot; data-start=&quot;1081&quot; data-section-id=&quot;1b7eaab&quot; data-ke-size=&quot;size23&quot;&gt;사용 기술&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1201&quot; data-start=&quot;1092&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1116&quot; data-start=&quot;1092&quot; data-section-id=&quot;sx58wj&quot;&gt;Next.js (App Router)&lt;/li&gt;
&lt;li data-end=&quot;1131&quot; data-start=&quot;1117&quot; data-section-id=&quot;1i4dgrj&quot;&gt;TypeScript&lt;/li&gt;
&lt;li data-end=&quot;1148&quot; data-start=&quot;1132&quot; data-section-id=&quot;ydpgen&quot;&gt;Tailwind CSS&lt;/li&gt;
&lt;li data-end=&quot;1176&quot; data-start=&quot;1149&quot; data-section-id=&quot;dvyijm&quot;&gt;next-themes (다크/라이트 모드)&lt;/li&gt;
&lt;li data-end=&quot;1190&quot; data-start=&quot;1177&quot; data-section-id=&quot;1lfhrnj&quot;&gt;Vercel 배포&lt;/li&gt;
&lt;li data-end=&quot;1201&quot; data-start=&quot;1191&quot; data-section-id=&quot;1aths9y&quot;&gt;PWA 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1215&quot; data-start=&quot;1203&quot; data-section-id=&quot;1rgrqn7&quot; data-ke-size=&quot;size23&quot;&gt;적용 예정 기술&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1272&quot; data-start=&quot;1217&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1242&quot; data-start=&quot;1217&quot; data-section-id=&quot;1cqfq9z&quot;&gt;Zustand (클라이언트 상태 관리)&lt;/li&gt;
&lt;li data-end=&quot;1272&quot; data-start=&quot;1243&quot; data-section-id=&quot;1vm7dcv&quot;&gt;TanStack Query (서버 상태 관리)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1283&quot; data-start=&quot;1274&quot; data-section-id=&quot;11wolpr&quot; data-ke-size=&quot;size23&quot;&gt;선택 이유&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1470&quot; data-start=&quot;1285&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1311&quot; data-start=&quot;1285&quot; data-section-id=&quot;5xz64w&quot;&gt;Next.js &amp;rarr; 페이지 구조 + 확장성&lt;/li&gt;
&lt;li data-end=&quot;1339&quot; data-start=&quot;1312&quot; data-section-id=&quot;1qqgkm9&quot;&gt;TypeScript &amp;rarr; 데이터 구조 명확화&lt;/li&gt;
&lt;li data-end=&quot;1363&quot; data-start=&quot;1340&quot; data-section-id=&quot;w0w0h3&quot;&gt;Tailwind &amp;rarr; 빠른 UI 구성&lt;/li&gt;
&lt;li data-end=&quot;1387&quot; data-start=&quot;1364&quot; data-section-id=&quot;tqlgei&quot;&gt;next-themes &amp;rarr; 테마 전환&lt;/li&gt;
&lt;li data-end=&quot;1407&quot; data-start=&quot;1388&quot; data-section-id=&quot;ek4wgd&quot;&gt;Vercel &amp;rarr; 간편한 배포&lt;/li&gt;
&lt;li data-end=&quot;1434&quot; data-start=&quot;1408&quot; data-section-id=&quot;7huwj8&quot;&gt;Zustand &amp;rarr; UI 상태 관리 단순화&lt;/li&gt;
&lt;li data-end=&quot;1470&quot; data-start=&quot;1435&quot; data-section-id=&quot;zopomk&quot;&gt;TanStack Query &amp;rarr; API 데이터 관리 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1475&quot; data-start=&quot;1472&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1607&quot; data-start=&quot;1595&quot; data-section-id=&quot;18fzlf5&quot; data-ke-size=&quot;size26&quot;&gt;4. PWA 적용&lt;/h2&gt;
&lt;p data-end=&quot;1680&quot; data-start=&quot;1609&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트는 웹 서비스로만 끝내지 않고,&lt;br /&gt;&lt;b&gt;PWA(Progressive Web App)&lt;/b&gt; 형태로도 적용하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1680&quot; data-start=&quot;1609&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1770&quot; data-start=&quot;1682&quot; data-ke-size=&quot;size16&quot;&gt;PWA를 적용한 이유는&lt;br /&gt;사용자가 브라우저에서만 접속하는 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;1770&quot; data-start=&quot;1682&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;홈 화면에 추가해서 앱처럼 접근할 수 있는 경험&lt;/b&gt;을 주고 싶었기 때문입니다.&lt;/p&gt;
&lt;p data-end=&quot;1800&quot; data-start=&quot;1772&quot; data-ke-size=&quot;size16&quot;&gt;현재는 다음과 같은 기본 설정을 적용한 상태입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1918&quot; data-start=&quot;1802&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1820&quot; data-start=&quot;1802&quot; data-section-id=&quot;1yjjxxv&quot;&gt;manifest.ts 구성&lt;/li&gt;
&lt;li data-end=&quot;1831&quot; data-start=&quot;1821&quot; data-section-id=&quot;cbnfz4&quot;&gt;앱 아이콘 설정&lt;/li&gt;
&lt;li data-end=&quot;1862&quot; data-start=&quot;1832&quot; data-section-id=&quot;1u96pra&quot;&gt;PwaRegister 컴포넌트를 통한 등록 처리&lt;/li&gt;
&lt;li data-end=&quot;1886&quot; data-start=&quot;1863&quot; data-section-id=&quot;110zvl4&quot;&gt;InstallPrompt 버튼 구성&lt;/li&gt;
&lt;li data-end=&quot;1918&quot; data-start=&quot;1887&quot; data-section-id=&quot;1eh59tx&quot;&gt;HTTPS 환경에서 설치 가능하도록 Vercel 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1985&quot; data-start=&quot;1920&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;br /&gt;지금은 &lt;b&gt;추천형 웹 서비스이면서 동시에 앱처럼 설치할 수 있는 형태&lt;/b&gt;까지 기본 기반을 마련한 상태입니다.&lt;/p&gt;
&lt;p data-end=&quot;1985&quot; data-start=&quot;1920&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-start=&quot;1472&quot; data-end=&quot;1475&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1494&quot; data-start=&quot;1477&quot; data-section-id=&quot;1qirq75&quot;&gt;5. 현재 홈 화면 구성&lt;/h1&gt;
&lt;p data-end=&quot;1550&quot; data-start=&quot;1496&quot; data-ke-size=&quot;size16&quot;&gt;현재 홈 화면은 단순 소개 페이지가 아니라&lt;br /&gt;&lt;b&gt;스포츠 데이터 대시보드 형태로 구성했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1550&quot; data-start=&quot;1496&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1565&quot; data-start=&quot;1552&quot; data-ke-size=&quot;size16&quot;&gt;구성은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1635&quot; data-start=&quot;1567&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1587&quot; data-start=&quot;1567&quot; data-section-id=&quot;gtch08&quot;&gt;오늘 경기 리스트 (가로 스크롤)&lt;/li&gt;
&lt;li data-end=&quot;1599&quot; data-start=&quot;1588&quot; data-section-id=&quot;9nzup5&quot;&gt;오늘의 추천 경기&lt;/li&gt;
&lt;li data-end=&quot;1606&quot; data-start=&quot;1600&quot; data-section-id=&quot;acpno0&quot;&gt;팀 순위&lt;/li&gt;
&lt;li data-end=&quot;1614&quot; data-start=&quot;1607&quot; data-section-id=&quot;18qmeil&quot;&gt;득점 리더&lt;/li&gt;
&lt;li data-end=&quot;1624&quot; data-start=&quot;1615&quot; data-section-id=&quot;11qfdqd&quot;&gt;매치업 데이터&lt;/li&gt;
&lt;li data-end=&quot;1635&quot; data-start=&quot;1625&quot; data-section-id=&quot;6pm24p&quot;&gt;최근 경기 결과&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1641&quot; data-start=&quot;1637&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-end=&quot;1685&quot; data-start=&quot;1643&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;앱에 들어오자마자 바로 사용할 수 있는 구조&lt;/b&gt;로 설계했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1690&quot; data-start=&quot;1687&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1706&quot; data-start=&quot;1692&quot; data-section-id=&quot;urn2po&quot;&gt;6. 프로젝트 구조&lt;/h1&gt;
&lt;p data-end=&quot;1729&quot; data-start=&quot;1708&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트 구조는 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776674295595&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src
├─app
│ globals.css
│ icon.png
│ layout.tsx
│ manifest.ts
│ page.tsx
│ providers.tsx
│
├─components
│ InstallPrompt.tsx
│ PwaRegister.tsx
│ ThemeToggle.tsx
│
└─features
└─nba
├─constants
│ team-brand.ts
│
├─data
│ └─home
│ featured-game.ts
│ games.ts
│ scoring-leaders.ts
│ team-rankings.ts
│
├─lib
│ score.ts
│ team-brand.ts
│
└─types
home.ts&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2332&quot; data-start=&quot;2329&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2354&quot; data-start=&quot;2334&quot; data-section-id=&quot;u0memd&quot;&gt;7. 구조를 이렇게 나눈 이유&lt;/h1&gt;
&lt;p data-end=&quot;2416&quot; data-start=&quot;2356&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 모든 데이터를 page.tsx 안에 넣었지만,&lt;br /&gt;파일이 커지면서 유지보수가 어려워졌습니다.&lt;/p&gt;
&lt;p data-end=&quot;2416&quot; data-start=&quot;2356&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2439&quot; data-start=&quot;2418&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다음과 같이 구조를 나눴습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2454&quot; data-start=&quot;2441&quot; data-section-id=&quot;1uwiaxa&quot; data-ke-size=&quot;size23&quot;&gt;1) data&lt;/h3&gt;
&lt;blockquote data-end=&quot;2481&quot; data-start=&quot;2455&quot; data-ke-style=&quot;style2&quot;&gt;화면에서 사용하는 mock 데이터 분리&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2545&quot; data-start=&quot;2483&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2499&quot; data-start=&quot;2483&quot; data-section-id=&quot;1ddbdpy&quot;&gt;featuredGame&lt;/li&gt;
&lt;li data-end=&quot;2509&quot; data-start=&quot;2500&quot; data-section-id=&quot;mda0et&quot;&gt;games&lt;/li&gt;
&lt;li data-end=&quot;2526&quot; data-start=&quot;2510&quot; data-section-id=&quot;1uzvai8&quot;&gt;teamRankings&lt;/li&gt;
&lt;li data-end=&quot;2545&quot; data-start=&quot;2527&quot; data-section-id=&quot;15t7drh&quot;&gt;scoringLeaders&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2550&quot; data-start=&quot;2547&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2570&quot; data-start=&quot;2552&quot; data-section-id=&quot;lxlt4g&quot; data-ke-size=&quot;size23&quot;&gt;2) constants&lt;/h3&gt;
&lt;blockquote data-end=&quot;2591&quot; data-start=&quot;2571&quot; data-ke-style=&quot;style2&quot;&gt;공통적으로 사용하는 값 관리&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2617&quot; data-start=&quot;2593&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2605&quot; data-start=&quot;2593&quot; data-section-id=&quot;16fhilg&quot;&gt;팀 브랜드 컬러&lt;/li&gt;
&lt;li data-end=&quot;2617&quot; data-start=&quot;2606&quot; data-section-id=&quot;gbzit2&quot;&gt;UI 기준 값&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2622&quot; data-start=&quot;2619&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2636&quot; data-start=&quot;2624&quot; data-section-id=&quot;n8eaor&quot; data-ke-size=&quot;size23&quot;&gt;3) lib&lt;/h3&gt;
&lt;blockquote data-end=&quot;2647&quot; data-start=&quot;2637&quot; data-ke-style=&quot;style2&quot;&gt;로직 분리&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2669&quot; data-start=&quot;2649&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2658&quot; data-start=&quot;2649&quot; data-section-id=&quot;1abvuyc&quot;&gt;점수 계산&lt;/li&gt;
&lt;li data-end=&quot;2669&quot; data-start=&quot;2659&quot; data-section-id=&quot;1gfoayw&quot;&gt;데이터 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2674&quot; data-start=&quot;2671&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2690&quot; data-start=&quot;2676&quot; data-section-id=&quot;111u100&quot; data-ke-size=&quot;size23&quot;&gt;4) types&lt;/h3&gt;
&lt;blockquote data-end=&quot;2705&quot; data-start=&quot;2691&quot; data-ke-style=&quot;style2&quot;&gt;데이터 구조 정의&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2729&quot; data-start=&quot;2707&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2717&quot; data-start=&quot;2707&quot; data-section-id=&quot;jnqodl&quot;&gt;타입 명확화&lt;/li&gt;
&lt;li data-end=&quot;2729&quot; data-start=&quot;2718&quot; data-section-id=&quot;1qkhah8&quot;&gt;안정적인 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2734&quot; data-start=&quot;2731&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;2747&quot; data-start=&quot;2736&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 분리하면서&lt;/p&gt;
&lt;p data-end=&quot;2794&quot; data-start=&quot;2749&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;page.tsx는 렌더링 역할에만 집중하도록 구조를 개선했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2799&quot; data-start=&quot;2796&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2828&quot; data-start=&quot;2801&quot; data-section-id=&quot;34dwfx&quot;&gt;8. 현재는 mock 데이터 기반으로 구현&lt;/h1&gt;
&lt;p data-end=&quot;2889&quot; data-start=&quot;2830&quot; data-ke-size=&quot;size16&quot;&gt;현재 단계에서는 실제 API를 연결하지 않고&lt;br /&gt;&lt;b&gt;mock 데이터 기반으로 UI를 먼저 구성했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2889&quot; data-start=&quot;2830&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2912&quot; data-start=&quot;2891&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 진행한 이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2987&quot; data-start=&quot;2914&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2935&quot; data-start=&quot;2914&quot; data-section-id=&quot;tjluls&quot;&gt;UI 구조를 먼저 확정하기 위해&lt;/li&gt;
&lt;li data-end=&quot;2958&quot; data-start=&quot;2936&quot; data-section-id=&quot;i47cyt&quot;&gt;데이터 형태를 미리 설계하기 위해&lt;/li&gt;
&lt;li data-end=&quot;2987&quot; data-start=&quot;2959&quot; data-section-id=&quot;pwvtbh&quot;&gt;API 변경에 영향을 받지 않도록 하기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2993&quot; data-start=&quot;2989&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-end=&quot;3041&quot; data-start=&quot;2995&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;UI &amp;rarr; 데이터 구조 &amp;rarr; API 연동&amp;rdquo; 순서로 개발하고 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;3046&quot; data-start=&quot;3043&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3065&quot; data-start=&quot;3048&quot; data-section-id=&quot;4kpi14&quot;&gt;9. 구현하면서 느낀 점&lt;/h1&gt;
&lt;h2 data-end=&quot;3090&quot; data-start=&quot;3067&quot; data-section-id=&quot;3gbtn0&quot; data-ke-size=&quot;size26&quot;&gt;1) 데이터 구조 설계가 중요하다&lt;/h2&gt;
&lt;p data-end=&quot;3121&quot; data-start=&quot;3092&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 화면부터 만들었지만,&lt;br /&gt;결국 중요한 건&lt;/p&gt;
&lt;p data-end=&quot;3156&quot; data-start=&quot;3123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터를 어떻게 설계하고 관리하느냐&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3161&quot; data-start=&quot;3158&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3194&quot; data-start=&quot;3163&quot; data-section-id=&quot;1yb1h2i&quot; data-ke-size=&quot;size26&quot;&gt;2) 서비스형 UI와 랜딩 UI는 완전히 다르다&lt;/h2&gt;
&lt;p data-end=&quot;3216&quot; data-start=&quot;3196&quot; data-ke-size=&quot;size16&quot;&gt;랜딩 페이지는&lt;br /&gt;&lt;b&gt;&lt;u&gt;설명 중심&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3216&quot; data-start=&quot;3196&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3238&quot; data-start=&quot;3218&quot; data-ke-size=&quot;size16&quot;&gt;서비스 홈은&lt;br /&gt;&lt;b&gt;&lt;u&gt;데이터 중심&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3271&quot; data-start=&quot;3240&quot; data-ke-size=&quot;size16&quot;&gt;이 차이를 직접 경험한 것이 가장 큰 수확이었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3276&quot; data-start=&quot;3273&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3293&quot; data-start=&quot;3278&quot; data-section-id=&quot;1yeqhm4&quot;&gt;10. 현재 구현 상태&lt;/h1&gt;
&lt;p data-end=&quot;3317&quot; data-start=&quot;3295&quot; data-ke-size=&quot;size16&quot;&gt;현재까지 진행된 내용은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3468&quot; data-start=&quot;3319&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3338&quot; data-start=&quot;3319&quot; data-section-id=&quot;nnvllk&quot;&gt;Next.js 프로젝트 세팅&lt;/li&gt;
&lt;li data-end=&quot;3354&quot; data-start=&quot;3339&quot; data-section-id=&quot;1br8in8&quot;&gt;Tailwind 적용&lt;/li&gt;
&lt;li data-end=&quot;3371&quot; data-start=&quot;3355&quot; data-section-id=&quot;1kp26f7&quot;&gt;다크/라이트 모드 구현&lt;/li&gt;
&lt;li data-end=&quot;3388&quot; data-start=&quot;3372&quot; data-section-id=&quot;1sf714n&quot;&gt;Vercel 배포 완료&lt;/li&gt;
&lt;li data-end=&quot;3402&quot; data-start=&quot;3389&quot; data-section-id=&quot;82xjim&quot;&gt;PWA 기본 적용&lt;/li&gt;
&lt;li data-end=&quot;3422&quot; data-start=&quot;3403&quot; data-section-id=&quot;1yjrzr4&quot;&gt;홈 화면 대시보드 구조 구현&lt;/li&gt;
&lt;li data-end=&quot;3444&quot; data-start=&quot;3423&quot; data-section-id=&quot;13jh57j&quot;&gt;mock 데이터 기반 UI 구성&lt;/li&gt;
&lt;li data-end=&quot;3468&quot; data-start=&quot;3445&quot; data-section-id=&quot;ibe5b1&quot;&gt;데이터 / 상수 / 유틸 분리 완료&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3473&quot; data-start=&quot;3470&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3486&quot; data-start=&quot;3475&quot; data-section-id=&quot;ua6i61&quot;&gt;11. 마무리&lt;/h1&gt;
&lt;p data-end=&quot;3515&quot; data-start=&quot;3488&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트를 진행하면서 가장 크게 느낀 점은&lt;/p&gt;
&lt;p data-end=&quot;3563&quot; data-start=&quot;3517&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;좋은 서비스는 데이터를 어떻게 보여주느냐에 달려있다&lt;/b&gt;는 것이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;3563&quot; data-start=&quot;3517&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3632&quot; data-start=&quot;3565&quot; data-ke-size=&quot;size16&quot;&gt;단순히 정보를 나열하는 것이 아니라,&lt;br /&gt;사용자가 빠르게 판단할 수 있도록 구조를 만드는 것이 중요하다고 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;3632&quot; data-start=&quot;3565&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3678&quot; data-start=&quot;3634&quot; data-ke-size=&quot;size16&quot;&gt;현재는 전체 구조와 UI 방향을 잡는 단계까지 진행했고,&lt;br /&gt;다음 단계에서는&lt;/p&gt;
&lt;p data-end=&quot;3761&quot; data-start=&quot;3680&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;홈 화면의 Card, GameRow, RankingList, ScoringLeaders 컴포넌트 분리 과정&lt;/b&gt;을 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;3761&quot; data-start=&quot;3680&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3827&quot; data-start=&quot;3763&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 통해&lt;br /&gt;UI 구조를 어떻게 나누고 재사용성을 높였는지에 대해&lt;br /&gt;좀 더 자세하게 다뤄볼 예정입니다.&lt;/p&gt;</description>
      <category>프로젝트 회고록</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/16</guid>
      <comments>https://dlsxo.tistory.com/16#entry16comment</comments>
      <pubDate>Fri, 1 May 2026 22:51:26 +0900</pubDate>
    </item>
    <item>
      <title>[후기/전시] World IT Show 2026 코엑스 관람 후기 - WIS</title>
      <link>https://dlsxo.tistory.com/15</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이번에는 &lt;b&gt;월드 IT Show 2026(World IT Show 2026)&lt;/b&gt;에 직접 다녀온 후기를 정리해보려고 합니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이번 박람회는 단순히 &amp;ldquo;최신 기술이 많았다&amp;rdquo;는 정도를 넘어서,&lt;br /&gt;현재 IT 업계가 어떤 방향으로 움직이고 있는지를 비교적 구체적으로 보여주는 자리라는 느낌이 강했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;특히 이번 행사에서 가장 인상 깊었던 키워드는 크게 두 가지였습니다.&lt;br /&gt;첫째는 &lt;b&gt;AI 에이전트(Agentic AI)&lt;/b&gt;,&lt;br /&gt;둘째는 &lt;b&gt;VR/XR, 3D 공간 기술과 같은 디지털 공간 계열 기술&lt;/b&gt;이었습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;예전에는 AI가 &amp;ldquo;무엇을 할 수 있다&amp;rdquo;는 기술 소개 중심으로 보였다면,&lt;br /&gt;이번 행사에서는 AI가 실제로 어떤 업무를 대신하고, 어떤 데이터를 연결하고, 어떤 사용자 경험으로 서비스되는지가 훨씬 구체적으로 보였습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이번 글에서는 월드 IT Show 2026 현장 분위기와 함께,&lt;br /&gt;직접 둘러보면서 인상 깊었던 흐름들을 후기 형식으로 정리해보겠습니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;1. 월드 IT Show 2026 전체 분위기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kGTFU/dJMcaib2peK/OTVkC0wXarMpNMJPBTTdn0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kGTFU/dJMcaib2peK/OTVkC0wXarMpNMJPBTTdn0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kGTFU/dJMcaib2peK/OTVkC0wXarMpNMJPBTTdn0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkGTFU%2FdJMcaib2peK%2FOTVkC0wXarMpNMJPBTTdn0%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이번 월드 IT Show 2026은 규모가 꽤 크고,&lt;br /&gt;전시장 구성도 한눈에 봐도 성격이 나뉘어 있다는 점이 인상적이었습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;행사 배치도를 보면 전시가 크게 &lt;b&gt;1F Hall A / Hall B&lt;/b&gt;, 그리고 &lt;b&gt;3F Hall C&lt;/b&gt;로 나뉘어 있었고,&lt;br /&gt;각 공간이 보여주는 분위기도 꽤 달랐습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WpOqY/dJMcaiiLDKc/izj6qbhNBeGvVfxrg7GPB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WpOqY/dJMcaiiLDKc/izj6qbhNBeGvVfxrg7GPB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WpOqY/dJMcaiiLDKc/izj6qbhNBeGvVfxrg7GPB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWpOqY%2FdJMcaiiLDKc%2Fizj6qbhNBeGvVfxrg7GPB1%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;414&quot; height=&quot;850&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;1F Hall A&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;ITRC 인재양성대전 2026, 2026 ICT 기술사업화 페스티벌, 어워드테크관, 글로벌관 등&lt;/li&gt;
&lt;li&gt;비교적 &lt;b&gt;연구&amp;middot;실증&amp;middot;기술사업화 성격&lt;/b&gt;이 강한 공간&lt;/li&gt;
&lt;li&gt;&lt;b&gt;1F Hall B&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Mingling Zone / Startup Pavilion&lt;/li&gt;
&lt;li&gt;AI &amp;amp; Digital Intelligence, ICT Convergence 중심의 &lt;b&gt;스타트업&amp;middot;융합기술 성격&lt;/b&gt;이 강한 공간&lt;/li&gt;
&lt;li&gt;&lt;b&gt;3F Hall C&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;에이전틱 AI, AI 플랫폼, K-AI 반도체 생태계관, Mobility, Smart Live, Data Tech, EnterTech 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대기업과 주요 플랫폼 중심의 메인 전시장&lt;/b&gt; 분위기가 강한 공간&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 같은 박람회 안에서도&lt;br /&gt;한쪽에서는 연구와 실증 기술을 보고,&lt;br /&gt;다른 한쪽에서는 실제 서비스화된 대형 부스를 볼 수 있다는 점이 좋았습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;2. 1층에서 확인한 기술 실증과 체험형 부스&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;1층을 둘러보면서 가장 먼저 느낀 점은,&lt;br /&gt;이 공간이 단순한 홍보형 전시장보다는 &lt;b&gt;기술 실증과 체험 중심의 공간&lt;/b&gt;에 더 가깝다는 것이었습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;ITRC 인재양성대전과 ICT 기술사업화 페스티벌이 함께 운영되고 있어서 그런지,&lt;br /&gt;기업 부스뿐 아니라 연구기관&amp;middot;대학&amp;middot;기술 실증형 전시가 많이 보였습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;직접 본 부스들 중에는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VR/XR 기반 가상 공간 체험&lt;/li&gt;
&lt;li&gt;국방 메타버스 플랫폼&lt;/li&gt;
&lt;li&gt;AI 기반 휴대용 3D 공간 정보 스캐너&lt;/li&gt;
&lt;li&gt;실시간 통역 및 기업 검증&lt;/li&gt;
&lt;li&gt;제조/운영 데이터 기반 AI 시스템&lt;/li&gt;
&lt;li&gt;산업형 ERP 및 데이터 대시보드&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;같이 **&amp;ldquo;이 기술이 실제로 어디에 쓰이는가&amp;rdquo;**를 보여주는 전시가 많았습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이 점이 흥미로웠던 이유는,&lt;br /&gt;기술이 추상적인 개념으로 제시되는 것이 아니라&lt;br /&gt;&lt;b&gt;공간, 산업, 공공, 제조, 업무 자동화&lt;/b&gt;처럼 비교적 명확한 사용처와 함께 전시되고 있었기 때문입니다&lt;br /&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mD7nm/dJMcagrIMT2/Mmt3WIFKStHC0TNBi3fC8k/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mD7nm/dJMcagrIMT2/Mmt3WIFKStHC0TNBi3fC8k/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mD7nm/dJMcagrIMT2/Mmt3WIFKStHC0TNBi3fC8k/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmD7nm%2FdJMcagrIMT2%2FMmt3WIFKStHC0TNBi3fC8k%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;3. VR/XR 및 메타버스 계열 기술 전시 흐름&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 행사를 보기 전에는 솔직히&lt;br /&gt;예전보다 메타버스라는 단어의 존재감이 많이 줄었을 것이라고 생각했습니다.&lt;br /&gt;그런데 실제 현장에서는 메타버스나 XR/VR 계열 기술이 완전히 사라진 것이 아니라,&lt;br /&gt;조금 더 &lt;b&gt;구체적인 목적을 가진 형태&lt;/b&gt;로 남아 있다는 인상을 받았습니다.&lt;br /&gt;예를 들어 현장에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VR 헤드셋을 이용한 가상 공간 체험&lt;/li&gt;
&lt;li&gt;&lt;b&gt;VR Concert&lt;/b&gt;처럼 고글을 착용하고 즐기는 콘텐츠형 체험&lt;/li&gt;
&lt;li&gt;&lt;b&gt;국방 메타버스 플랫폼&lt;/b&gt;처럼 특정 목적을 가진 시뮬레이션형 기술&lt;/li&gt;
&lt;li&gt;실제 공간을 스캔하고 데이터화하는 &lt;b&gt;3D 공간 정보 스캐너&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;제조 설비와 공간을 디지털로 구현한 3D 시각화/시뮬레이션&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;같은 전시가 눈에 띄었습니다.&lt;br /&gt;즉, 예전처럼 막연하게 &amp;ldquo;모든 것이 메타버스&amp;rdquo;라고 말하는 분위기보다는,&lt;br /&gt;지금은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;훈련&lt;/li&gt;
&lt;li&gt;시뮬레이션&lt;/li&gt;
&lt;li&gt;공간 시각화&lt;/li&gt;
&lt;li&gt;디지털 트윈&lt;/li&gt;
&lt;li&gt;몰입형 콘텐츠&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;처럼 &lt;b&gt;쓰임새가 구체적인 방향으로 정리되고 있다&lt;/b&gt;는 느낌이 더 강했습니다.&lt;br /&gt;특히 3D 공간 스캐너 부스는&lt;br /&gt;메타버스나 디지털 공간 기술이 단순히 보여주기용이 아니라,&lt;br /&gt;현실 공간을 데이터로 전환하고 시뮬레이션 환경까지 연결하는 기술이라는 점을 보여줘서 인상적이었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvA4ft/dJMcaiiLFSH/yhLNIP43CiIhkiq52GH4d1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvA4ft/dJMcaiiLFSH/yhLNIP43CiIhkiq52GH4d1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvA4ft/dJMcaiiLFSH/yhLNIP43CiIhkiq52GH4d1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvA4ft%2FdJMcaiiLFSH%2FyhLNIP43CiIhkiq52GH4d1%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYygbs/dJMcagFiiOu/0d4cINNmSLHeV37fk3ww7K/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYygbs/dJMcagFiiOu/0d4cINNmSLHeV37fk3ww7K/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYygbs/dJMcagFiiOu/0d4cINNmSLHeV37fk3ww7K/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYygbs%2FdJMcagFiiOu%2F0d4cINNmSLHeV37fk3ww7K%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XvI49/dJMcaf0DdlV/Xf6QTUVRJYxJGvxNWE3c2K/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XvI49/dJMcaf0DdlV/Xf6QTUVRJYxJGvxNWE3c2K/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XvI49/dJMcaf0DdlV/Xf6QTUVRJYxJGvxNWE3c2K/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXvI49%2FdJMcaf0DdlV%2FXf6QTUVRJYxJGvxNWE3c2K%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XT7JY/dJMcadIuLDd/AAuybsKfINScd24fAAY3A0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XT7JY/dJMcadIuLDd/AAuybsKfINScd24fAAY3A0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XT7JY/dJMcadIuLDd/AAuybsKfINScd24fAAY3A0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXT7JY%2FdJMcadIuLDd%2FAAuybsKfINScd24fAAY3A0%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKV6rG/dJMcabKLmVA/COTCoE879lSWbAi7It3nEK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKV6rG/dJMcabKLmVA/COTCoE879lSWbAi7It3nEK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKV6rG/dJMcabKLmVA/COTCoE879lSWbAi7It3nEK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKV6rG%2FdJMcabKLmVA%2FCOTCoE879lSWbAi7It3nEK%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;4. 산업형 AI와 공간 데이터 기술 전시 특징&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 행사에서는 일반 사용자 대상 서비스형 AI뿐 아니라,&lt;br /&gt;산업 현장과 운영 데이터에 붙는 AI도 꽤 많이 보였습니다.&lt;br /&gt;예를 들어&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제조 산업 실증 사례&lt;/li&gt;
&lt;li&gt;설비 정보 3D 시각화 시뮬레이션&lt;/li&gt;
&lt;li&gt;산업 부산물 및 자원 관리 어시스턴트&lt;/li&gt;
&lt;li&gt;제조 원가 예측/운영 데이터 기반 ERP&lt;/li&gt;
&lt;li&gt;시계열 데이터 기반 모니터링 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;같은 전시가 반복적으로 보였습니다.&lt;br /&gt;이런 부스들을 보면서 느낀 점은,&lt;br /&gt;AI가 이제 단순한 텍스트 생성 기능이 아니라&lt;br /&gt;&lt;b&gt;산업 현장 데이터와 연결되어 의사결정을 돕는 방향&lt;/b&gt;으로 많이 가고 있다는 것이었습니다.&lt;br /&gt;특히 설비나 공간을 단순 표로 보여주는 것이 아니라,&lt;br /&gt;3D 시각화나 디지털 화면으로 함께 보여주는 사례가 많아서&lt;br /&gt;AI와 데이터 시각화, 디지털 트윈 계열 기술이 함께 움직이고 있다는 인상도 받았습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOedr/dJMcagSObjb/c0BCMeE0jTKlgoL8tvzCe0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOedr/dJMcagSObjb/c0BCMeE0jTKlgoL8tvzCe0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOedr/dJMcagSObjb/c0BCMeE0jTKlgoL8tvzCe0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOedr%2FdJMcagSObjb%2Fc0BCMeE0jTKlgoL8tvzCe0%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuJh2o/dJMcadhs4PS/Q9OE6MnCfBUE85P0wBhzGk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuJh2o/dJMcadhs4PS/Q9OE6MnCfBUE85P0wBhzGk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuJh2o/dJMcadhs4PS/Q9OE6MnCfBUE85P0wBhzGk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuJh2o%2FdJMcadhs4PS%2FQ9OE6MnCfBUE85P0wBhzGk%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpqY0n/dJMcaiXkT97/wJbeHgFdKLY6IHJ9NHwtV1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpqY0n/dJMcaiXkT97/wJbeHgFdKLY6IHJ9NHwtV1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpqY0n/dJMcaiXkT97/wJbeHgFdKLY6IHJ9NHwtV1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpqY0n%2FdJMcaiXkT97%2FwJbeHgFdKLY6IHJ9NHwtV1%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diGYLW/dJMcaaSBp2K/kzgCAgJxL2pCTD0GX34To0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diGYLW/dJMcaaSBp2K/kzgCAgJxL2pCTD0GX34To0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diGYLW/dJMcaaSBp2K/kzgCAgJxL2pCTD0GX34To0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiGYLW%2FdJMcaaSBp2K%2FkzgCAgJxL2pCTD0GX34To0%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5GDF3/dJMcacv7wjL/9AuUZBfl24nXWucuBwAox1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5GDF3/dJMcacv7wjL/9AuUZBfl24nXWucuBwAox1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5GDF3/dJMcacv7wjL/9AuUZBfl24nXWucuBwAox1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5GDF3%2FdJMcacv7wjL%2F9AuUZBfl24nXWucuBwAox1%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAi4vv/dJMcaaZk1qe/dr7aJC1QyQK8YhZdh7adUk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAi4vv/dJMcaaZk1qe/dr7aJC1QyQK8YhZdh7adUk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAi4vv/dJMcaaZk1qe/dr7aJC1QyQK8YhZdh7adUk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAi4vv%2FdJMcaaZk1qe%2Fdr7aJC1QyQK8YhZdh7adUk%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;5. AI 에이전트 중심의 서비스 변화&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 월드 IT Show 2026에서 가장 많이 느낀 키워드를 하나 고르라고 하면,&lt;br /&gt;저는 &lt;b&gt;AI 에이전트&lt;/b&gt;라고 말할 것 같습니다.&lt;br /&gt;이번에 본 부스들을 떠올려보면 단순히 &amp;ldquo;AI가 답변해준다&amp;rdquo;는 수준보다,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문서를 읽고&lt;/li&gt;
&lt;li&gt;사내 데이터를 연결하고&lt;/li&gt;
&lt;li&gt;메시지를 요약하고&lt;/li&gt;
&lt;li&gt;통화 내용을 정리하고&lt;/li&gt;
&lt;li&gt;민원을 안내하고&lt;/li&gt;
&lt;li&gt;상담을 보조하고&lt;/li&gt;
&lt;li&gt;반복 업무를 줄여주는&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;형태의 AI가 굉장히 많이 보였습니다.&lt;br /&gt;즉, 질문에 답하는 챗봇보다는&lt;br /&gt;&lt;b&gt;실제로 무언가를 대신 처리해주는 AI&lt;/b&gt;가 많이 등장하고 있다는 느낌이었습니다.&lt;br /&gt;이 흐름은 스타트업 부스에서도 보였고,&lt;br /&gt;업무 자동화 전문 개발사나 문서/ERP/그룹웨어 통합형 AI 솔루션에서도 보였으며,&lt;br /&gt;공공 안내형 AI, 상담형 AI, 음성 AI 부스에서도 공통적으로 드러났습니다.&lt;br /&gt;그래서 이번 행사에서 본 AI는&lt;br /&gt;단순한 생성형 AI 소개가 아니라&lt;br /&gt;&lt;b&gt;&amp;ldquo;행동하는 AI&amp;rdquo;, &amp;ldquo;업무를 도와주는 AI&amp;rdquo;, &amp;ldquo;서비스 안으로 들어간 AI&amp;rdquo;&lt;/b&gt;에 훨씬 가까웠습니다.&lt;br /&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cn9MO/dJMcajonm3k/ZdOzFSC9ocSSdYFl2fvjbk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cn9MO/dJMcajonm3k/ZdOzFSC9ocSSdYFl2fvjbk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cn9MO/dJMcajonm3k/ZdOzFSC9ocSSdYFl2fvjbk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCn9MO%2FdJMcajonm3k%2FZdOzFSC9ocSSdYFl2fvjbk%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tOzC4/dJMcajaSKyC/kaWuPPjPkYUMQ5YO5F2KG0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tOzC4/dJMcajaSKyC/kaWuPPjPkYUMQ5YO5F2KG0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tOzC4/dJMcajaSKyC/kaWuPPjPkYUMQ5YO5F2KG0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtOzC4%2FdJMcajaSKyC%2FkaWuPPjPkYUMQ5YO5F2KG0%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vNlSj/dJMcahD9fzK/m5KDABZo4Pkhuf3WXuIc4k/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vNlSj/dJMcahD9fzK/m5KDABZo4Pkhuf3WXuIc4k/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vNlSj/dJMcahD9fzK/m5KDABZo4Pkhuf3WXuIc4k/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvNlSj%2FdJMcahD9fzK%2Fm5KDABZo4Pkhuf3WXuIc4k%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;6. 대기업 부스에서 확인한 AI 에이전트 흐름&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 행사에서 특히 인상 깊었던 부분은,&lt;br /&gt;AI 에이전트가 스타트업이나 솔루션 기업의 키워드를 넘어서&lt;br /&gt;&lt;b&gt;대기업의 메인 메시지로도 올라오고 있었다&lt;/b&gt;는 점입니다.&lt;br /&gt;배치도를 보면 3층 Hall C에는&lt;br /&gt;KT, SK텔레콤, LG전자, 삼성, 카카오 같은 주요 기업들이 큰 부스를 구성하고 있었고,&lt;br /&gt;실제 현장 분위기도 1층과는 다르게 &lt;b&gt;서비스와 플랫폼 중심&lt;/b&gt;의 메시지가 강했습니다.&lt;br /&gt;그중에서도 개인적으로 가장 눈에 띈 것은 &lt;b&gt;카카오 Kanana 부스&lt;/b&gt;였습니다.&lt;br /&gt;현장에서는&lt;br /&gt;&lt;b&gt;&amp;ldquo;5천만의 일상 속 Agentic AI&amp;rdquo;&lt;/b&gt;&lt;br /&gt;라는 문구가 전면에 걸려 있었고,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오늘의 브리핑&lt;/li&gt;
&lt;li&gt;메시지 요약&lt;/li&gt;
&lt;li&gt;통화 요약&lt;/li&gt;
&lt;li&gt;일정 챙김&lt;/li&gt;
&lt;li&gt;대화 맥락 정리&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;같이 사용자의 일상 속에서 AI가 직접 보조하는 기능들을 보여주고 있었습니다.&lt;br /&gt;이 부분이 흥미로웠던 이유는,&lt;br /&gt;AI 에이전트라는 개념이 이제 일부 기술 데모 수준이 아니라&lt;br /&gt;&lt;b&gt;실제 메신저, 플랫폼, 일상 서비스 UX 안으로 들어가고 있다&lt;/b&gt;는 점을 보여줬기 때문입니다.&lt;br /&gt;예전에는 AI가 &amp;ldquo;신기한 기능&amp;rdquo;처럼 보였다면,&lt;br /&gt;이번에는 &amp;ldquo;내가 실제로 쓰게 될 서비스&amp;rdquo;처럼 보였다는 점에서 차이가 있었습니다.&lt;br /&gt;또 다른 대기업 부스들도&lt;br /&gt;AI를 단순히 기술 설명으로 보여주기보다&lt;br /&gt;서비스와 사용 경험 단위로 연결하려는 시도가 강하게 느껴졌습니다.&lt;br /&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUIUK2/dJMcabDXDaA/45G0L0qeJh6C8c8JK1DjMK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUIUK2/dJMcabDXDaA/45G0L0qeJh6C8c8JK1DjMK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUIUK2/dJMcabDXDaA/45G0L0qeJh6C8c8JK1DjMK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUIUK2%2FdJMcabDXDaA%2F45G0L0qeJh6C8c8JK1DjMK%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mVI6j/dJMcaf7piBd/wCYOv0aX72OTr3xODChJs1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mVI6j/dJMcaf7piBd/wCYOv0aX72OTr3xODChJs1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mVI6j/dJMcaf7piBd/wCYOv0aX72OTr3xODChJs1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmVI6j%2FdJMcaf7piBd%2FwCYOv0aX72OTr3xODChJs1%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4i1te/dJMcahjUk86/hCgB2GMkhS7pu67VIZwtrK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4i1te/dJMcahjUk86/hCgB2GMkhS7pu67VIZwtrK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4i1te/dJMcahjUk86/hCgB2GMkhS7pu67VIZwtrK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4i1te%2FdJMcahjUk86%2FhCgB2GMkhS7pu67VIZwtrK%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bizJN9/dJMcafl39RU/GKqzkhZxN4ebHtHsmeU5nK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bizJN9/dJMcafl39RU/GKqzkhZxN4ebHtHsmeU5nK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bizJN9/dJMcafl39RU/GKqzkhZxN4ebHtHsmeU5nK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbizJN9%2FdJMcafl39RU%2FGKqzkhZxN4ebHtHsmeU5nK%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br3FFY/dJMcagrINHA/YU8p1KMJhVA8jcadyKKMX1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br3FFY/dJMcagrINHA/YU8p1KMJhVA8jcadyKKMX1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br3FFY/dJMcagrINHA/YU8p1KMJhVA8jcadyKKMX1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr3FFY%2FdJMcagrINHA%2FYU8p1KMJhVA8jcadyKKMX1%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGaZqC/dJMcajhD7sC/PsBfzBoihT7Bc2dbjHHHu0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGaZqC/dJMcajhD7sC/PsBfzBoihT7Bc2dbjHHHu0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGaZqC/dJMcajhD7sC/PsBfzBoihT7Bc2dbjHHHu0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGaZqC%2FdJMcajhD7sC%2FPsBfzBoihT7Bc2dbjHHHu0%2Fimg.webp&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;3000&quot; height=&quot;4000&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&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;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z4r7m/dJMcajaSKIo/ngTKlhTo7ABb2tyEXSbRC1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z4r7m/dJMcajaSKIo/ngTKlhTo7ABb2tyEXSbRC1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z4r7m/dJMcajaSKIo/ngTKlhTo7ABb2tyEXSbRC1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ4r7m%2FdJMcajaSKIo%2FngTKlhTo7ABb2tyEXSbRC1%2Fimg.webp&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;4000&quot; height=&quot;3000&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;7. 기억에 남았던 주요 부스&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 행사에서 기억에 남았던 부스를 몇 곳만 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;7.1 Kanana&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;대기업도 AI 에이전트를 매우 직접적으로 이야기하고 있다는 점이 인상적이었습니다.&lt;br /&gt;AI를 어렵게 설명하기보다, 브리핑&amp;middot;요약&amp;middot;정리&amp;middot;보조 같은 일상 언어로 풀어낸 점도 눈에 띄었습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;7.2 DIMENVUE&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;3D 공간 정보 스캐너와 공간 데이터 기반 기술이 꽤 실용적으로 보였습니다.&lt;br /&gt;메타버스나 디지털 트윈이 단순한 개념이 아니라, 현실 공간을 실제 데이터로 바꾸는 기술이라는 점을 보여주는 부스였습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;7.3 Typecast&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;AI 보이스가 이제 단순 데모가 아니라 API와 자동화 도구 형태로 실제 서비스에 연결되고 있다는 점이 흥미로웠습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;7.4 WISSLY&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;사내 문서, ERP, 그룹웨어 등을 AI로 연결하는 흐름이 강하게 느껴졌습니다.&lt;br /&gt;기업 내부 데이터 활용형 AI 에이전트의 방향을 보여주는 사례라고 생각했습니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;7.5 VR Concert&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;XR이 여전히 매력적인 체험형 콘텐츠로 남아 있다는 점을 보여준 부스였습니다.&lt;br /&gt;고글을 착용하고 직접 몰입해서 즐기는 경험은 여전히 강한 현장성을 가지고 있었습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;8. 월드 IT Show 2026을 둘러본 후 느낀 점&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 월드 IT Show 2026을 직접 둘러보며 느낀 점을 정리해보았습니다.&lt;br /&gt;이번 행사는 단순히 &amp;ldquo;최신 기술이 많았다&amp;rdquo;는 정도로 끝나는 박람회가 아니라,&lt;br /&gt;현재 IT 업계가 어떤 방향으로 움직이고 있는지를 비교적 선명하게 보여주는 자리였습니다.&lt;br /&gt;특히 가장 인상 깊었던 점은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AI가 단순 생성 기능을 넘어서 &lt;b&gt;에이전트형 서비스&lt;/b&gt;로 진화하고 있다는 점&lt;/li&gt;
&lt;li&gt;대기업도 AI 에이전트를 실제 서비스와 일상 UX 안으로 연결하려는 흐름을 보이고 있다는 점&lt;/li&gt;
&lt;li&gt;VR/XR과 메타버스 계열 기술이 사라진 것이 아니라, 더 구체적인 목적을 가진 형태로 남아 있다는 점&lt;/li&gt;
&lt;li&gt;산업형 AI, 3D 공간 데이터, 디지털 트윈 기술이 함께 커지고 있다는 점&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이번 월드 IT Show 2026은&lt;br /&gt;&amp;ldquo;AI가 많았다&amp;rdquo;는 행사라기보다,&lt;br /&gt;&lt;b&gt;AI가 실제 서비스와 산업 현장에 어떤 방식으로 들어가고 있는지를 보여준 행사&lt;/b&gt;에 더 가까웠다고 생각합니다.&lt;br /&gt;앞으로 이러한 흐름이 실제 제품과 서비스 안에서 어떻게 자리 잡을지 더 궁금해졌습니다.&lt;br /&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>일상</category>
      <category>agenticai</category>
      <category>AI에이전트</category>
      <category>AI트렌드</category>
      <category>VR</category>
      <category>WIS2026</category>
      <category>WorldITSHOW</category>
      <category>디지털트윈</category>
      <category>생성형AI</category>
      <category>월드IT쇼</category>
      <category>월드IT쇼2026</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/15</guid>
      <comments>https://dlsxo.tistory.com/15#entry15comment</comments>
      <pubDate>Sun, 26 Apr 2026 21:22:30 +0900</pubDate>
    </item>
    <item>
      <title>사이드 프로젝트에 Docker 적용해보기 (self-interior-guide)</title>
      <link>https://dlsxo.tistory.com/14</link>
      <description>&lt;p data-end=&quot;150&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;이전 글에서는 Docker의 기본 개념과 전체 구조를 정리해봤습니다.&lt;/p&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;240&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는&lt;br /&gt;실제 프로젝트인 &lt;b&gt;self-interior-guide에 Docker를 적용해본 과정&lt;/b&gt;을 정리해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;240&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;387&quot; data-start=&quot;316&quot; data-ke-size=&quot;size16&quot;&gt;앞선 글에서 Docker의 개념을 이해했다면,&lt;br /&gt;이번에는 그 개념들이 실제로 어떻게 동작하는지 확인하는 단계라고 보면 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;387&quot; data-start=&quot;316&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;393&quot; data-ke-size=&quot;size16&quot;&gt;다만 이번 적용은&lt;br /&gt;&lt;b&gt;실제 배포를 위한 것이 아니라 테스트 및 학습 목적&lt;/b&gt;으로 진행했습니다.&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;393&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;562&quot; data-start=&quot;453&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트는&lt;br /&gt;&amp;nbsp;**&lt;span&gt;&lt;span&gt;Vercel&lt;/span&gt;&lt;/span&gt;**을 통해 배포하고 있고,&lt;br /&gt;Docker는 실행 환경을 직접 구성해보기 위한 용도로 사용했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;567&quot; data-start=&quot;564&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;592&quot; data-start=&quot;569&quot; data-section-id=&quot;mivea8&quot;&gt;1. Docker 적용을 시작하기 전에&lt;/h1&gt;
&lt;p data-end=&quot;645&quot; data-start=&quot;594&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 적용하기 전에&lt;br /&gt;먼저 Docker가 정상적으로 설치되어 있는지 확인했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663678357&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker -v&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;325&quot; data-origin-height=&quot;44&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dl2iiY/dJMcadPcDQE/fqsbUyXWkKcyK1HMbnPjv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dl2iiY/dJMcadPcDQE/fqsbUyXWkKcyK1HMbnPjv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dl2iiY/dJMcadPcDQE/fqsbUyXWkKcyK1HMbnPjv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdl2iiY%2FdJMcadPcDQE%2FfqsbUyXWkKcyK1HMbnPjv0%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;325&quot; height=&quot;44&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;44&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;743&quot; data-start=&quot;705&quot; data-ke-size=&quot;size16&quot;&gt;Docker가 정상적으로 설치되어 있다면&lt;br /&gt;버전 정보가 출력됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;748&quot; data-start=&quot;745&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;780&quot; data-start=&quot;750&quot; data-section-id=&quot;1j8keuy&quot;&gt;2. hello-world로 Docker 동작 확인&lt;/h1&gt;
&lt;p data-end=&quot;840&quot; data-start=&quot;782&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 Docker가 실제로 동작하는지 확인하기 위해&lt;br /&gt;hello-world 이미지를 실행해봤습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1776663793809&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run hello-world&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;719&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Wl9A/dJMcafzyRmK/jkTWky7RDof94KzhhhaA71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Wl9A/dJMcafzyRmK/jkTWky7RDof94KzhhhaA71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Wl9A/dJMcafzyRmK/jkTWky7RDof94KzhhhaA71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Wl9A%2FdJMcafzyRmK%2FjkTWky7RDof94KzhhhaA71%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;719&quot; height=&quot;501&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;955&quot; data-start=&quot;918&quot; data-ke-size=&quot;size16&quot;&gt;이 과정에서 Docker 내부에서는 다음과 같은 흐름이 발생합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1012&quot; data-start=&quot;957&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;980&quot; data-start=&quot;957&quot; data-section-id=&quot;x975ba&quot;&gt;Docker Hub에서 이미지 pull&lt;/li&gt;
&lt;li data-end=&quot;990&quot; data-start=&quot;981&quot; data-section-id=&quot;1r2eboc&quot;&gt;컨테이너 생성&lt;/li&gt;
&lt;li data-end=&quot;1000&quot; data-start=&quot;991&quot; data-section-id=&quot;1r2dyd9&quot;&gt;컨테이너 실행&lt;/li&gt;
&lt;li data-end=&quot;1008&quot; data-start=&quot;1001&quot; data-section-id=&quot;hnrqf1&quot;&gt;결과 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1062&quot; data-start=&quot;1014&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이 한 번의 실행으로&lt;br /&gt;Docker의 전체 흐름을 간단하게 확인할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1067&quot; data-start=&quot;1064&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1085&quot; data-start=&quot;1069&quot; data-section-id=&quot;png1ga&quot;&gt;3. 프로젝트 이미지 빌드&lt;/h1&gt;
&lt;p data-end=&quot;1129&quot; data-start=&quot;1087&quot; data-ke-size=&quot;size16&quot;&gt;이제 실제 프로젝트를 Docker로 실행하기 위해&lt;br /&gt;이미지를 생성했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663815957&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build -t self-interior-guide .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;1422&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x8jHx/dJMcadIr1e9/2wQ4oVk8v0L3gRss7LZh40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x8jHx/dJMcadIr1e9/2wQ4oVk8v0L3gRss7LZh40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x8jHx/dJMcadIr1e9/2wQ4oVk8v0L3gRss7LZh40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx8jHx%2FdJMcadIr1e9%2F2wQ4oVk8v0L3gRss7LZh40%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;1422&quot; height=&quot;553&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1224&quot; data-start=&quot;1182&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1268&quot; data-start=&quot;1230&quot; data-ke-size=&quot;size16&quot;&gt;빌드 과정에서는&lt;br /&gt;Dockerfile을 기준으로 이미지가 생성되며,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1304&quot; data-start=&quot;1270&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1282&quot; data-start=&quot;1270&quot; data-section-id=&quot;1uqh5n4&quot;&gt;Node 환경 구성&lt;/li&gt;
&lt;li data-end=&quot;1291&quot; data-start=&quot;1283&quot; data-section-id=&quot;dq5ohk&quot;&gt;패키지 설치&lt;/li&gt;
&lt;li data-end=&quot;1304&quot; data-start=&quot;1292&quot; data-section-id=&quot;1awudks&quot;&gt;프로젝트 파일 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1326&quot; data-start=&quot;1306&quot; data-ke-size=&quot;size16&quot;&gt;와 같은 과정이 단계별로 실행됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;1331&quot; data-start=&quot;1328&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1362&quot; data-start=&quot;1333&quot; data-section-id=&quot;1e8h44p&quot;&gt;4. 실행 시 발생한 문제 (Node 버전 이슈)&lt;/h1&gt;
&lt;p data-end=&quot;1403&quot; data-start=&quot;1364&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 생성한 후 컨테이너를 실행했지만&lt;br /&gt;바로 문제가 발생했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663843574&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -p 5173:5173 self-interior-guide&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;1418&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nA2Y3/dJMcabjDOEh/HnOFWxRC3MDaYudUdaa0KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nA2Y3/dJMcabjDOEh/HnOFWxRC3MDaYudUdaa0KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nA2Y3/dJMcabjDOEh/HnOFWxRC3MDaYudUdaa0KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnA2Y3%2FdJMcabjDOEh%2FHnOFWxRC3MDaYudUdaa0KK%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;1418&quot; height=&quot;324&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1519&quot; data-start=&quot;1500&quot; data-ke-size=&quot;size16&quot;&gt;에러 내용을 보면 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663865902&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Vite requires Node.js version 20.19 or 22.12+&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1638&quot; data-start=&quot;1584&quot; data-ke-size=&quot;size16&quot;&gt;즉, Dockerfile에서 사용한 Node 버전이&lt;br /&gt;프로젝트 요구사항과 맞지 않았던 것입니다.&lt;/p&gt;
&lt;p data-end=&quot;1674&quot; data-start=&quot;1644&quot; data-ke-size=&quot;size16&quot;&gt;이 부분을 통해 확인할 수 있는 점은 다음과 같습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1723&quot; data-start=&quot;1676&quot; data-ke-style=&quot;style3&quot;&gt;Docker도 결국 실행 환경이기 때문에&lt;br /&gt;런타임 버전이 매우 중요하다&lt;/blockquote&gt;
&lt;hr data-end=&quot;1728&quot; data-start=&quot;1725&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1754&quot; data-start=&quot;1730&quot; data-section-id=&quot;9ug8re&quot;&gt;5. Dockerfile 수정 후 재빌드&lt;/h1&gt;
&lt;p data-end=&quot;1790&quot; data-start=&quot;1756&quot; data-ke-size=&quot;size16&quot;&gt;문제를 해결하기 위해&lt;br /&gt;Node 버전을 22로 수정했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663928224&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM node:22-alpine&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1853&quot; data-start=&quot;1835&quot; data-ke-size=&quot;size16&quot;&gt;이후 다시 이미지를 빌드했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663960619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build -t self-interior-guide .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;1418&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJSoow/dJMcagL0FTE/HZJCG1gEGHLQQQ7Tobb59k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJSoow/dJMcagL0FTE/HZJCG1gEGHLQQQ7Tobb59k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJSoow/dJMcagL0FTE/HZJCG1gEGHLQQQ7Tobb59k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJSoow%2FdJMcagL0FTE%2FHZJCG1gEGHLQQQ7Tobb59k%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;1418&quot; height=&quot;439&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;1950&quot; data-start=&quot;1947&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1965&quot; data-start=&quot;1952&quot; data-section-id=&quot;9xib8q&quot;&gt;6. 정상 실행 확인&lt;/h1&gt;
&lt;p data-end=&quot;1988&quot; data-start=&quot;1967&quot; data-ke-size=&quot;size16&quot;&gt;수정 후 다시 컨테이너를 실행했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663976969&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -p 5173:5173 self-interior-guide&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&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;1389&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgtGGo/dJMcahc3s9S/MEx1P8URaugFtUqplU8E70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgtGGo/dJMcahc3s9S/MEx1P8URaugFtUqplU8E70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgtGGo/dJMcahc3s9S/MEx1P8URaugFtUqplU8E70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgtGGo%2FdJMcahc3s9S%2FMEx1P8URaugFtUqplU8E70%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;1389&quot; height=&quot;229&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2115&quot; data-start=&quot;2080&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 실행되며&lt;br /&gt;다음과 같은 결과를 확인할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776663990050&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Local: http://localhost:5173&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2200&quot; data-start=&quot;2163&quot; data-ke-size=&quot;size16&quot;&gt;즉, 컨테이너 환경에서도&lt;br /&gt;로컬과 동일하게 프로젝트가 실행됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;2205&quot; data-start=&quot;2202&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2235&quot; data-start=&quot;2207&quot; data-section-id=&quot;s3vklw&quot;&gt;7. Docker Desktop에서 이미지 확인&lt;/h1&gt;
&lt;p data-end=&quot;2277&quot; data-start=&quot;2237&quot; data-ke-size=&quot;size16&quot;&gt;Docker Desktop에서도&lt;br /&gt;생성된 이미지를 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;873&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L0uS0/dJMcabDUYy2/iCBAE4lruNfZpu3gLkc5C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L0uS0/dJMcabDUYy2/iCBAE4lruNfZpu3gLkc5C0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L0uS0/dJMcabDUYy2/iCBAE4lruNfZpu3gLkc5C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL0uS0%2FdJMcabDUYy2%2FiCBAE4lruNfZpu3gLkc5C0%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;1264&quot; height=&quot;873&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;873&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2354&quot; data-start=&quot;2329&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2354&quot; data-start=&quot;2329&quot; data-ke-size=&quot;size16&quot;&gt;여기서 확인할 수 있는 점은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2432&quot; data-start=&quot;2356&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2387&quot; data-start=&quot;2356&quot; data-section-id=&quot;m28m8m&quot;&gt;self-interior-guide 이미지 생성 완료&lt;/li&gt;
&lt;li data-end=&quot;2408&quot; data-start=&quot;2388&quot; data-section-id=&quot;435dxt&quot;&gt;hello-world 이미지 존재&lt;/li&gt;
&lt;li data-end=&quot;2428&quot; data-start=&quot;2409&quot; data-section-id=&quot;fheop3&quot;&gt;동일 이미지에 대한 tag 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2471&quot; data-start=&quot;2434&quot; data-ke-size=&quot;size16&quot;&gt;즉, CLI에서 생성한 결과를&lt;br /&gt;GUI에서도 확인할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2476&quot; data-start=&quot;2473&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2502&quot; data-start=&quot;2478&quot; data-section-id=&quot;21ljia&quot;&gt;8. Docker Hub에 이미지 업로드&lt;/h1&gt;
&lt;p data-end=&quot;2554&quot; data-start=&quot;2504&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 Docker Hub에 업로드하면&lt;br /&gt;다른 환경에서도 동일하게 실행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTvs7/dJMb99MPBm7/Pd9eKrkZ57SBHkqJR7Dkjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTvs7/dJMb99MPBm7/Pd9eKrkZ57SBHkqJR7Dkjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTvs7/dJMb99MPBm7/Pd9eKrkZ57SBHkqJR7Dkjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTvs7%2FdJMb99MPBm7%2FPd9eKrkZ57SBHkqJR7Dkjk%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;1260&quot; height=&quot;872&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2642&quot; data-start=&quot;2600&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2642&quot; data-start=&quot;2600&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 업로드된 이미지는&lt;br /&gt;다른 환경에서 다음과 같이 사용할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776664028795&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker pull ryuintae/self-interior-guide
docker run -p 5173:5173 ryuintae/self-interior-guide&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2754&quot; data-start=&quot;2751&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;123&quot; data-start=&quot;92&quot; data-section-id=&quot;9zs2uk&quot;&gt;9. Docker 배포 방식 (개발 vs 운영 관점)&lt;/h1&gt;
&lt;p data-end=&quot;178&quot; data-start=&quot;125&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 사용하다 보면&lt;br /&gt;단순히 이미지를 만들고 실행하는 것에서 끝나는 것이 아니라,&lt;/p&gt;
&lt;blockquote data-end=&quot;232&quot; data-start=&quot;180&quot; data-ke-style=&quot;style2&quot;&gt;누가 어떤 목적에서 사용하느냐에 따라 방식이 달라진다는 점을 확인할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-end=&quot;289&quot; data-start=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;289&quot; data-start=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;크게 보면&lt;br /&gt;개발 환경과 운영 환경, 이렇게 두 가지 관점으로 나누어 이해할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;294&quot; data-start=&quot;291&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;320&quot; data-start=&quot;296&quot; data-section-id=&quot;wyjilv&quot; data-ke-size=&quot;size26&quot;&gt;9.1 개발 환경 (개발자 협업 기준)&lt;/h2&gt;
&lt;p data-end=&quot;393&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;개발 단계에서는 보통&lt;br /&gt;&lt;b&gt;이미지를 공유하기보다는 소스코드와 Dockerfile을 함께 공유하는 방식으로 진행합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;415&quot; data-start=&quot;399&quot; data-ke-size=&quot;size16&quot;&gt;전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776666426597&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;소스코드 + Dockerfile 공유
&amp;rarr; 각자 docker build
&amp;rarr; 로컬에서 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;495&quot; data-ke-size=&quot;size16&quot;&gt;왜 이런 방식을 사용할까요?&lt;/p&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;516&quot; data-ke-size=&quot;size16&quot;&gt;개발 단계에서는 프로젝트가 계속 바뀌기 때문입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;603&quot; data-start=&quot;546&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;562&quot; data-start=&quot;546&quot; data-section-id=&quot;okop3d&quot;&gt;기능이 추가되기도 하고&lt;/li&gt;
&lt;li data-end=&quot;579&quot; data-start=&quot;563&quot; data-section-id=&quot;hwcvvl&quot;&gt;버그를 수정하기도 하며&lt;/li&gt;
&lt;li data-end=&quot;599&quot; data-start=&quot;580&quot; data-section-id=&quot;1saely3&quot;&gt;의존성이 변경되기도 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;668&quot; data-start=&quot;605&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 코드가 자주 바뀌는 상황에서는&lt;br /&gt;매번 이미지를 새로 만들어 공유하는 것이 오히려 비효율적일 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;746&quot; data-start=&quot;674&quot; data-ke-size=&quot;size16&quot;&gt;그래서 개발 환경에서는&lt;br /&gt;&lt;b&gt;이미지 자체를 공유하기보다, 동일한 실행 환경을 맞추는 데 Docker를 활용하게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;751&quot; data-start=&quot;748&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;775&quot; data-start=&quot;753&quot; data-section-id=&quot;dmralq&quot; data-ke-size=&quot;size23&quot;&gt;개발 환경에서 Docker의 역할&lt;/h3&gt;
&lt;p data-end=&quot;829&quot; data-start=&quot;777&quot; data-ke-size=&quot;size16&quot;&gt;개발 환경에서 Docker의 가장 큰 역할은&lt;br /&gt;&lt;b&gt;환경 통일&lt;/b&gt;이라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;872&quot; data-start=&quot;835&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 협업을 하다 보면 다음과 같은 문제가 생길 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;960&quot; data-start=&quot;874&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;894&quot; data-start=&quot;874&quot; data-section-id=&quot;7kw21g&quot;&gt;Node 버전이 다를 수 있고&lt;/li&gt;
&lt;li data-end=&quot;920&quot; data-start=&quot;895&quot; data-section-id=&quot;7lzfi3&quot;&gt;npm 패키지 충돌이 발생할 수 있으며&lt;/li&gt;
&lt;li data-end=&quot;956&quot; data-start=&quot;921&quot; data-section-id=&quot;2c77s3&quot;&gt;운영체제 차이로 인해 실행 결과가 달라질 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;962&quot; data-ke-size=&quot;size16&quot;&gt;이런 문제를 줄이기 위해&lt;br /&gt;Dockerfile을 기준으로 실행 환경을 고정하게 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1017&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;br /&gt;같은 소스코드를 받아도&lt;br /&gt;각 개발자가 같은 방식으로 이미지를 빌드하고 실행할 수 있도록 만드는 것입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1086&quot; data-start=&quot;1083&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1100&quot; data-start=&quot;1088&quot; data-section-id=&quot;s1j8v2&quot; data-ke-size=&quot;size23&quot;&gt;실제 협업 흐름&lt;/h3&gt;
&lt;p data-end=&quot;1131&quot; data-start=&quot;1102&quot; data-ke-size=&quot;size16&quot;&gt;실제 협업 흐름을 단순하게 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1776666457123&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Git clone
&amp;darr;
docker build
&amp;darr;
docker run&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1243&quot; data-start=&quot;1200&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면&lt;br /&gt;모든 개발자가 동일한 환경에서 프로젝트를 실행할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1248&quot; data-start=&quot;1245&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1259&quot; data-start=&quot;1250&quot; data-section-id=&quot;g19u0j&quot; data-ke-size=&quot;size23&quot;&gt;핵심 특징&lt;/h3&gt;
&lt;p data-end=&quot;1298&quot; data-start=&quot;1261&quot; data-ke-size=&quot;size16&quot;&gt;개발 환경에서의 Docker 사용 특징을 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1398&quot; data-start=&quot;1300&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1317&quot; data-start=&quot;1300&quot; data-section-id=&quot;19q0vr&quot;&gt;코드 수정이 가능합니다.&lt;/li&gt;
&lt;li data-end=&quot;1343&quot; data-start=&quot;1318&quot; data-section-id=&quot;1d3f6g6&quot;&gt;실행 환경만 Docker로 통일합니다.&lt;/li&gt;
&lt;li data-end=&quot;1373&quot; data-start=&quot;1344&quot; data-section-id=&quot;188qmv7&quot;&gt;이미지를 공유하기보다는 소스코드를 공유합니다.&lt;/li&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1374&quot; data-section-id=&quot;bjhhlu&quot;&gt;빠르게 반복 개발하는 데 적합합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1403&quot; data-start=&quot;1400&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1425&quot; data-start=&quot;1405&quot; data-section-id=&quot;1bdwam5&quot; data-ke-size=&quot;size26&quot;&gt;9.2 운영 환경 (배포 기준)&lt;/h2&gt;
&lt;p data-end=&quot;1453&quot; data-start=&quot;1427&quot; data-ke-size=&quot;size16&quot;&gt;반면 운영 환경에서는 방식이 완전히 달라집니다.&lt;/p&gt;
&lt;p data-end=&quot;1512&quot; data-start=&quot;1459&quot; data-ke-size=&quot;size16&quot;&gt;운영 단계에서는&lt;br /&gt;&lt;b&gt;소스코드를 전달하지 않고 이미지를 전달하는 방식으로 진행합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1534&quot; data-start=&quot;1518&quot; data-ke-size=&quot;size16&quot;&gt;전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776666472777&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Dockerfile &amp;rarr; build &amp;rarr; image 생성
&amp;rarr; Docker Hub push
&amp;rarr; 서버에서 pull &amp;rarr; 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1629&quot; data-start=&quot;1626&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1644&quot; data-start=&quot;1631&quot; data-section-id=&quot;1s48v86&quot; data-ke-size=&quot;size23&quot;&gt;왜 이렇게 할까?&lt;/h3&gt;
&lt;p data-end=&quot;1679&quot; data-start=&quot;1646&quot; data-ke-size=&quot;size16&quot;&gt;운영 환경에서는 개발 환경과 중요하게 보는 기준이 다릅니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1753&quot; data-start=&quot;1681&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1699&quot; data-start=&quot;1681&quot; data-section-id=&quot;13qkesx&quot;&gt;안정적으로 실행되어야 하고&lt;/li&gt;
&lt;li data-end=&quot;1721&quot; data-start=&quot;1700&quot; data-section-id=&quot;185bn0d&quot;&gt;항상 동일한 결과가 나와야 하며&lt;/li&gt;
&lt;li data-end=&quot;1749&quot; data-start=&quot;1722&quot; data-section-id=&quot;hksybv&quot;&gt;배포도 빠르고 일관되게 이루어져야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1815&quot; data-start=&quot;1755&quot; data-ke-size=&quot;size16&quot;&gt;즉, 운영 환경에서는&lt;br /&gt;코드를 수정하는 것보다&lt;br /&gt;&lt;b&gt;정확하게 실행되는 것 자체가 더 중요합니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1820&quot; data-start=&quot;1817&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1844&quot; data-start=&quot;1822&quot; data-section-id=&quot;rwwra3&quot; data-ke-size=&quot;size23&quot;&gt;운영 환경에서 Docker의 역할&lt;/h3&gt;
&lt;p data-end=&quot;1900&quot; data-start=&quot;1846&quot; data-ke-size=&quot;size16&quot;&gt;운영 환경에서 Docker의 역할은&lt;br /&gt;&lt;b&gt;완성된 실행 환경을 그대로 전달하는 것&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;1924&quot; data-start=&quot;1906&quot; data-ke-size=&quot;size16&quot;&gt;여기서 전달되는 이미지 안에는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1961&quot; data-start=&quot;1926&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1937&quot; data-start=&quot;1926&quot; data-section-id=&quot;3hq6p4&quot;&gt;Node 버전&lt;/li&gt;
&lt;li data-end=&quot;1947&quot; data-start=&quot;1938&quot; data-section-id=&quot;1hln7xo&quot;&gt;라이브러리&lt;/li&gt;
&lt;li data-end=&quot;1961&quot; data-start=&quot;1948&quot; data-section-id=&quot;1mogeek&quot;&gt;애플리케이션 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1978&quot; data-start=&quot;1963&quot; data-ke-size=&quot;size16&quot;&gt;가 모두 포함되어 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2056&quot; data-start=&quot;1984&quot; data-ke-size=&quot;size16&quot;&gt;즉, 서버에서는 소스코드를 다시 세팅하거나&lt;br /&gt;환경을 하나씩 맞출 필요 없이,&lt;br /&gt;이미지를 pull 받아 실행하기만 하면 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;2061&quot; data-start=&quot;2058&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2075&quot; data-start=&quot;2063&quot; data-section-id=&quot;mnmb9b&quot; data-ke-size=&quot;size23&quot;&gt;실제 운영 흐름&lt;/h3&gt;
&lt;p data-end=&quot;2103&quot; data-start=&quot;2077&quot; data-ke-size=&quot;size16&quot;&gt;운영 흐름을 단순하게 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1776666489989&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;개발 서버에서 build
&amp;darr;
Docker Hub push
&amp;darr;
운영 서버 pull
&amp;darr;
docker run&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2274&quot; data-start=&quot;2192&quot; data-ke-size=&quot;size16&quot;&gt;이 방식의 핵심은&lt;br /&gt;서버에서는 별도의 추가 설정 없이&lt;br /&gt;&lt;b&gt;이미지를 실행하는 것만으로 동일한 환경을 그대로 재현할 수 있다는 점&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;2279&quot; data-start=&quot;2276&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2290&quot; data-start=&quot;2281&quot; data-section-id=&quot;g19u0j&quot; data-ke-size=&quot;size23&quot;&gt;핵심 특징&lt;/h3&gt;
&lt;p data-end=&quot;2329&quot; data-start=&quot;2292&quot; data-ke-size=&quot;size16&quot;&gt;운영 환경에서의 Docker 사용 특징을 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2420&quot; data-start=&quot;2331&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2349&quot; data-start=&quot;2331&quot; data-section-id=&quot;18vb6jv&quot;&gt;코드 수정은 불가능합니다.&lt;/li&gt;
&lt;li data-end=&quot;2371&quot; data-start=&quot;2350&quot; data-section-id=&quot;166th4n&quot;&gt;환경과 코드가 함께 고정됩니다.&lt;/li&gt;
&lt;li data-end=&quot;2396&quot; data-start=&quot;2372&quot; data-section-id=&quot;1afc6dn&quot;&gt;이미지 기반으로 배포가 이루어집니다.&lt;/li&gt;
&lt;li data-end=&quot;2420&quot; data-start=&quot;2397&quot; data-section-id=&quot;1lbqgmp&quot;&gt;CI/CD와 연결하기에 적합합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2425&quot; data-start=&quot;2422&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2448&quot; data-start=&quot;2427&quot; data-section-id=&quot;1oe3e44&quot; data-ke-size=&quot;size26&quot;&gt;9.3 개발 vs 운영 차이 정리&lt;/h2&gt;
&lt;p data-end=&quot;2482&quot; data-start=&quot;2450&quot; data-ke-size=&quot;size16&quot;&gt;개발 환경과 운영 환경의 차이를 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2668&quot; data-start=&quot;2484&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구분&lt;/td&gt;
&lt;td&gt;개발 환경&lt;/td&gt;
&lt;td&gt;운영 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2550&quot; data-start=&quot;2534&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2539&quot; data-start=&quot;2534&quot;&gt;목적&lt;/td&gt;
&lt;td data-end=&quot;2544&quot; data-start=&quot;2539&quot; data-col-size=&quot;sm&quot;&gt;개발&lt;/td&gt;
&lt;td data-end=&quot;2550&quot; data-start=&quot;2544&quot; data-col-size=&quot;sm&quot;&gt;배포&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2573&quot; data-start=&quot;2551&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2559&quot; data-start=&quot;2551&quot;&gt;전달 방식&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2566&quot; data-start=&quot;2559&quot;&gt;소스코드&lt;/td&gt;
&lt;td data-end=&quot;2573&quot; data-start=&quot;2566&quot; data-col-size=&quot;sm&quot;&gt;이미지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2606&quot; data-start=&quot;2574&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2586&quot; data-start=&quot;2574&quot;&gt;Docker 역할&lt;/td&gt;
&lt;td data-end=&quot;2594&quot; data-start=&quot;2586&quot; data-col-size=&quot;sm&quot;&gt;환경 통일&lt;/td&gt;
&lt;td data-end=&quot;2606&quot; data-start=&quot;2594&quot; data-col-size=&quot;sm&quot;&gt;실행 환경 전달&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2624&quot; data-start=&quot;2607&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2612&quot; data-start=&quot;2607&quot;&gt;수정&lt;/td&gt;
&lt;td data-end=&quot;2617&quot; data-start=&quot;2612&quot; data-col-size=&quot;sm&quot;&gt;가능&lt;/td&gt;
&lt;td data-end=&quot;2624&quot; data-start=&quot;2617&quot; data-col-size=&quot;sm&quot;&gt;불가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2648&quot; data-start=&quot;2625&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2630&quot; data-start=&quot;2625&quot;&gt;속도&lt;/td&gt;
&lt;td data-end=&quot;2638&quot; data-start=&quot;2630&quot; data-col-size=&quot;sm&quot;&gt;빠른 반복&lt;/td&gt;
&lt;td data-end=&quot;2648&quot; data-start=&quot;2638&quot; data-col-size=&quot;sm&quot;&gt;안정적 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2668&quot; data-start=&quot;2649&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2657&quot; data-start=&quot;2649&quot;&gt;사용 위치&lt;/td&gt;
&lt;td data-end=&quot;2662&quot; data-start=&quot;2657&quot; data-col-size=&quot;sm&quot;&gt;로컬&lt;/td&gt;
&lt;td data-end=&quot;2668&quot; data-start=&quot;2662&quot; data-col-size=&quot;sm&quot;&gt;서버&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2673&quot; data-start=&quot;2670&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2695&quot; data-start=&quot;2675&quot; data-section-id=&quot;bqvbr3&quot; data-ke-size=&quot;size26&quot;&gt;9.4 이번 프로젝트 기준 적용&lt;/h2&gt;
&lt;p data-end=&quot;2797&quot; data-start=&quot;2697&quot; data-ke-size=&quot;size16&quot;&gt;self-interior-guide 프로젝트 기준으로 보면&lt;br /&gt;이번 Docker 적용은 운영 배포보다는&lt;br /&gt;&lt;b&gt;개발 및 학습 환경에 더 가까운 방식&lt;/b&gt;이라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2815&quot; data-start=&quot;2803&quot; data-ke-size=&quot;size16&quot;&gt;실제로 이번 과정에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2878&quot; data-start=&quot;2817&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2837&quot; data-start=&quot;2817&quot; data-section-id=&quot;bdy7ti&quot;&gt;Dockerfile을 작성했고&lt;/li&gt;
&lt;li data-end=&quot;2852&quot; data-start=&quot;2838&quot; data-section-id=&quot;1xyqjxo&quot;&gt;이미지를 빌드했으며&lt;/li&gt;
&lt;li data-end=&quot;2874&quot; data-start=&quot;2853&quot; data-section-id=&quot;5ov2cm&quot;&gt;로컬에서 직접 실행해보았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2922&quot; data-start=&quot;2880&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제 서비스는&lt;br /&gt;&lt;b&gt;Vercel&lt;/b&gt;을 통해 배포하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;3041&quot; data-start=&quot;2928&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이번 프로젝트에서는 Docker를&lt;br /&gt;실제 배포 도구로 사용한 것이 아니라,&lt;br /&gt;&lt;b&gt;실행 환경을 직접 구성하고 Docker의 동작 흐름을 이해해보기 위한 도구로 사용했다고 볼 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;3046&quot; data-start=&quot;3043&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3064&quot; data-start=&quot;3048&quot; data-section-id=&quot;yhdb06&quot; data-ke-size=&quot;size26&quot;&gt;9.5 한 줄로 정리하면&lt;/h2&gt;
&lt;p data-end=&quot;3080&quot; data-start=&quot;3066&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 다음과 같습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;3170&quot; data-start=&quot;3082&quot; data-ke-style=&quot;style2&quot;&gt;개발 환경에서는 환경을 맞추기 위해 Docker를 사용하고&lt;br /&gt;운영 환경에서는 환경을 그대로 전달하기 위해 Docker를 사용합니다.&lt;/blockquote&gt;
&lt;p data-end=&quot;3226&quot; data-start=&quot;3176&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3226&quot; data-start=&quot;3176&quot; data-ke-size=&quot;size16&quot;&gt;즉, 같은 Docker를 사용하더라도&lt;br /&gt;목적에 따라 사용하는 방식은 달라질 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3102&quot; data-start=&quot;3099&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3112&quot; data-start=&quot;3104&quot; data-section-id=&quot;olknm8&quot;&gt;10. 정리&lt;/h1&gt;
&lt;p data-end=&quot;3174&quot; data-start=&quot;3114&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는&lt;br /&gt;self-interior-guide 프로젝트에 Docker를 적용해본 과정을 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;3201&quot; data-start=&quot;3180&quot; data-ke-size=&quot;size16&quot;&gt;핵심 내용을 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3370&quot; data-start=&quot;3203&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3232&quot; data-start=&quot;3203&quot; data-section-id=&quot;1lpb4jw&quot;&gt;Docker는 실행 환경을 포함한 구조로 동작한다&lt;/li&gt;
&lt;li data-end=&quot;3261&quot; data-start=&quot;3233&quot; data-section-id=&quot;1n7v2d3&quot;&gt;이미지 &amp;rarr; 컨테이너 흐름을 직접 확인할 수 있다&lt;/li&gt;
&lt;li data-end=&quot;3296&quot; data-start=&quot;3262&quot; data-section-id=&quot;7riwxc&quot;&gt;환경 문제(Node 버전)도 컨테이너에서 동일하게 발생한다&lt;/li&gt;
&lt;li data-end=&quot;3336&quot; data-start=&quot;3297&quot; data-section-id=&quot;1s1oy6n&quot;&gt;Docker Desktop을 통해 상태를 시각적으로 확인할 수 있다&lt;/li&gt;
&lt;li data-end=&quot;3366&quot; data-start=&quot;3337&quot; data-section-id=&quot;5jokt3&quot;&gt;Docker Hub를 통해 이미지 배포가 가능하다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3451&quot; data-start=&quot;3413&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 프로젝트에서는 Docker를 실제 배포에는 사용하지 않았지만,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;적용 과정을 통해 Docker의 실행 구조와 흐름을 직접 경험해볼 수 있었고,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;개념으로만 이해하던 내용을 실제 동작과 연결해볼 수 있었습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Dev Tools</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/14</guid>
      <comments>https://dlsxo.tistory.com/14#entry14comment</comments>
      <pubDate>Mon, 20 Apr 2026 15:30:49 +0900</pubDate>
    </item>
    <item>
      <title>Docker 기본 개념 정리</title>
      <link>https://dlsxo.tistory.com/13</link>
      <description>&lt;p data-end=&quot;212&quot; data-start=&quot;204&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-end=&quot;212&quot; data-start=&quot;204&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;199&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 Docker의 기본 개념을 정리해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;326&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 공부하다 보면&lt;br /&gt;이미지(Image), 컨테이너(Container), Dockerfile, Registry, Compose 같은 용어가 계속 등장합니다.&lt;/p&gt;
&lt;p data-end=&quot;326&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;388&quot; data-start=&quot;328&quot; data-ke-size=&quot;size16&quot;&gt;이 개념들은 각각 따로 보이지만,&lt;br /&gt;실제로는 서로 연결되어 있기 때문에 흐름으로 이해하는 것이 중요합니다.&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;390&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;390&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 Docker를 왜 사용하는지부터 시작해서,&lt;br /&gt;Docker Desktop과 CLI, 이미지와 컨테이너의 관계, Dockerfile의 역할,&lt;br /&gt;그리고 Compose와 Registry까지 전체 구조를 한 번에 정리해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;390&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;595&quot; data-start=&quot;525&quot; data-ke-size=&quot;size16&quot;&gt;단순히 명령어만 보는 것이 아니라,&lt;br /&gt;Docker가 어떤 문제를 해결하고 어떤 방식으로 동작하는지를 중심으로 살펴보겠습니다.&lt;/p&gt;
&lt;hr data-end=&quot;666&quot; data-start=&quot;663&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;706&quot; data-start=&quot;668&quot; data-section-id=&quot;e3hd0p&quot; data-ke-size=&quot;size26&quot;&gt;0. Docker Desktop과 CLI&lt;/h2&gt;
&lt;p data-end=&quot;715&quot; data-start=&quot;684&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 사용하는 방법은 크게 두 가지가 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;715&quot; data-start=&quot;684&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;818&quot; data-start=&quot;717&quot; data-ke-size=&quot;size16&quot;&gt;하나는 터미널에서 직접 명령어를 입력하는 &lt;b&gt;CLI 방식&lt;/b&gt;이고,&lt;br /&gt;다른 하나는 화면에서 컨테이너와 이미지를 확인하고 관리할 수 있는 &lt;b&gt;Docker Desktop 방식&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;818&quot; data-start=&quot;717&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;925&quot; data-start=&quot;820&quot; data-ke-size=&quot;size16&quot;&gt;윈도우 환경에서는 보통 Docker Desktop을 먼저 설치해서 사용하게 되는데,&lt;br /&gt;실제로 Docker를 다룰 때는 CLI와 Docker Desktop을 함께 사용하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;925&quot; data-start=&quot;820&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1032&quot; data-start=&quot;927&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker Desktop은 Docker를 좀 더 쉽게 관리하고 상태를 확인하게 해주는 도구이고,&lt;br /&gt;CLI는 Docker를 실제로 실행하고 제어하는 기본 방식이라고 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;839&quot; data-start=&quot;804&quot; data-section-id=&quot;3d5f0i&quot; data-ke-size=&quot;size23&quot;&gt;0.1 CLI (Command Line Interface)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lJyhx/dJMcai3WbkK/u8dPulGhOYlCN6hXguk6Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lJyhx/dJMcai3WbkK/u8dPulGhOYlCN6hXguk6Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lJyhx/dJMcai3WbkK/u8dPulGhOYlCN6hXguk6Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlJyhx%2FdJMcai3WbkK%2Fu8dPulGhOYlCN6hXguk6Wk%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;1111&quot; height=&quot;480&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;871&quot; data-start=&quot;841&quot; data-ke-size=&quot;size16&quot;&gt;CLI는 터미널에서 직접 명령어를 입력하는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;871&quot; data-start=&quot;841&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;897&quot; data-start=&quot;873&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 아래와 같은 명령어들이 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775807554447&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build
docker run
docker ps
docker images&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1019&quot; data-start=&quot;960&quot; data-ke-size=&quot;size16&quot;&gt;이 방식은 처음에는 다소 낯설 수 있지만,&lt;br /&gt;Docker를 실제로 다룰 때 가장 기본이 되는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;1019&quot; data-start=&quot;960&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1042&quot; data-start=&quot;1021&quot; data-ke-size=&quot;size16&quot;&gt;CLI 방식의 장점은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1134&quot; data-start=&quot;1044&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1064&quot; data-start=&quot;1044&quot; data-section-id=&quot;1nfg12c&quot;&gt;명령어로 세밀하게 제어할 수 있음&lt;/li&gt;
&lt;li data-end=&quot;1082&quot; data-start=&quot;1065&quot; data-section-id=&quot;109l030&quot;&gt;반복 작업을 자동화하기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;1109&quot; data-start=&quot;1083&quot; data-section-id=&quot;1hm7yp3&quot;&gt;CI/CD나 서버 환경에서 그대로 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;1134&quot; data-start=&quot;1110&quot; data-section-id=&quot;1cr4wba&quot;&gt;Docker의 동작 원리를 익히기에 좋음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1189&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;즉, CLI는&lt;br /&gt;&lt;b&gt;Docker를 실제로 다루는 가장 표준적인 방식&lt;/b&gt;이라고 볼 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1194&quot; data-start=&quot;1191&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1218&quot; data-start=&quot;1196&quot; data-section-id=&quot;1khse98&quot; data-ke-size=&quot;size23&quot;&gt;0.2 Docker Desktop&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kIjpZ/dJMcabqh8Wr/FQ5MlZ0lrCZKBolO84NJn0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kIjpZ/dJMcabqh8Wr/FQ5MlZ0lrCZKBolO84NJn0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kIjpZ/dJMcabqh8Wr/FQ5MlZ0lrCZKBolO84NJn0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkIjpZ%2FdJMcabqh8Wr%2FFQ5MlZ0lrCZKBolO84NJn0%2Fimg.webp&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;1280&quot; height=&quot;882&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1220&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1220&quot; data-ke-size=&quot;size16&quot;&gt;반면 윈도우나 Mac 환경에서는 Docker Desktop이라는 GUI 프로그램을 함께 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1220&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1347&quot; data-start=&quot;1282&quot; data-ke-size=&quot;size16&quot;&gt;Docker Desktop은&lt;br /&gt;Docker Engine을 조금 더 쉽게 사용할 수 있도록 도와주는 관리 도구입니다.&lt;/p&gt;
&lt;p data-end=&quot;1347&quot; data-start=&quot;1282&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1413&quot; data-start=&quot;1349&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Docker Desktop에서는 다음과 같은 작업을&lt;br /&gt;UI 화면에서 비교적 직관적으로 할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1491&quot; data-start=&quot;1415&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1433&quot; data-start=&quot;1415&quot; data-section-id=&quot;w0nas1&quot;&gt;현재 실행 중인 컨테이너 확인&lt;/li&gt;
&lt;li data-end=&quot;1445&quot; data-start=&quot;1434&quot; data-section-id=&quot;1u0cdkt&quot;&gt;이미지 목록 확인&lt;/li&gt;
&lt;li data-end=&quot;1465&quot; data-start=&quot;1446&quot; data-section-id=&quot;f1k459&quot;&gt;컨테이너 시작 / 중지 / 삭제&lt;/li&gt;
&lt;li data-end=&quot;1473&quot; data-start=&quot;1466&quot; data-section-id=&quot;4r7m8x&quot;&gt;로그 확인&lt;/li&gt;
&lt;li data-end=&quot;1491&quot; data-start=&quot;1474&quot; data-section-id=&quot;t4z6xr&quot;&gt;볼륨 / 네트워크 상태 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1548&quot; data-start=&quot;1493&quot; data-ke-size=&quot;size16&quot;&gt;즉, 명령어를 모두 외우지 않아도&lt;br /&gt;현재 Docker 상태를 눈으로 확인하고 관리하기가 쉽습니다.&lt;/p&gt;
&lt;p data-end=&quot;1548&quot; data-start=&quot;1493&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1626&quot; data-start=&quot;1550&quot; data-ke-size=&quot;size16&quot;&gt;특히 Docker를 처음 공부할 때는&lt;br /&gt;컨테이너가 실제로 생성되고 실행되는 모습을&lt;br /&gt;GUI 화면으로 보는 것이 이해에 도움이 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;1631&quot; data-start=&quot;1628&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1676&quot; data-start=&quot;1633&quot; data-section-id=&quot;1v25gj0&quot; data-ke-size=&quot;size23&quot;&gt;0.3 Windows에서는 왜 Docker Desktop을 많이 쓰는가&lt;/h3&gt;
&lt;p data-end=&quot;1772&quot; data-start=&quot;1678&quot; data-ke-size=&quot;size16&quot;&gt;리눅스에서는 Docker를 비교적 직접 설치해서 사용하는 경우가 많지만,&lt;br /&gt;윈도우에서는 Docker Desktop을 통해 Docker 환경을 구성하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;1772&quot; data-start=&quot;1678&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1864&quot; data-start=&quot;1774&quot; data-ke-size=&quot;size16&quot;&gt;그 이유는 윈도우가 리눅스 커널을 직접 사용하는 환경이 아니기 때문에,&lt;br /&gt;Docker Desktop이 내부적으로 필요한 실행 환경을 함께 관리해주기 때문입니다.&lt;/p&gt;
&lt;p data-end=&quot;1864&quot; data-start=&quot;1774&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1969&quot; data-start=&quot;1866&quot; data-ke-size=&quot;size16&quot;&gt;사용자 입장에서는 복잡한 내부 구조를 모두 신경 쓰기보다&lt;br /&gt;Docker Desktop을 설치하고 실행한 뒤,&lt;br /&gt;CLI와 GUI를 함께 사용하는 방식으로 시작하는 경우가 일반적입니다.&lt;/p&gt;
&lt;p data-end=&quot;1969&quot; data-start=&quot;1866&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2001&quot; data-start=&quot;1971&quot; data-ke-size=&quot;size16&quot;&gt;즉, 윈도우 기준으로는 보통 다음처럼 이해하면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2089&quot; data-start=&quot;2003&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2055&quot; data-start=&quot;2003&quot; data-section-id=&quot;1ji63nf&quot;&gt;Docker Desktop = Docker를 쉽게 실행하고 관리할 수 있게 해주는 프로그램&lt;/li&gt;
&lt;li data-end=&quot;2089&quot; data-start=&quot;2056&quot; data-section-id=&quot;a6orab&quot;&gt;CLI = Docker를 실제로 조작하는 핵심 명령 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2094&quot; data-start=&quot;2091&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2127&quot; data-start=&quot;2096&quot; data-section-id=&quot;mq3ozw&quot; data-ke-size=&quot;size23&quot;&gt;0.4 Docker Desktop과 CLI의 관계&lt;/h3&gt;
&lt;p data-end=&quot;2168&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;이 둘은 서로 대체 관계라기보다는&lt;br /&gt;함께 사용하는 관계에 가깝습니다.&lt;/p&gt;
&lt;p data-end=&quot;2168&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2175&quot; data-start=&quot;2170&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2262&quot; data-start=&quot;2177&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2203&quot; data-start=&quot;2177&quot; data-section-id=&quot;75yevc&quot;&gt;이미지는 CLI로 docker build&lt;/li&gt;
&lt;li data-end=&quot;2234&quot; data-start=&quot;2204&quot; data-section-id=&quot;lwf2ta&quot;&gt;컨테이너 상태는 Docker Desktop에서 확인&lt;/li&gt;
&lt;li data-end=&quot;2262&quot; data-start=&quot;2235&quot; data-section-id=&quot;gopyos&quot;&gt;실행과 삭제는 CLI 또는 GUI 둘 다 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2285&quot; data-start=&quot;2264&quot; data-ke-size=&quot;size16&quot;&gt;이런 식으로 함께 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2301&quot; data-start=&quot;2287&quot; data-ke-size=&quot;size16&quot;&gt;정리하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2392&quot; data-start=&quot;2303&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2334&quot; data-start=&quot;2303&quot; data-section-id=&quot;10vq1rr&quot;&gt;&lt;b&gt;CLI는 Docker를 직접 다루는 핵심 방식&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2392&quot; data-start=&quot;2335&quot; data-section-id=&quot;hm1t2&quot;&gt;&lt;b&gt;Docker Desktop은 Docker를 더 쉽게 관리하고 시각적으로 확인하게 해주는 도구&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2464&quot; data-start=&quot;2394&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 Docker Desktop으로 전체 구조를 이해하고,&lt;br /&gt;점점 CLI 중심으로 익숙해지는 방식이 가장 자연스럽습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2585&quot; data-start=&quot;2582&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2608&quot; data-start=&quot;2587&quot; data-section-id=&quot;kl3x1j&quot; data-ke-size=&quot;size26&quot;&gt;1. 왜 Docker를 사용하는가&lt;/h2&gt;
&lt;p data-end=&quot;2637&quot; data-start=&quot;2610&quot; data-ke-size=&quot;size16&quot;&gt;개발을 하다 보면&lt;br /&gt;같은 프로젝트라도 실행 환경에 따라 정상적으로 동작하지 않는 경우를 자주 마주하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXV0qA/dJMcaf0tL9c/agE5HFFcgkbGTxDPQPxMek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXV0qA/dJMcaf0tL9c/agE5HFFcgkbGTxDPQPxMek/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXV0qA/dJMcaf0tL9c/agE5HFFcgkbGTxDPQPxMek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXV0qA%2FdJMcaf0tL9c%2FagE5HFFcgkbGTxDPQPxMek%2Fimg.jpg&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;800&quot; height=&quot;455&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2696&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2696&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 로컬에서는 잘 동작하던 코드가&lt;br /&gt;서버에서는 오류가 발생하거나 실행되지 않는 상황이 생길 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2696&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2696&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;같은 프로젝트라도 실행 환경이 다르면 문제가 생길 수 있가 때문입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2782&quot; data-start=&quot;2698&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2713&quot; data-start=&quot;2698&quot; data-section-id=&quot;1b6rdel&quot;&gt;운영체제가 다를 수 있고&lt;/li&gt;
&lt;li data-end=&quot;2735&quot; data-start=&quot;2714&quot; data-section-id=&quot;89pbdv&quot;&gt;Node.js 버전이 다를 수 있고&lt;/li&gt;
&lt;li data-end=&quot;2756&quot; data-start=&quot;2736&quot; data-section-id=&quot;144jejo&quot;&gt;설치된 라이브러리가 다를 수 있고&lt;/li&gt;
&lt;li data-end=&quot;2782&quot; data-start=&quot;2757&quot; data-section-id=&quot;1e8tqnw&quot;&gt;배포 서버와 로컬 환경이 다를 수 있습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2861&quot; data-start=&quot;2784&quot; data-ke-size=&quot;size16&quot;&gt;이런 차이 때문에&lt;br /&gt;로컬에서는 잘 되지만 서버에서는 동작하지 않거나,&lt;br /&gt;협업 중에 같은 코드를 받아도 실행이 안 되는 경우가 생깁니다.&lt;/p&gt;
&lt;p data-end=&quot;2861&quot; data-start=&quot;2784&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2892&quot; data-start=&quot;2863&quot; data-ke-size=&quot;size16&quot;&gt;Docker는 이런 문제를 해결하기 위해 사용합니다.&lt;/p&gt;
&lt;p data-end=&quot;2892&quot; data-start=&quot;2863&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2973&quot; data-start=&quot;2894&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션을 단순히 코드만 옮기는 것이 아니라,&lt;br /&gt;실행에 필요한 환경까지 함께 묶어서&lt;br /&gt;어디서든 동일하게 실행할 수 있도록 만들어줍니다.&lt;/p&gt;
&lt;p data-end=&quot;2973&quot; data-start=&quot;2894&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3030&quot; data-start=&quot;2975&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker의 가장 큰 목적은&lt;br /&gt;&lt;b&gt;환경 차이를 줄이고 실행 환경을 표준화하는 것&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;3152&quot; data-start=&quot;3149&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3168&quot; data-start=&quot;3154&quot; data-section-id=&quot;15kv2nm&quot; data-ke-size=&quot;size26&quot;&gt;2. Docker란?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctWQBv/dJMcafzr3jD/vO3aqlWaUmKtjaIOBctfm1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctWQBv/dJMcafzr3jD/vO3aqlWaUmKtjaIOBctfm1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctWQBv/dJMcafzr3jD/vO3aqlWaUmKtjaIOBctfm1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctWQBv%2FdJMcafzr3jD%2FvO3aqlWaUmKtjaIOBctfm1%2Fimg.jpg&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;1269&quot; height=&quot;397&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;3240&quot; data-start=&quot;3170&quot; data-ke-size=&quot;size16&quot;&gt;Docker는 컨테이너 기반 가상화 기술을 활용해&lt;br /&gt;애플리케이션을 더 쉽게 실행하고 관리할 수 있도록 도와주는 플랫폼입니다.&lt;/p&gt;
&lt;p data-end=&quot;3240&quot; data-start=&quot;3170&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3315&quot; data-start=&quot;3242&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 쉽게 말하면,&lt;br /&gt;프로그램을 실행하는 데 필요한 환경을 하나로 묶어서&lt;br /&gt;격리된 상태로 실행할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;p data-end=&quot;3315&quot; data-start=&quot;3242&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3362&quot; data-start=&quot;3317&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 어떤 애플리케이션을 실행하려면 다음과 같은 요소가 필요할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3433&quot; data-start=&quot;3364&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3376&quot; data-start=&quot;3364&quot; data-section-id=&quot;uqsv08&quot;&gt;운영체제 기반 환경&lt;/li&gt;
&lt;li data-end=&quot;3404&quot; data-start=&quot;3377&quot; data-section-id=&quot;jbwxm7&quot;&gt;언어 런타임(Node.js, Python 등)&lt;/li&gt;
&lt;li data-end=&quot;3412&quot; data-start=&quot;3405&quot; data-section-id=&quot;1egvizw&quot;&gt;라이브러리&lt;/li&gt;
&lt;li data-end=&quot;3424&quot; data-start=&quot;3413&quot; data-section-id=&quot;7oo5ik&quot;&gt;애플리케이션 코드&lt;/li&gt;
&lt;li data-end=&quot;3433&quot; data-start=&quot;3425&quot; data-section-id=&quot;1ezxuml&quot;&gt;실행 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3497&quot; data-start=&quot;3435&quot; data-ke-size=&quot;size16&quot;&gt;Docker는 이런 요소들을 하나의 실행 단위로 정리해&lt;br /&gt;어디서든 같은 방식으로 실행할 수 있게 만들어줍니다.&lt;/p&gt;
&lt;p data-end=&quot;3497&quot; data-start=&quot;3435&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3512&quot; data-start=&quot;3499&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3588&quot; data-start=&quot;3514&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3533&quot; data-start=&quot;3514&quot; data-section-id=&quot;elzd4q&quot;&gt;실행 환경을 함께 묶을 수 있음&lt;/li&gt;
&lt;li data-end=&quot;3550&quot; data-start=&quot;3534&quot; data-section-id=&quot;eih1gw&quot;&gt;격리된 환경에서 실행 가능&lt;/li&gt;
&lt;li data-end=&quot;3573&quot; data-start=&quot;3551&quot; data-section-id=&quot;g09mcp&quot;&gt;다른 컴퓨터에서도 동일하게 실행 가능&lt;/li&gt;
&lt;li data-end=&quot;3588&quot; data-start=&quot;3574&quot; data-section-id=&quot;1huxon1&quot;&gt;배포와 실행이 단순해짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3660&quot; data-start=&quot;3590&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker는&lt;br /&gt;**&amp;ldquo;프로그램을 실행하기 위한 환경까지 함께 포장해서 배포하는 방식&amp;rdquo;**이라고 이해하면 가장 쉽습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3789&quot; data-start=&quot;3786&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3834&quot; data-start=&quot;3791&quot; data-section-id=&quot;7bwkhj&quot; data-ke-size=&quot;size26&quot;&gt;3. Virtual Machine과 Docker Container의 차이&lt;/h2&gt;
&lt;p data-end=&quot;3887&quot; data-start=&quot;3836&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 이해할 때 가장 많이 비교되는 대상이 바로 Virtual Machine입니다.&lt;/p&gt;
&lt;p data-end=&quot;3887&quot; data-start=&quot;3836&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3932&quot; data-start=&quot;3889&quot; data-ke-size=&quot;size16&quot;&gt;둘 다 격리된 환경을 만든다는 공통점은 있지만,&lt;br /&gt;동작 방식은 꽤 다릅니다.&lt;/p&gt;
&lt;h3 data-end=&quot;3963&quot; data-start=&quot;3934&quot; data-section-id=&quot;wzszee&quot; data-ke-size=&quot;size23&quot;&gt;3.1 Virtual Machine(가상머신)&lt;/h3&gt;
&lt;p data-end=&quot;4040&quot; data-start=&quot;3965&quot; data-ke-size=&quot;size16&quot;&gt;기존 가상화 방식은 하이퍼바이저(Hypervisor)를 이용해&lt;br /&gt;하나의 호스트 위에 여러 개의 운영체제를 올려서 사용하는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;4040&quot; data-start=&quot;3965&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4098&quot; data-start=&quot;4042&quot; data-ke-size=&quot;size16&quot;&gt;각 가상머신은 독립된 Guest OS를 가지고,&lt;br /&gt;그 안에서 필요한 프로그램을 설치하고 실행합니다.&lt;/p&gt;
&lt;p data-end=&quot;4098&quot; data-start=&quot;4042&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4156&quot; data-start=&quot;4100&quot; data-ke-size=&quot;size16&quot;&gt;즉, 애플리케이션 하나를 실행하기 위해&lt;br /&gt;운영체제 전체를 하나 더 올리는 구조라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;4156&quot; data-start=&quot;4100&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4205&quot; data-start=&quot;4158&quot; data-ke-size=&quot;size16&quot;&gt;이 방식의 장점은&lt;br /&gt;운영체제 단위로 완전히 분리된 환경을 만들 수 있다는 점입니다.&lt;/p&gt;
&lt;p data-end=&quot;4205&quot; data-start=&quot;4158&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4220&quot; data-start=&quot;4207&quot; data-ke-size=&quot;size16&quot;&gt;하지만 단점도 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4327&quot; data-start=&quot;4222&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4240&quot; data-start=&quot;4222&quot; data-section-id=&quot;11pygcc&quot;&gt;Guest OS가 각각 필요함&lt;/li&gt;
&lt;li data-end=&quot;4264&quot; data-start=&quot;4241&quot; data-section-id=&quot;1p78buc&quot;&gt;커널과 라이브러리까지 모두 포함해야 함&lt;/li&gt;
&lt;li data-end=&quot;4276&quot; data-start=&quot;4265&quot; data-section-id=&quot;1rximdg&quot;&gt;이미지 크기가 큼&lt;/li&gt;
&lt;li data-end=&quot;4294&quot; data-start=&quot;4277&quot; data-section-id=&quot;nexhi8&quot;&gt;실행 속도가 상대적으로 느림&lt;/li&gt;
&lt;li data-end=&quot;4327&quot; data-start=&quot;4295&quot; data-section-id=&quot;1rh2xmp&quot;&gt;하이퍼바이저를 거치므로 성능 오버헤드가 발생할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4356&quot; data-start=&quot;4329&quot; data-ke-size=&quot;size16&quot;&gt;즉, VM은 강력한 격리를 제공하지만 무겁습니다.&lt;/p&gt;
&lt;p data-end=&quot;4356&quot; data-start=&quot;4329&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;1280&quot; data-origin-height=&quot;1278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vb39L/dJMcag6bGf9/lhqxBIESmr26eoWG19Lwy0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vb39L/dJMcag6bGf9/lhqxBIESmr26eoWG19Lwy0/img.jpg&quot; data-alt=&quot;VM &amp;amp;rarr; OS 포함&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vb39L/dJMcag6bGf9/lhqxBIESmr26eoWG19Lwy0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvb39L%2FdJMcag6bGf9%2FlhqxBIESmr26eoWG19Lwy0%2Fimg.jpg&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;1280&quot; height=&quot;1278&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1278&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;VM &amp;rarr; OS 포함&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;4453&quot; data-start=&quot;4450&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;4488&quot; data-start=&quot;4455&quot; data-section-id=&quot;10vm7r7&quot; data-ke-size=&quot;size23&quot;&gt;3.2 Docker Container(도커 컨테이너)&lt;/h3&gt;
&lt;p data-end=&quot;4532&quot; data-start=&quot;4490&quot; data-ke-size=&quot;size16&quot;&gt;Docker 컨테이너는 가상머신처럼 운영체제를 통째로 새로 만들지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;4532&quot; data-start=&quot;4490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4582&quot; data-start=&quot;4534&quot; data-ke-size=&quot;size16&quot;&gt;호스트 OS의 커널을 공유하면서&lt;br /&gt;프로세스 단위로 애플리케이션을 격리해서 실행합니다.&lt;/p&gt;
&lt;p data-end=&quot;4582&quot; data-start=&quot;4534&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4625&quot; data-start=&quot;4584&quot; data-ke-size=&quot;size16&quot;&gt;즉, 필요한 것은 분리하되&lt;br /&gt;운영체제 전체를 복제하지는 않는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;4625&quot; data-start=&quot;4584&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4652&quot; data-start=&quot;4627&quot; data-ke-size=&quot;size16&quot;&gt;이 방식 덕분에 다음과 같은 장점이 생깁니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4700&quot; data-start=&quot;4654&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4662&quot; data-start=&quot;4654&quot; data-section-id=&quot;1hds5ad&quot;&gt;훨씬 가볍다&lt;/li&gt;
&lt;li data-end=&quot;4675&quot; data-start=&quot;4663&quot; data-section-id=&quot;1tjq9ks&quot;&gt;실행 속도가 빠르다&lt;/li&gt;
&lt;li data-end=&quot;4688&quot; data-start=&quot;4676&quot; data-section-id=&quot;1dtpm0d&quot;&gt;이미지 크기가 작다&lt;/li&gt;
&lt;li data-end=&quot;4700&quot; data-start=&quot;4689&quot; data-section-id=&quot;crosex&quot;&gt;성능 손실이 적다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4762&quot; data-start=&quot;4702&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 안에는&lt;br /&gt;애플리케이션 실행에 필요한 라이브러리와 파일만 포함되고,&lt;br /&gt;커널은 호스트와 공유합니다.&lt;/p&gt;
&lt;p data-end=&quot;4762&quot; data-start=&quot;4702&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4815&quot; data-start=&quot;4764&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Docker는&lt;br /&gt;가상머신보다 더 빠르고 효율적으로 실행 환경을 제공할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;4947&quot; data-start=&quot;4944&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4972&quot; data-start=&quot;4949&quot; data-section-id=&quot;1quk3wq&quot; data-ke-size=&quot;size26&quot;&gt;4. Docker가 가볍고 빠른 이유&lt;/h2&gt;
&lt;p data-end=&quot;5024&quot; data-start=&quot;4974&quot; data-ke-size=&quot;size16&quot;&gt;Docker가 빠르다고 많이 이야기하지만,&lt;br /&gt;중요한 것은 왜 빠른가를 이해하는 것입니다.&lt;/p&gt;
&lt;p data-end=&quot;5024&quot; data-start=&quot;4974&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5063&quot; data-start=&quot;5026&quot; data-ke-size=&quot;size16&quot;&gt;Docker가 가볍고 빠른 이유는 크게 세 가지로 볼 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;5091&quot; data-start=&quot;5065&quot; data-section-id=&quot;3vclvf&quot; data-ke-size=&quot;size23&quot;&gt;4.1 운영체제를 통째로 포함하지 않는다&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw4L6f/dJMcahDZN8f/HMIqimbys3aLLVjKRjgsk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw4L6f/dJMcahDZN8f/HMIqimbys3aLLVjKRjgsk1/img.jpg&quot; data-alt=&quot;OS 전체 포함 vs 필요한 실행 환경만 포함&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw4L6f/dJMcahDZN8f/HMIqimbys3aLLVjKRjgsk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw4L6f%2FdJMcahDZN8f%2FHMIqimbys3aLLVjKRjgsk1%2Fimg.jpg&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;960&quot; height=&quot;720&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OS 전체 포함 vs 필요한 실행 환경만 포함&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;5169&quot; data-start=&quot;5093&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5169&quot; data-start=&quot;5093&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 Guest OS를 따로 가지지 않습니다.&lt;br /&gt;호스트의 커널을 공유하기 때문에&lt;br /&gt;운영체제 전체를 매번 포함할 필요가 없습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;5190&quot; data-start=&quot;5171&quot; data-section-id=&quot;120o69d&quot; data-ke-size=&quot;size23&quot;&gt;4.2 필요한 것만 포함한다&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz2bKn/dJMcah46mrc/ocQBa5YRSDHE1ABUgzDT6k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz2bKn/dJMcah46mrc/ocQBa5YRSDHE1ABUgzDT6k/img.jpg&quot; data-alt=&quot;필요한 것만 포함&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz2bKn/dJMcah46mrc/ocQBa5YRSDHE1ABUgzDT6k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz2bKn%2FdJMcah46mrc%2FocQBa5YRSDHE1ABUgzDT6k%2Fimg.jpg&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;880&quot; height=&quot;429&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;필요한 것만 포함&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;5231&quot; data-start=&quot;5192&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5231&quot; data-start=&quot;5192&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너에는 애플리케이션 실행에 필요한 파일과 라이브러리만 들어갑니다.&lt;/p&gt;
&lt;p data-end=&quot;5231&quot; data-start=&quot;5192&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5293&quot; data-start=&quot;5233&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Node.js 애플리케이션이라면&lt;br /&gt;Node 런타임, 패키지, 소스 코드 정도만 포함하면 됩니다.&lt;/p&gt;
&lt;h3 data-end=&quot;5316&quot; data-start=&quot;5295&quot; data-section-id=&quot;xm444m&quot; data-ke-size=&quot;size23&quot;&gt;4.3 프로세스 단위로 격리한다&lt;/h3&gt;
&lt;p data-end=&quot;5378&quot; data-start=&quot;5318&quot; data-ke-size=&quot;size16&quot;&gt;가상머신은 OS 단위 가상화에 가깝지만,&lt;br /&gt;Docker는 프로세스 단위 격리이기 때문에 훨씬 효율적입니다.&lt;/p&gt;
&lt;p data-end=&quot;5378&quot; data-start=&quot;5318&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5450&quot; data-start=&quot;5380&quot; data-ke-size=&quot;size16&quot;&gt;결국 Docker는&lt;br /&gt;무겁게 전체 시스템을 가상화하는 대신, 필요한 실행 환경만 분리해서 사용하기 때문에 빠르고 가볍습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;765&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5YCQE/dJMcafzr3yE/2bPXLSkWzPEsdnDQDgjTU1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5YCQE/dJMcafzr3yE/2bPXLSkWzPEsdnDQDgjTU1/img.jpg&quot; data-alt=&quot;프로세스 단위 비교 인포그래픽&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5YCQE/dJMcafzr3yE/2bPXLSkWzPEsdnDQDgjTU1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5YCQE%2FdJMcafzr3yE%2F2bPXLSkWzPEsdnDQDgjTU1%2Fimg.jpg&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;1280&quot; height=&quot;765&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;765&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로세스 단위 비교 인포그래픽&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;5539&quot; data-start=&quot;5536&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;5562&quot; data-start=&quot;5541&quot; data-section-id=&quot;ogj1zi&quot; data-ke-size=&quot;size26&quot;&gt;5. Docker의 핵심 구성요소&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker를 사용할 때 자주 등장하는 구성요소는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n00Fs/dJMb9963GVW/5smU0VEQpBhq5y6vxKcDZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n00Fs/dJMb9963GVW/5smU0VEQpBhq5y6vxKcDZk/img.png&quot; data-alt=&quot;도커 흐름도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n00Fs/dJMb9963GVW/5smU0VEQpBhq5y6vxKcDZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn00Fs%2FdJMb9963GVW%2F5smU0VEQpBhq5y6vxKcDZk%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;1233&quot; height=&quot;651&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;도커 흐름도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;5624&quot; data-start=&quot;5603&quot; data-section-id=&quot;toh9b5&quot; data-ke-size=&quot;size23&quot;&gt;5.1 Docker Client&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sECWL/dJMcaiJExRZ/k5FUCuTwuRbKJmATOfnRV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sECWL/dJMcaiJExRZ/k5FUCuTwuRbKJmATOfnRV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sECWL/dJMcaiJExRZ/k5FUCuTwuRbKJmATOfnRV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsECWL%2FdJMcaiJExRZ%2Fk5FUCuTwuRbKJmATOfnRV1%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;1233&quot; height=&quot;651&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;5675&quot; data-start=&quot;5626&quot; data-ke-size=&quot;size16&quot;&gt;우리가 터미널에서 사용하는 docker 명령어가 바로 Docker Client입니다.&lt;/p&gt;
&lt;p data-end=&quot;5675&quot; data-start=&quot;5626&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5682&quot; data-start=&quot;5677&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775808689252&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build
docker pull
docker run&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5790&quot; data-start=&quot;5733&quot; data-ke-size=&quot;size16&quot;&gt;이런 명령어를 입력하면&lt;br /&gt;Docker Client가 그 요청을 Docker Engine에 전달합니다.&lt;/p&gt;
&lt;p data-end=&quot;5790&quot; data-start=&quot;5733&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5829&quot; data-start=&quot;5792&quot; data-ke-size=&quot;size16&quot;&gt;즉, 사용자의 입력을 받아 실제 엔진에 명령을 전달하는 역할입니다.&lt;/p&gt;
&lt;hr data-end=&quot;5834&quot; data-start=&quot;5831&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;5872&quot; data-start=&quot;5836&quot; data-section-id=&quot;qea27g&quot; data-ke-size=&quot;size23&quot;&gt;5.2 Docker Engine(Docker Daemon)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0mS2n/dJMcaibSIA9/zn2Sv7kGjSSrjKeKVitPp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0mS2n/dJMcaibSIA9/zn2Sv7kGjSSrjKeKVitPp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0mS2n/dJMcaibSIA9/zn2Sv7kGjSSrjKeKVitPp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0mS2n%2FdJMcaibSIA9%2Fzn2Sv7kGjSSrjKeKVitPp1%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;1233&quot; height=&quot;651&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1617&quot; data-origin-height=&quot;869&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJK5vQ/dJMcaibSIIo/dJJYToOHPZDIoXqlwUjNok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJK5vQ/dJMcaibSIIo/dJJYToOHPZDIoXqlwUjNok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJK5vQ/dJMcaibSIIo/dJJYToOHPZDIoXqlwUjNok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJK5vQ%2FdJMcaibSIIo%2FdJJYToOHPZDIoXqlwUjNok%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;1617&quot; height=&quot;869&quot; data-origin-width=&quot;1617&quot; data-origin-height=&quot;869&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;5894&quot; data-start=&quot;5874&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5894&quot; data-start=&quot;5874&quot; data-ke-size=&quot;size16&quot;&gt;Docker의 실제 동작 주체입니다.&lt;/p&gt;
&lt;p data-end=&quot;5894&quot; data-start=&quot;5874&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5928&quot; data-start=&quot;5896&quot; data-ke-size=&quot;size16&quot;&gt;Docker Engine은 다음과 같은 작업을 수행합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5984&quot; data-start=&quot;5930&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5938&quot; data-start=&quot;5930&quot; data-section-id=&quot;17t3j9w&quot;&gt;이미지 빌드&lt;/li&gt;
&lt;li data-end=&quot;5954&quot; data-start=&quot;5939&quot; data-section-id=&quot;uocfoe&quot;&gt;이미지 다운로드 및 저장&lt;/li&gt;
&lt;li data-end=&quot;5969&quot; data-start=&quot;5955&quot; data-section-id=&quot;10rmbxa&quot;&gt;컨테이너 생성 및 실행&lt;/li&gt;
&lt;li data-end=&quot;5984&quot; data-start=&quot;5970&quot; data-section-id=&quot;1vqjqw3&quot;&gt;네트워크 / 볼륨 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;6030&quot; data-start=&quot;5986&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker의 핵심은 결국 Docker Engine이라고 볼 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;6035&quot; data-start=&quot;6032&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;6056&quot; data-start=&quot;6037&quot; data-section-id=&quot;n89ja2&quot; data-ke-size=&quot;size23&quot;&gt;5.3 Docker Host&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L2iNE/dJMcaaSrZcO/lF3LBrjxgGawTDSsVKd0z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L2iNE/dJMcaaSrZcO/lF3LBrjxgGawTDSsVKd0z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L2iNE/dJMcaaSrZcO/lF3LBrjxgGawTDSsVKd0z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL2iNE%2FdJMcaaSrZcO%2FlF3LBrjxgGawTDSsVKd0z0%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;1233&quot; height=&quot;651&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;6130&quot; data-start=&quot;6058&quot; data-ke-size=&quot;size16&quot;&gt;Docker Engine이 실행되는 환경입니다.&lt;br /&gt;이미지와 컨테이너가 실제로 존재하고 관리되는 서버 또는 PC라고 보면 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;6135&quot; data-start=&quot;6132&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;6153&quot; data-start=&quot;6137&quot; data-section-id=&quot;fouvto&quot; data-ke-size=&quot;size23&quot;&gt;5.4 Registry&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rz5UQ/dJMcai3Wdq6/CD2vA8vXOWJtVvBYZZCLwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rz5UQ/dJMcai3Wdq6/CD2vA8vXOWJtVvBYZZCLwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rz5UQ/dJMcai3Wdq6/CD2vA8vXOWJtVvBYZZCLwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frz5UQ%2FdJMcai3Wdq6%2FCD2vA8vXOWJtVvBYZZCLwK%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;1233&quot; height=&quot;651&quot; data-origin-width=&quot;1233&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;6175&quot; data-start=&quot;6155&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 저장하는 원격 저장소입니다.&lt;/p&gt;
&lt;p data-end=&quot;6175&quot; data-start=&quot;6155&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6192&quot; data-start=&quot;6177&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로 다음이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6244&quot; data-start=&quot;6194&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6206&quot; data-start=&quot;6194&quot; data-section-id=&quot;kl03b7&quot;&gt;Docker Hub&lt;/li&gt;
&lt;li data-end=&quot;6216&quot; data-start=&quot;6207&quot; data-section-id=&quot;17n9ymx&quot;&gt;AWS ECR&lt;/li&gt;
&lt;li data-end=&quot;6244&quot; data-start=&quot;6217&quot; data-section-id=&quot;e9fhof&quot;&gt;GitHub Container Registry&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;6300&quot; data-start=&quot;6246&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 Registry에 올려두면&lt;br /&gt;다른 환경에서 pull 받아서 그대로 실행할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;6433&quot; data-start=&quot;6430&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;6471&quot; data-start=&quot;6435&quot; data-section-id=&quot;yrb799&quot; data-ke-size=&quot;size26&quot;&gt;6. Docker Image와 Docker Container&lt;/h2&gt;
&lt;p data-end=&quot;6513&quot; data-start=&quot;6473&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 이해할 때 가장 중요한 개념은&lt;br /&gt;이미지와 컨테이너입니다.&lt;/p&gt;
&lt;p data-end=&quot;6513&quot; data-start=&quot;6473&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6541&quot; data-start=&quot;6515&quot; 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;825&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXFbU9%2FdJMcaiv76wS%2FHtwZeDUwkwFZipuswGK3vK%2Fimg.jpg&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;825&quot; height=&quot;481&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;6565&quot; data-start=&quot;6543&quot; data-section-id=&quot;1y2t9oj&quot; data-ke-size=&quot;size23&quot;&gt;6.1 Docker Image란?&lt;/h3&gt;
&lt;p data-end=&quot;6605&quot; data-start=&quot;6567&quot; data-ke-size=&quot;size16&quot;&gt;Docker Image는 컨테이너를 생성하기 위한 실행 패키지입니다.&lt;/p&gt;
&lt;p data-end=&quot;6605&quot; data-start=&quot;6567&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6649&quot; data-start=&quot;6607&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면&lt;br /&gt;애플리케이션을 실행하는 데 필요한 환경을 담아둔 묶음입니다.&lt;/p&gt;
&lt;p data-end=&quot;6649&quot; data-start=&quot;6607&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6669&quot; data-start=&quot;6651&quot; data-ke-size=&quot;size16&quot;&gt;여기에는 보통 다음이 포함됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6713&quot; data-start=&quot;6671&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6683&quot; data-start=&quot;6671&quot; data-section-id=&quot;cp40d1&quot;&gt;베이스 이미지 정보&lt;/li&gt;
&lt;li data-end=&quot;6689&quot; data-start=&quot;6684&quot; data-section-id=&quot;22ckkc&quot;&gt;런타임&lt;/li&gt;
&lt;li data-end=&quot;6697&quot; data-start=&quot;6690&quot; data-section-id=&quot;1egvizw&quot;&gt;라이브러리&lt;/li&gt;
&lt;li data-end=&quot;6705&quot; data-start=&quot;6698&quot; data-section-id=&quot;wg22i0&quot;&gt;소스 코드&lt;/li&gt;
&lt;li data-end=&quot;6713&quot; data-start=&quot;6706&quot; data-section-id=&quot;vogyjd&quot;&gt;실행 명령&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;6744&quot; data-start=&quot;6715&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지는 실행 환경이 미리 구성된 결과물입니다.&lt;/p&gt;
&lt;p data-end=&quot;6744&quot; data-start=&quot;6715&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6760&quot; data-start=&quot;6746&quot; data-ke-size=&quot;size16&quot;&gt;비유하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6824&quot; data-start=&quot;6762&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6783&quot; data-start=&quot;6762&quot; data-section-id=&quot;cxl4r8&quot;&gt;클래스와 인스턴스 관계에서의 클래스&lt;/li&gt;
&lt;li data-end=&quot;6810&quot; data-start=&quot;6784&quot; data-section-id=&quot;7qjtbk&quot;&gt;프로그램과 프로세스 관계에서의 프로그램 파일&lt;/li&gt;
&lt;li data-end=&quot;6824&quot; data-start=&quot;6811&quot; data-section-id=&quot;td0a7h&quot;&gt;건축으로 보면 설계도&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;6859&quot; data-start=&quot;6826&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지는&lt;br /&gt;&lt;b&gt;실행되기 전의 정적인 패키지&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;6864&quot; data-start=&quot;6861&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;6892&quot; data-start=&quot;6866&quot; data-section-id=&quot;1gwp4ao&quot; data-ke-size=&quot;size23&quot;&gt;6.2 Docker Container란?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdkbVE/dJMcagkNjMw/pp6fm9lgzzpwvUsCFs1iy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdkbVE/dJMcagkNjMw/pp6fm9lgzzpwvUsCFs1iy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdkbVE/dJMcagkNjMw/pp6fm9lgzzpwvUsCFs1iy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdkbVE%2FdJMcagkNjMw%2Fpp6fm9lgzzpwvUsCFs1iy0%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;1536&quot; height=&quot;1024&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;6919&quot; data-start=&quot;6894&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 이미지를 실제로 실행한 상태입니다.&lt;/p&gt;
&lt;p data-end=&quot;6919&quot; data-start=&quot;6894&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;6986&quot; data-start=&quot;6921&quot; data-ke-size=&quot;size16&quot;&gt;이미지가 정적인 실행 패키지라면,&lt;br /&gt;컨테이너는 그 패키지가 메모리 위에서 실제로 동작하고 있는 실행 인스턴스입니다.&lt;/p&gt;
&lt;p data-end=&quot;6986&quot; data-start=&quot;6921&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7046&quot; data-start=&quot;6988&quot; data-ke-size=&quot;size16&quot;&gt;같은 이미지 하나로 여러 개의 컨테이너를 만들 수 있기 때문에&lt;br /&gt;이미지와 컨테이너는 1:N 관계입니다.&lt;/p&gt;
&lt;p data-end=&quot;7046&quot; data-start=&quot;6988&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7099&quot; data-start=&quot;7048&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 하나의 웹 서버 이미지로부터&lt;br /&gt;여러 개의 웹 서버 컨테이너를 띄울 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;7099&quot; data-start=&quot;7048&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7154&quot; data-start=&quot;7101&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지는 재사용 가능한 원본이고,&lt;br /&gt;컨테이너는 그 원본으로부터 만들어진 실행 결과입니다.&lt;/p&gt;
&lt;hr data-end=&quot;7159&quot; data-start=&quot;7156&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;7182&quot; data-start=&quot;7161&quot; data-section-id=&quot;v9o80t&quot; data-ke-size=&quot;size23&quot;&gt;6.3 이미지와 컨테이너의 차이&lt;/h3&gt;
&lt;p data-end=&quot;7253&quot; data-start=&quot;7184&quot; data-ke-size=&quot;size16&quot;&gt;이미지는 읽기 전용입니다.&lt;br /&gt;한 번 만들어진 이미지는 직접 수정하는 개념보다&lt;br /&gt;새로 빌드해서 교체하는 방식에 가깝습니다.&lt;/p&gt;
&lt;p data-end=&quot;7253&quot; data-start=&quot;7184&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7283&quot; data-start=&quot;7255&quot; data-ke-size=&quot;size16&quot;&gt;반면 컨테이너는 실행 중 상태가 바뀔 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;7283&quot; data-start=&quot;7255&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7382&quot; data-start=&quot;7285&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 컨테이너 안에서 파일을 수정하거나 프로그램을 설치할 수 있지만,&lt;br /&gt;그 변경은 원본 이미지에 직접 반영되는 것이 아니라&lt;br /&gt;컨테이너의 쓰기 계층에 따로 저장됩니다.&lt;/p&gt;
&lt;p data-end=&quot;7382&quot; data-start=&quot;7285&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7386&quot; data-start=&quot;7384&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;7437&quot; data-start=&quot;7388&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;7397&quot; data-start=&quot;7388&quot; data-section-id=&quot;c252pk&quot;&gt;이미지는 원본&lt;/li&gt;
&lt;li data-end=&quot;7409&quot; data-start=&quot;7398&quot; data-section-id=&quot;1br2ysx&quot;&gt;컨테이너는 실행본&lt;/li&gt;
&lt;li data-end=&quot;7437&quot; data-start=&quot;7410&quot; data-section-id=&quot;kqjj85&quot;&gt;컨테이너의 변경 사항은 해당 컨테이너에만 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;7443&quot; data-start=&quot;7439&quot; data-ke-size=&quot;size16&quot;&gt;됩니다.&lt;/p&gt;
&lt;p data-end=&quot;7443&quot; data-start=&quot;7439&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7503&quot; data-start=&quot;7445&quot; data-ke-size=&quot;size16&quot;&gt;같은 이미지로 만든 A 컨테이너를 수정해도&lt;br /&gt;B 컨테이너에는 영향을 주지 않는 이유가 바로 이것입니다.&lt;/p&gt;
&lt;hr data-end=&quot;7615&quot; data-start=&quot;7612&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;7646&quot; data-start=&quot;7617&quot; data-section-id=&quot;1f9ua8m&quot; data-ke-size=&quot;size26&quot;&gt;7. 이미지의 핵심 특징: 불변성과 레이어 구조&lt;/h2&gt;
&lt;p data-end=&quot;7729&quot; data-start=&quot;7648&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지가 어떻게 관리되는지를 이해하려면&lt;br /&gt;&lt;b&gt;불변성(Immutable)&lt;/b&gt; 과 &lt;b&gt;레이어(Layer)&lt;/b&gt; 개념을 꼭 알아야 합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;7752&quot; data-start=&quot;7731&quot; data-section-id=&quot;1qsvsk1&quot; data-ke-size=&quot;size23&quot;&gt;7.1 이미지는 변경할 수 없다&lt;/h3&gt;
&lt;p data-end=&quot;7778&quot; data-start=&quot;7754&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 기본적으로 불변입니다.&lt;/p&gt;
&lt;p data-end=&quot;7778&quot; data-start=&quot;7754&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7846&quot; data-start=&quot;7780&quot; data-ke-size=&quot;size16&quot;&gt;즉, 한 번 생성된 이미지를 직접 수정해서 덮어쓰는 방식이 아니라&lt;br /&gt;변경이 필요하면 새로운 이미지를 다시 빌드합니다.&lt;/p&gt;
&lt;p data-end=&quot;7846&quot; data-start=&quot;7780&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7931&quot; data-start=&quot;7848&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 코드가 수정되었거나 패키지가 추가되었다면&lt;br /&gt;기존 이미지를 고치는 것이 아니라&lt;br /&gt;그 상태를 반영한 새로운 이미지를 다시 만들어야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;7931&quot; data-start=&quot;7848&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7963&quot; data-start=&quot;7933&quot; data-ke-size=&quot;size16&quot;&gt;이 방식은 번거로워 보일 수 있지만 장점이 분명합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;8039&quot; data-start=&quot;7965&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;7983&quot; data-start=&quot;7965&quot; data-section-id=&quot;1qhov3w&quot;&gt;실행 환경이 항상 예측 가능함&lt;/li&gt;
&lt;li data-end=&quot;8013&quot; data-start=&quot;7984&quot; data-section-id=&quot;1y63240&quot;&gt;같은 이미지라면 어디서 실행해도 동일한 결과 보장&lt;/li&gt;
&lt;li data-end=&quot;8025&quot; data-start=&quot;8014&quot; data-section-id=&quot;7zpgko&quot;&gt;버전 관리가 쉬움&lt;/li&gt;
&lt;li data-end=&quot;8039&quot; data-start=&quot;8026&quot; data-section-id=&quot;1a4syh1&quot;&gt;배포 이력이 명확해짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;8116&quot; data-start=&quot;8041&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker는&lt;br /&gt;&amp;ldquo;실행 중인 환경을 직접 고쳐 쓰는 방식&amp;rdquo;보다&lt;br /&gt;&amp;ldquo;새로운 버전을 다시 만들어 교체하는 방식&amp;rdquo;에 더 가깝습니다.&lt;/p&gt;
&lt;hr data-end=&quot;8121&quot; data-start=&quot;8118&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;8148&quot; data-start=&quot;8123&quot; data-section-id=&quot;8nv7no&quot; data-ke-size=&quot;size23&quot;&gt;7.2 이미지는 여러 레이어로 구성된다&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1251&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cicWSI/dJMcagkNkkE/TODdIQnGEHwdlnb5HCdo3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cicWSI/dJMcagkNkkE/TODdIQnGEHwdlnb5HCdo3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cicWSI/dJMcagkNkkE/TODdIQnGEHwdlnb5HCdo3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcicWSI%2FdJMcagkNkkE%2FTODdIQnGEHwdlnb5HCdo3K%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;1251&quot; height=&quot;632&quot; data-origin-width=&quot;1251&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;8208&quot; data-start=&quot;8150&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 하나의 덩어리 파일처럼 보이지만,&lt;br /&gt;내부적으로는 여러 레이어가 쌓여서 구성됩니다.&lt;/p&gt;
&lt;p data-end=&quot;8208&quot; data-start=&quot;8150&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;8246&quot; data-start=&quot;8210&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 아래와 같은 Dockerfile이 있다고 해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775809931273&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;8454&quot; data-start=&quot;8390&quot; data-ke-size=&quot;size16&quot;&gt;이 Dockerfile은 한 번에 전체가 만들어지는 것이 아니라,&lt;br /&gt;각 명령어 단위로 레이어가 쌓이는 구조입니다.&lt;/p&gt;
&lt;p data-end=&quot;8454&quot; data-start=&quot;8390&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;8474&quot; data-start=&quot;8456&quot; data-ke-size=&quot;size16&quot;&gt;대략적인 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;8758&quot; data-start=&quot;8476&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;8532&quot; data-start=&quot;8476&quot; data-section-id=&quot;1vm1n7h&quot;&gt;&lt;b&gt;FROM node:22-alpine&lt;/b&gt;&lt;br /&gt;&amp;rarr; Node.js 22 기반의 베이스 이미지 레이어&lt;/li&gt;
&lt;li data-end=&quot;8570&quot; data-start=&quot;8533&quot; data-section-id=&quot;130x7jw&quot;&gt;&lt;b&gt;WORKDIR /app&lt;/b&gt;&lt;br /&gt;&amp;rarr; 작업 디렉토리 설정 레이어&lt;/li&gt;
&lt;li data-end=&quot;8633&quot; data-start=&quot;8571&quot; data-section-id=&quot;1jqknn2&quot;&gt;&lt;b&gt;COPY package.json package-lock.json ./&lt;/b&gt;&lt;br /&gt;&amp;rarr; 의존성 파일 복사 레이어&lt;/li&gt;
&lt;li data-end=&quot;8670&quot; data-start=&quot;8634&quot; data-section-id=&quot;164rudv&quot;&gt;&lt;b&gt;RUN npm install&lt;/b&gt;&lt;br /&gt;&amp;rarr; 패키지 설치 레이어&lt;/li&gt;
&lt;li data-end=&quot;8705&quot; data-start=&quot;8671&quot; data-section-id=&quot;11tgo3g&quot;&gt;&lt;b&gt;COPY . .&lt;/b&gt;&lt;br /&gt;&amp;rarr; 실제 소스 코드 복사 레이어&lt;/li&gt;
&lt;li data-end=&quot;8758&quot; data-start=&quot;8706&quot; data-section-id=&quot;1y52p0h&quot;&gt;&lt;b&gt;CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]&lt;/b&gt;&lt;br /&gt;&amp;rarr; 컨테이너 실행 기본 명령 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;8800&quot; data-start=&quot;8760&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지는 여러 단계의 파일 시스템 변경이 차곡차곡 쌓인 결과입니다.&lt;/p&gt;
&lt;hr data-end=&quot;8805&quot; data-start=&quot;8802&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;8829&quot; data-start=&quot;8807&quot; data-section-id=&quot;1tgbd5h&quot; data-ke-size=&quot;size23&quot;&gt;7.3 레이어 구조가 중요한 이유&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo0LWf/dJMcahDZQcb/2ooxaCOMI1JZGPzok52MUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo0LWf/dJMcahDZQcb/2ooxaCOMI1JZGPzok52MUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo0LWf/dJMcahDZQcb/2ooxaCOMI1JZGPzok52MUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo0LWf%2FdJMcahDZQcb%2F2ooxaCOMI1JZGPzok52MUK%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;1108&quot; height=&quot;285&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;285&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;1280&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ryyKN/dJMcacipR9a/3kE1ic7gR9021VjAkKK1k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ryyKN/dJMcacipR9a/3kE1ic7gR9021VjAkKK1k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ryyKN/dJMcacipR9a/3kE1ic7gR9021VjAkKK1k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FryyKN%2FdJMcacipR9a%2F3kE1ic7gR9021VjAkKK1k0%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;1280&quot; height=&quot;506&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;8865&quot; data-start=&quot;8831&quot; data-ke-size=&quot;size16&quot;&gt;레이어 구조는 Docker의 성능과 효율성에 매우 중요합니다.&lt;/p&gt;
&lt;h4 data-end=&quot;8887&quot; data-start=&quot;8867&quot; data-ke-size=&quot;size20&quot;&gt;1) 캐시를 활용할 수 있다&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E1ryP/dJMcagSEIzt/dW6jKnk0pTNJRlr76FK8EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E1ryP/dJMcagSEIzt/dW6jKnk0pTNJRlr76FK8EK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E1ryP/dJMcagSEIzt/dW6jKnk0pTNJRlr76FK8EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE1ryP%2FdJMcagSEIzt%2FdW6jKnk0pTNJRlr76FK8EK%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;1280&quot; height=&quot;469&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;469&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;1280&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBOS4P/dJMcag6bIr5/F9sB3E6tU3gUoAg1xqjbtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBOS4P/dJMcag6bIr5/F9sB3E6tU3gUoAg1xqjbtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBOS4P/dJMcag6bIr5/F9sB3E6tU3gUoAg1xqjbtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBOS4P%2FdJMcag6bIr5%2FF9sB3E6tU3gUoAg1xqjbtK%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;1280&quot; height=&quot;522&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;8929&quot; data-start=&quot;8889&quot; data-ke-size=&quot;size16&quot;&gt;이전에 빌드한 레이어와 동일하면 다시 만들지 않고 재사용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;8929&quot; data-start=&quot;8889&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9012&quot; data-start=&quot;8931&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 package.json이 바뀌지 않았다면&lt;br /&gt;RUN npm install 레이어를 다시 만들지 않고 캐시를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;9012&quot; data-start=&quot;8931&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9038&quot; data-start=&quot;9014&quot; data-ke-size=&quot;size16&quot;&gt;그래서 보통 Dockerfile 작성 시에는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775810036210&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY package.json package-lock.json ./
RUN npm install
COPY . .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;9178&quot; data-start=&quot;9123&quot; data-ke-size=&quot;size16&quot;&gt;처럼 의존성 파일을 먼저 복사하고 설치한 뒤, 나중에 소스 코드를 복사하는 패턴을 많이 사용합니다.&lt;/p&gt;
&lt;p data-end=&quot;9178&quot; data-start=&quot;9123&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9235&quot; data-start=&quot;9180&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 코드만 수정됐을 때 매번 &lt;span style=&quot;background-color: #c0d1e7;&quot; data-darkreader-inline-bgcolor=&quot;&quot;&gt;npm install&lt;/span&gt;을 다시 하지 않아도 되기 때문입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;9255&quot; data-start=&quot;9237&quot; data-ke-size=&quot;size20&quot;&gt;2) 이미지 확장이 쉽다&lt;/h4&gt;
&lt;p data-end=&quot;9346&quot; data-start=&quot;9257&quot; data-ke-size=&quot;size16&quot;&gt;기존 베이스 이미지 위에 필요한 레이어만 추가하면 되기 때문에&lt;br /&gt;Node 이미지, Python 이미지 같은 공식 이미지를 기반으로 손쉽게 확장할 수 있습니다.&lt;/p&gt;
&lt;h4 data-end=&quot;9369&quot; data-start=&quot;9348&quot; data-ke-size=&quot;size20&quot;&gt;3) 저장과 전송이 효율적이다&lt;/h4&gt;
&lt;p data-end=&quot;9422&quot; data-start=&quot;9371&quot; data-ke-size=&quot;size16&quot;&gt;변경된 레이어만 전송하거나 재사용할 수 있기 때문에&lt;br /&gt;빌드와 배포 과정이 더 효율적입니다.&lt;/p&gt;
&lt;p data-end=&quot;9422&quot; data-start=&quot;9371&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9489&quot; data-start=&quot;9424&quot; data-ke-size=&quot;size16&quot;&gt;즉, 레이어 구조는 단순한 내부 구현이 아니라&lt;br /&gt;Docker가 빠르고 효율적으로 동작하는 핵심 이유 중 하나입니다.&lt;/p&gt;
&lt;hr data-end=&quot;9684&quot; data-start=&quot;9681&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;9705&quot; data-start=&quot;9686&quot; data-section-id=&quot;1uvkppm&quot; data-ke-size=&quot;size26&quot;&gt;8. Dockerfile이란?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OJ684/dJMcahquYLL/5mhrcFym4AKm9ortm1zNIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OJ684/dJMcahquYLL/5mhrcFym4AKm9ortm1zNIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OJ684/dJMcahquYLL/5mhrcFym4AKm9ortm1zNIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOJ684%2FdJMcahquYLL%2F5mhrcFym4AKm9ortm1zNIk%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;1013&quot; height=&quot;554&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;9748&quot; data-start=&quot;9707&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9748&quot; data-start=&quot;9707&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile은 이미지를 만들기 위한 명령어들을 작성하는 파일입니다.&lt;/p&gt;
&lt;p data-end=&quot;9748&quot; data-start=&quot;9707&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9813&quot; data-start=&quot;9750&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;br /&gt;**&amp;ldquo;이 애플리케이션을 어떤 환경에서, 어떤 순서로 이미지화할 것인가&amp;rdquo;**를 정의한 빌드 스크립트입니다.&lt;/p&gt;
&lt;p data-end=&quot;9813&quot; data-start=&quot;9750&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9883&quot; data-start=&quot;9815&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile은 단순히 명령어를 적는 파일이 아니라,&lt;br /&gt;이미지 생성 과정을 문서처럼 선언적으로 표현하는 파일입니다.&lt;/p&gt;
&lt;p data-end=&quot;9883&quot; data-start=&quot;9815&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;9902&quot; data-start=&quot;9885&quot; data-ke-size=&quot;size16&quot;&gt;즉, Dockerfile만 보면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;9966&quot; data-start=&quot;9904&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;9922&quot; data-start=&quot;9904&quot; data-section-id=&quot;8uxe9p&quot;&gt;어떤 베이스 이미지를 사용할지&lt;/li&gt;
&lt;li data-end=&quot;9936&quot; data-start=&quot;9923&quot; data-section-id=&quot;21qwet&quot;&gt;어떤 파일을 복사할지&lt;/li&gt;
&lt;li data-end=&quot;9951&quot; data-start=&quot;9937&quot; data-section-id=&quot;1adf5uc&quot;&gt;어떤 패키지를 설치할지&lt;/li&gt;
&lt;li data-end=&quot;9966&quot; data-start=&quot;9952&quot; data-section-id=&quot;1k8z3ex&quot;&gt;어떤 명령으로 실행할지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;9985&quot; data-start=&quot;9968&quot; data-ke-size=&quot;size16&quot;&gt;를 한눈에 파악할 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;10009&quot; data-start=&quot;9987&quot; data-section-id=&quot;jvhhl2&quot; data-ke-size=&quot;size23&quot;&gt;8.1 Dockerfile의 역할&lt;/h3&gt;
&lt;p data-end=&quot;10045&quot; data-start=&quot;10011&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile의 역할은 크게 네 가지로 볼 수 있습니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10063&quot; data-start=&quot;10047&quot; data-ke-size=&quot;size20&quot;&gt;1) 실행 환경 정의&lt;/h4&gt;
&lt;p data-end=&quot;10095&quot; data-start=&quot;10065&quot; data-ke-size=&quot;size16&quot;&gt;어떤 런타임과 어떤 OS 기반에서 시작할지를 정합니다.&lt;/p&gt;
&lt;p data-end=&quot;10102&quot; data-start=&quot;10097&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811794629&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM node:22-alpine&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10197&quot; data-start=&quot;10143&quot; data-ke-size=&quot;size16&quot;&gt;는&lt;br /&gt;Node.js 22가 설치된 Alpine Linux 기반 환경에서 시작하겠다는 의미입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10219&quot; data-start=&quot;10199&quot; data-ke-size=&quot;size20&quot;&gt;2) 애플리케이션 파일 복사&lt;/h4&gt;
&lt;p data-end=&quot;10253&quot; data-start=&quot;10221&quot; data-ke-size=&quot;size16&quot;&gt;내 로컬에 있는 프로젝트 파일을 이미지 안으로 복사합니다.&lt;/p&gt;
&lt;p data-end=&quot;10260&quot; data-start=&quot;10255&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811866473&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY . .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10323&quot; data-start=&quot;10290&quot; data-ke-size=&quot;size16&quot;&gt;는 현재 폴더의 파일을 이미지 내부로 복사하겠다는 뜻입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10343&quot; data-start=&quot;10325&quot; data-ke-size=&quot;size20&quot;&gt;3) 필요한 의존성 설치&lt;/h4&gt;
&lt;p data-end=&quot;10378&quot; data-start=&quot;10345&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션 실행에 필요한 패키지를 이미지 안에 설치합니다.&lt;/p&gt;
&lt;p data-end=&quot;10385&quot; data-start=&quot;10380&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811872084&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RUN npm install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10480&quot; data-start=&quot;10422&quot; data-ke-size=&quot;size16&quot;&gt;는 컨테이너 내부 환경에서 npm install을 실행해&lt;br /&gt;필요한 패키지를 설치하겠다는 의미입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10503&quot; data-start=&quot;10482&quot; data-ke-size=&quot;size20&quot;&gt;4) 컨테이너 시작 명령 정의&lt;/h4&gt;
&lt;p data-end=&quot;10541&quot; data-start=&quot;10505&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 실행했을 때 어떤 명령어를 기본으로 실행할지를 정합니다.&lt;/p&gt;
&lt;p data-end=&quot;10548&quot; data-start=&quot;10543&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811878600&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10637&quot; data-start=&quot;10595&quot; data-ke-size=&quot;size16&quot;&gt;는 컨테이너가 시작될 때 npm run dev를 실행하겠다는 의미입니다.&lt;/p&gt;
&lt;hr data-end=&quot;10642&quot; data-start=&quot;10639&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;10672&quot; data-start=&quot;10644&quot; data-section-id=&quot;cfclps&quot; data-ke-size=&quot;size23&quot;&gt;8.2 자주 쓰는 Dockerfile 명령어&lt;/h3&gt;
&lt;h4 data-end=&quot;10685&quot; data-start=&quot;10674&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;10696&quot; data-start=&quot;10686&quot; data-ke-size=&quot;size16&quot;&gt;베이스 이미지 지정&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811903960&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM node:22-alpine&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;10751&quot; data-start=&quot;10737&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;WORKDIR&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;10762&quot; data-start=&quot;10752&quot; data-ke-size=&quot;size16&quot;&gt;작업 디렉토리 지정&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775811920813&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WORKDIR /app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10823&quot; data-start=&quot;10796&quot; data-ke-size=&quot;size16&quot;&gt;이후 명령어들은 /app 기준으로 실행됩니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10836&quot; data-start=&quot;10825&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;COPY&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;10842&quot; data-start=&quot;10837&quot; data-ke-size=&quot;size16&quot;&gt;파일 복사&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775811928148&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY . .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10898&quot; data-start=&quot;10872&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트 파일을 이미지 내부로 복사합니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10910&quot; data-start=&quot;10900&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;RUN&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;10930&quot; data-start=&quot;10911&quot; data-ke-size=&quot;size16&quot;&gt;이미지 빌드 과정에서 실행할 명령어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775811937493&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RUN npm install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;10985&quot; data-start=&quot;10967&quot; data-ke-size=&quot;size16&quot;&gt;빌드 시점에 패키지를 설치합니다.&lt;/p&gt;
&lt;h4 data-end=&quot;10997&quot; data-start=&quot;10987&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;CMD&lt;/span&gt;&lt;/h4&gt;
&lt;p data-end=&quot;11020&quot; data-start=&quot;10998&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 실행 시 기본으로 실행할 명령어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775811968154&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CMD [&quot;npm&quot;, &quot;run&quot;, &quot;dev&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11085&quot; data-start=&quot;11067&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너가 시작될 때 실행됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;11090&quot; data-start=&quot;11087&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;11118&quot; data-start=&quot;11092&quot; data-section-id=&quot;d64vqs&quot; data-ke-size=&quot;size23&quot;&gt;8.3 Dockerfile은 왜 중요한가&lt;/h3&gt;
&lt;p data-end=&quot;11197&quot; data-start=&quot;11120&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile이 중요한 이유는&lt;br /&gt;이미지를 사람 손으로 직접 만드는 것이 아니라&lt;br /&gt;코드처럼 재현 가능하게 만들 수 있기 때문입니다.&lt;/p&gt;
&lt;p data-end=&quot;11197&quot; data-start=&quot;11120&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;11217&quot; data-start=&quot;11199&quot; data-ke-size=&quot;size16&quot;&gt;즉, Dockerfile이 있으면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;11282&quot; data-start=&quot;11219&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;11238&quot; data-start=&quot;11219&quot; data-section-id=&quot;11xe550&quot;&gt;누구나 동일한 이미지 생성 가능&lt;/li&gt;
&lt;li data-end=&quot;11252&quot; data-start=&quot;11239&quot; data-section-id=&quot;1a78w58&quot;&gt;배포 환경 재현 가능&lt;/li&gt;
&lt;li data-end=&quot;11263&quot; data-start=&quot;11253&quot; data-section-id=&quot;1o19s81&quot;&gt;버전 관리 가능&lt;/li&gt;
&lt;li data-end=&quot;11282&quot; data-start=&quot;11264&quot; data-section-id=&quot;fqn43d&quot;&gt;빌드 과정을 문서화할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;11340&quot; data-start=&quot;11284&quot; data-ke-size=&quot;size16&quot;&gt;결국 Dockerfile은&lt;br /&gt;&lt;b&gt;이미지 빌드 과정을 코드로 관리하는 파일&lt;/b&gt;이라고 볼 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;11477&quot; data-start=&quot;11474&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;11500&quot; data-start=&quot;11479&quot; data-section-id=&quot;bzufj5&quot; data-ke-size=&quot;size26&quot;&gt;9. 이미지는 어떻게 만들어지는가&lt;/h2&gt;
&lt;p data-end=&quot;11531&quot; data-start=&quot;11502&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 보통 다음 흐름으로 생성됩니다.&lt;/p&gt;
&lt;h3 data-end=&quot;11554&quot; data-start=&quot;11533&quot; data-section-id=&quot;7qptn6&quot; data-ke-size=&quot;size23&quot;&gt;9.1 Dockerfile 작성&lt;/h3&gt;
&lt;p data-end=&quot;11585&quot; data-start=&quot;11556&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 루트에 Dockerfile을 작성합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;11601&quot; data-start=&quot;11587&quot; data-section-id=&quot;1qincin&quot; data-ke-size=&quot;size23&quot;&gt;9.2 이미지 빌드&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775812001734&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build -t my-app .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11681&quot; data-start=&quot;11641&quot; data-ke-size=&quot;size16&quot;&gt;이 명령어를 실행하면 Dockerfile을 기반으로 이미지가 생성됩니다.&lt;/p&gt;
&lt;h3 data-end=&quot;11698&quot; data-start=&quot;11683&quot; data-section-id=&quot;vlen9z&quot; data-ke-size=&quot;size23&quot;&gt;9.3 컨테이너 실행&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775812010925&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -p 5173:5173 my-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;11768&quot; data-start=&quot;11744&quot; data-ke-size=&quot;size16&quot;&gt;생성된 이미지를 실행하면 컨테이너가 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;11789&quot; data-start=&quot;11770&quot; data-ke-size=&quot;size16&quot;&gt;즉, 전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775812019787&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Dockerfile
&amp;darr;
docker build
&amp;darr;
Docker Image
&amp;darr;
docker run
&amp;darr;
Docker Container&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXFbU9/dJMcaiv76wS/HtwZeDUwkwFZipuswGK3vK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXFbU9%2FdJMcaiv76wS%2FHtwZeDUwkwFZipuswGK3vK%2Fimg.jpg&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;825&quot; height=&quot;481&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;11973&quot; data-start=&quot;11970&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;11999&quot; data-start=&quot;11975&quot; data-section-id=&quot;1es1qro&quot; data-ke-size=&quot;size26&quot;&gt;10. 이미지 이름은 어떻게 구성되는가&lt;/h2&gt;
&lt;p data-end=&quot;12031&quot; data-start=&quot;12001&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지 이름은 보통 아래 형태를 따릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUY7ME/dJMcadaujBC/kcJQYifXrPJIiCJFpD1aGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUY7ME/dJMcadaujBC/kcJQYifXrPJIiCJFpD1aGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUY7ME/dJMcadaujBC/kcJQYifXrPJIiCJFpD1aGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUY7ME%2FdJMcadaujBC%2FkcJQYifXrPJIiCJFpD1aGk%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;1536&quot; height=&quot;1024&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&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;pre id=&quot;code_1775812035222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[저장소 이름]/[이미지 이름]:[태그]&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12084&quot; data-start=&quot;12069&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775812044267&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;myrepo/my-app:1.0&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;12136&quot; data-start=&quot;12117&quot; data-ke-size=&quot;size16&quot;&gt;각 부분의 의미는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;12190&quot; data-start=&quot;12138&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;12160&quot; data-start=&quot;12138&quot; data-section-id=&quot;1v1fxsi&quot;&gt;저장소 이름: 이미지가 저장되는 위치&lt;/li&gt;
&lt;li data-end=&quot;12178&quot; data-start=&quot;12161&quot; data-section-id=&quot;bxce7r&quot;&gt;이미지 이름: 이미지의 역할&lt;/li&gt;
&lt;li data-end=&quot;12190&quot; data-start=&quot;12179&quot; data-section-id=&quot;kvy0qf&quot;&gt;태그: 버전 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;12223&quot; data-start=&quot;12192&quot; data-ke-size=&quot;size16&quot;&gt;태그를 생략하면 일반적으로 latest로 인식합니다.&lt;/p&gt;
&lt;p data-end=&quot;12223&quot; data-start=&quot;12192&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12296&quot; data-start=&quot;12225&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지 이름은 단순한 문자열이 아니라&lt;br /&gt;어디 저장되어 있고, 어떤 역할을 하며, 어떤 버전인지까지 포함하는 식별자입니다.&lt;/p&gt;
&lt;hr data-end=&quot;12374&quot; data-start=&quot;12371&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;12403&quot; data-start=&quot;12376&quot; data-section-id=&quot;1qdpoyk&quot; data-ke-size=&quot;size26&quot;&gt;11. Registry와 Repository&lt;/h2&gt;
&lt;p data-end=&quot;12428&quot; data-start=&quot;12405&quot; 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;814&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caYVuU/dJMcagyj2sT/4UaG4HgTmKuynvEZGt0Sek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caYVuU/dJMcagyj2sT/4UaG4HgTmKuynvEZGt0Sek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caYVuU/dJMcagyj2sT/4UaG4HgTmKuynvEZGt0Sek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaYVuU%2FdJMcagyj2sT%2F4UaG4HgTmKuynvEZGt0Sek%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;764&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;12447&quot; data-start=&quot;12430&quot; data-section-id=&quot;javrws&quot; data-ke-size=&quot;size23&quot;&gt;11.1 Registry&lt;/h3&gt;
&lt;p data-end=&quot;12479&quot; data-start=&quot;12449&quot; data-ke-size=&quot;size16&quot;&gt;Registry는 이미지를 저장하는 중앙 저장소입니다.&lt;/p&gt;
&lt;p data-end=&quot;12479&quot; data-start=&quot;12449&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12516&quot; data-start=&quot;12481&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Docker Hub는 대표적인 Registry입니다.&lt;/p&gt;
&lt;p data-end=&quot;12516&quot; data-start=&quot;12481&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12548&quot; data-start=&quot;12518&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지를 push 하고 pull 받는 서버입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;12569&quot; data-start=&quot;12550&quot; data-section-id=&quot;286hug&quot; data-ke-size=&quot;size23&quot;&gt;11.2 Repository&lt;/h3&gt;
&lt;p data-end=&quot;12616&quot; data-start=&quot;12571&quot; data-ke-size=&quot;size16&quot;&gt;Repository는 Registry 안에서 관련 이미지들을 묶어두는 단위입니다.&lt;/p&gt;
&lt;p data-end=&quot;12616&quot; data-start=&quot;12571&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12647&quot; data-start=&quot;12618&quot; data-ke-size=&quot;size16&quot;&gt;하나의 프로젝트 폴더처럼 생각하면 이해하기 쉽습니다.&lt;/p&gt;
&lt;p data-end=&quot;12647&quot; data-start=&quot;12618&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12758&quot; data-start=&quot;12649&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Docker Hub라는 Registry 안에&lt;br /&gt;my-app이라는 Repository가 있고,&lt;br /&gt;그 안에 1.0, 1.1, latest 같은 태그가 존재할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;12762&quot; data-start=&quot;12760&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;12817&quot; data-start=&quot;12764&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;12787&quot; data-start=&quot;12764&quot; data-section-id=&quot;9emyfp&quot;&gt;Registry = 전체 이미지 저장소&lt;/li&gt;
&lt;li data-end=&quot;12817&quot; data-start=&quot;12788&quot; data-section-id=&quot;1cqbetq&quot;&gt;Repository = 특정 프로젝트 이미지 모음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;12823&quot; data-start=&quot;12819&quot; data-ke-size=&quot;size16&quot;&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;12903&quot; data-start=&quot;12900&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;12928&quot; data-start=&quot;12905&quot; data-section-id=&quot;av49i0&quot; data-ke-size=&quot;size26&quot;&gt;12. 왜 이미지를 만들어두면 편한가&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQy5X7/dJMcahqu1ld/EpDY32fvPSfaXQ6lfkBX00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQy5X7/dJMcahqu1ld/EpDY32fvPSfaXQ6lfkBX00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQy5X7/dJMcahqu1ld/EpDY32fvPSfaXQ6lfkBX00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQy5X7%2FdJMcahqu1ld%2FEpDY32fvPSfaXQ6lfkBX00%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;1536&quot; height=&quot;1024&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;12982&quot; data-start=&quot;12930&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;12982&quot; data-start=&quot;12930&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 한 번 잘 만들어두면&lt;br /&gt;다른 컴퓨터에서도 동일한 방식으로 쉽게 실행할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;12982&quot; data-start=&quot;12930&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13028&quot; data-start=&quot;12984&quot; data-ke-size=&quot;size16&quot;&gt;즉, 내 컴퓨터에서 동작하던 환경을&lt;br /&gt;그대로 다른 환경으로 옮길 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;13028&quot; data-start=&quot;12984&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13053&quot; data-start=&quot;13030&quot; data-ke-size=&quot;size16&quot;&gt;이 방식은 특히 다음 상황에서 강력합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;13094&quot; data-start=&quot;13055&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;13065&quot; data-start=&quot;13055&quot; data-section-id=&quot;spt2r4&quot;&gt;협업 환경 통일&lt;/li&gt;
&lt;li data-end=&quot;13074&quot; data-start=&quot;13066&quot; data-section-id=&quot;1j7imw9&quot;&gt;배포 자동화&lt;/li&gt;
&lt;li data-end=&quot;13082&quot; data-start=&quot;13075&quot; data-section-id=&quot;u9l3s0&quot;&gt;서버 이전&lt;/li&gt;
&lt;li data-end=&quot;13094&quot; data-start=&quot;13083&quot; data-section-id=&quot;1sqfidx&quot;&gt;테스트 환경 재현&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;13154&quot; data-start=&quot;13096&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 Registry에 올려두면&lt;br /&gt;다른 사람은 복잡한 설정 없이 pull 받아 실행만 하면 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;13154&quot; data-start=&quot;13096&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13206&quot; data-start=&quot;13156&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Docker는 개발 환경뿐 아니라&lt;br /&gt;운영 환경과 CI/CD에서도 많이 사용됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;13305&quot; data-start=&quot;13302&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;13336&quot; data-start=&quot;13307&quot; data-section-id=&quot;1gt7dv5&quot; data-ke-size=&quot;size26&quot;&gt;13. 컨테이너는 하나의 역할만 맡는 것이 좋다&lt;/h2&gt;
&lt;p data-end=&quot;13367&quot; data-start=&quot;13338&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너를 사용할 때 자주 언급되는 원칙이 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;13367&quot; data-start=&quot;13338&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13404&quot; data-start=&quot;13369&quot; data-ke-size=&quot;size16&quot;&gt;하나의 컨테이너는 하나의 역할에 집중하는 것이 좋다는 점입니다.&lt;/p&gt;
&lt;p data-end=&quot;13404&quot; data-start=&quot;13369&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13427&quot; data-start=&quot;13406&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 다음처럼 나누는 방식입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;13479&quot; data-start=&quot;13429&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;13441&quot; data-start=&quot;13429&quot; data-section-id=&quot;1gp7f2c&quot;&gt;프론트엔드 컨테이너&lt;/li&gt;
&lt;li data-end=&quot;13452&quot; data-start=&quot;13442&quot; data-section-id=&quot;1fbvt6x&quot;&gt;백엔드 컨테이너&lt;/li&gt;
&lt;li data-end=&quot;13466&quot; data-start=&quot;13453&quot; data-section-id=&quot;osw9zo&quot;&gt;데이터베이스 컨테이너&lt;/li&gt;
&lt;li data-end=&quot;13479&quot; data-start=&quot;13467&quot; data-section-id=&quot;psgntw&quot;&gt;캐시 서버 컨테이너&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;13505&quot; data-start=&quot;13481&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 역할을 나누면 다음 장점이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;13548&quot; data-start=&quot;13507&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;13515&quot; data-start=&quot;13507&quot; data-section-id=&quot;ff5sso&quot;&gt;관리가 쉬움&lt;/li&gt;
&lt;li data-end=&quot;13529&quot; data-start=&quot;13516&quot; data-section-id=&quot;mjqdsg&quot;&gt;장애 범위 분리 가능&lt;/li&gt;
&lt;li data-end=&quot;13537&quot; data-start=&quot;13530&quot; data-section-id=&quot;3c8qed&quot;&gt;확장 용이&lt;/li&gt;
&lt;li data-end=&quot;13548&quot; data-start=&quot;13538&quot; data-section-id=&quot;2qgrjc&quot;&gt;배포 단위 명확&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;13586&quot; data-start=&quot;13550&quot; data-ke-size=&quot;size16&quot;&gt;즉, 컨테이너는 작고 분리된 단위로 설계할수록 관리가 쉬워집니다.&lt;/p&gt;
&lt;hr data-end=&quot;13681&quot; data-start=&quot;13678&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;13706&quot; data-start=&quot;13683&quot; data-section-id=&quot;16x1be5&quot; data-ke-size=&quot;size26&quot;&gt;14. Docker Compose란?&lt;/h2&gt;
&lt;p data-end=&quot;13747&quot; data-start=&quot;13708&quot; data-ke-size=&quot;size16&quot;&gt;실제 애플리케이션은 하나의 컨테이너만으로 끝나지 않는 경우가 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;13754&quot; data-start=&quot;13749&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;13786&quot; data-start=&quot;13756&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;13763&quot; data-start=&quot;13756&quot; data-section-id=&quot;722qkc&quot;&gt;프론트엔드&lt;/li&gt;
&lt;li data-end=&quot;13769&quot; data-start=&quot;13764&quot; data-section-id=&quot;2109n5&quot;&gt;백엔드&lt;/li&gt;
&lt;li data-end=&quot;13778&quot; data-start=&quot;13770&quot; data-section-id=&quot;xzv5nw&quot;&gt;데이터베이스&lt;/li&gt;
&lt;li data-end=&quot;13786&quot; data-start=&quot;13779&quot; data-section-id=&quot;179h5y9&quot;&gt;Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;13816&quot; data-start=&quot;13788&quot; data-ke-size=&quot;size16&quot;&gt;처럼 여러 서비스가 함께 동작해야 할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;13816&quot; data-start=&quot;13788&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13870&quot; data-start=&quot;13818&quot; data-ke-size=&quot;size16&quot;&gt;이때 각각을 docker run으로 하나씩 띄우면&lt;br /&gt;설정도 길어지고 관리도 어려워집니다.&lt;/p&gt;
&lt;p data-end=&quot;13870&quot; data-start=&quot;13818&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;13909&quot; data-start=&quot;13872&quot; data-ke-size=&quot;size16&quot;&gt;Docker Compose는 이런 문제를 해결하기 위해 사용합니다.&lt;/p&gt;
&lt;p data-end=&quot;13981&quot; data-start=&quot;13911&quot; data-ke-size=&quot;size16&quot;&gt;여러 컨테이너와 그 설정을&lt;br /&gt;하나의 YAML 파일에 정의하고,&lt;br /&gt;한 번의 명령으로 함께 실행할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZemZ1/dJMcabjw2TT/XgolKkWsZh8iWC8P6IYc5K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZemZ1/dJMcabjw2TT/XgolKkWsZh8iWC8P6IYc5K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZemZ1/dJMcabjw2TT/XgolKkWsZh8iWC8P6IYc5K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZemZ1%2FdJMcabjw2TT%2FXgolKkWsZh8iWC8P6IYc5K%2Fimg.jpg&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;1280&quot; height=&quot;853&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;14002&quot; data-start=&quot;13983&quot; data-section-id=&quot;p6wpnk&quot; data-ke-size=&quot;size23&quot;&gt;14.1 Compose 예시&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775812154349&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: &quot;3&quot;

services:
app:
build: .
ports:
- &quot;5173:5173&quot;

db:
image: postgres&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;14127&quot; data-start=&quot;14119&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 작성하면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775812159083&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;14192&quot; data-start=&quot;14160&quot; data-ke-size=&quot;size16&quot;&gt;명령어 한 번으로 여러 서비스를 함께 실행할 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;14214&quot; data-start=&quot;14194&quot; data-section-id=&quot;x4ukpi&quot; data-ke-size=&quot;size23&quot;&gt;14.2 Compose의 핵심&lt;/h3&gt;
&lt;p data-end=&quot;14229&quot; data-start=&quot;14216&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;14285&quot; data-start=&quot;14231&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;14256&quot; data-start=&quot;14231&quot; data-section-id=&quot;5u19ha&quot;&gt;Dockerfile은 이미지를 만드는 파일&lt;/li&gt;
&lt;li data-end=&quot;14285&quot; data-start=&quot;14257&quot; data-section-id=&quot;x8q9ys&quot;&gt;Compose는 실행할 서비스들을 정의하는 파일&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;14333&quot; data-start=&quot;14287&quot; data-ke-size=&quot;size16&quot;&gt;즉, Dockerfile은 빌드 중심이고&lt;br /&gt;Compose는 실행 구성 중심입니다.&lt;/p&gt;
&lt;hr data-end=&quot;14423&quot; data-start=&quot;14420&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;14460&quot; data-start=&quot;14425&quot; data-section-id=&quot;1hlmxja&quot; data-ke-size=&quot;size26&quot;&gt;15. Dockerfile과 Compose는 무엇이 다른가&lt;/h2&gt;
&lt;p data-end=&quot;14483&quot; data-start=&quot;14462&quot; data-ke-size=&quot;size16&quot;&gt;둘은 비슷해 보이지만 역할이 다릅니다.&lt;/p&gt;
&lt;h3 data-end=&quot;14499&quot; data-start=&quot;14485&quot; data-section-id=&quot;lqpkxg&quot; data-ke-size=&quot;size23&quot;&gt;Dockerfile&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;14525&quot; data-start=&quot;14500&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;14514&quot; data-start=&quot;14500&quot; data-section-id=&quot;h5isc9&quot;&gt;이미지 생성 방법 정의&lt;/li&gt;
&lt;li data-end=&quot;14525&quot; data-start=&quot;14515&quot; data-section-id=&quot;1171c58&quot;&gt;빌드 과정 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;14541&quot; data-start=&quot;14527&quot; data-section-id=&quot;1lok7ha&quot; data-ke-size=&quot;size23&quot;&gt;Compose 파일&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;14569&quot; data-start=&quot;14542&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;14555&quot; data-start=&quot;14542&quot; data-section-id=&quot;1rmhtf4&quot;&gt;실행할 컨테이너 정의&lt;/li&gt;
&lt;li data-end=&quot;14569&quot; data-start=&quot;14556&quot; data-section-id=&quot;126mud9&quot;&gt;서비스 간 연결 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;14573&quot; data-start=&quot;14571&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;14629&quot; data-start=&quot;14575&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;14602&quot; data-start=&quot;14575&quot; data-section-id=&quot;zdtcab&quot;&gt;Dockerfile &amp;rarr; 이미지를 어떻게 만들지&lt;/li&gt;
&lt;li data-end=&quot;14629&quot; data-start=&quot;14603&quot; data-section-id=&quot;uvf02g&quot;&gt;Compose &amp;rarr; 컨테이너를 어떻게 실행할지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;14639&quot; data-start=&quot;14631&quot; data-ke-size=&quot;size16&quot;&gt;를 담당합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;99&quot; data-start=&quot;72&quot; data-section-id=&quot;16d52j2&quot; data-ke-size=&quot;size26&quot;&gt;Dockerfile vs Compose 비교&lt;/h2&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;579&quot; data-start=&quot;101&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;항목&lt;/td&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;Docker Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;219&quot; data-start=&quot;177&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;182&quot; data-start=&quot;177&quot;&gt;목적&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;199&quot; data-start=&quot;182&quot;&gt;이미지를 만드는 방법 정의&lt;/td&gt;
&lt;td data-end=&quot;219&quot; data-start=&quot;199&quot; data-col-size=&quot;sm&quot;&gt;여러 컨테이너를 실행하고 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;256&quot; data-start=&quot;220&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;225&quot; data-start=&quot;220&quot;&gt;대상&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;237&quot; data-start=&quot;225&quot;&gt;단일 이미지 빌드&lt;/td&gt;
&lt;td data-end=&quot;256&quot; data-start=&quot;237&quot; data-col-size=&quot;sm&quot;&gt;여러 서비스(컨테이너) 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;280&quot; data-start=&quot;257&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;265&quot; data-start=&quot;257&quot;&gt;중심 개념&lt;/td&gt;
&lt;td data-end=&quot;273&quot; data-start=&quot;265&quot; data-col-size=&quot;sm&quot;&gt;build&lt;/td&gt;
&lt;td data-end=&quot;280&quot; data-start=&quot;273&quot; data-col-size=&quot;sm&quot;&gt;run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;345&quot; data-start=&quot;281&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;289&quot; data-start=&quot;281&quot;&gt;작성 파일&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;304&quot; data-start=&quot;289&quot;&gt;Dockerfile&lt;/td&gt;
&lt;td data-end=&quot;345&quot; data-start=&quot;304&quot; data-col-size=&quot;sm&quot;&gt;compose.yml 또는 docker-compose.yml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;422&quot; data-start=&quot;346&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;354&quot; data-start=&quot;346&quot;&gt;주요 내용&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;389&quot; data-start=&quot;354&quot;&gt;베이스 이미지, 파일 복사, 패키지 설치, 실행 명령 정의&lt;/td&gt;
&lt;td data-end=&quot;422&quot; data-start=&quot;389&quot; data-col-size=&quot;sm&quot;&gt;서비스 정의, 포트, 볼륨, 네트워크, 환경변수 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;459&quot; data-start=&quot;423&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;431&quot; data-start=&quot;423&quot;&gt;사용 시점&lt;/td&gt;
&lt;td data-end=&quot;444&quot; data-start=&quot;431&quot; data-col-size=&quot;sm&quot;&gt;이미지를 생성할 때&lt;/td&gt;
&lt;td data-end=&quot;459&quot; data-start=&quot;444&quot; data-col-size=&quot;sm&quot;&gt;컨테이너를 실행할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;509&quot; data-start=&quot;460&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;469&quot; data-start=&quot;460&quot;&gt;대표 명령어&lt;/td&gt;
&lt;td data-end=&quot;486&quot; data-start=&quot;469&quot; data-col-size=&quot;sm&quot;&gt;docker build&lt;/td&gt;
&lt;td data-end=&quot;509&quot; data-start=&quot;486&quot; data-col-size=&quot;sm&quot;&gt;docker compose up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;557&quot; data-start=&quot;510&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;515&quot; data-start=&quot;510&quot;&gt;결과&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;533&quot; data-start=&quot;515&quot;&gt;Docker Image 생성&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;557&quot; data-start=&quot;533&quot;&gt;여러 Container 생성 및 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;579&quot; data-start=&quot;558&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;563&quot; data-start=&quot;558&quot;&gt;비유&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;569&quot; data-start=&quot;563&quot;&gt;설계도&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;579&quot; data-start=&quot;569&quot;&gt;실행 계획표&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;14712&quot; data-start=&quot;14709&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;14734&quot; data-start=&quot;14714&quot; data-section-id=&quot;1g3r7yh&quot; data-ke-size=&quot;size26&quot;&gt;16. 전체 흐름으로 다시 정리&lt;/h2&gt;
&lt;p data-end=&quot;14780&quot; data-start=&quot;14736&quot; data-ke-size=&quot;size16&quot;&gt;지금까지의 내용을 한 번에 정리하면 Docker의 전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;14922&quot; data-start=&quot;14782&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;14800&quot; data-start=&quot;14782&quot; data-section-id=&quot;1qu8phk&quot;&gt;Dockerfile 작성&lt;/li&gt;
&lt;li data-end=&quot;14828&quot; data-start=&quot;14801&quot; data-section-id=&quot;1v09rtz&quot;&gt;docker build로 이미지 생성&lt;/li&gt;
&lt;li data-end=&quot;14853&quot; data-start=&quot;14829&quot; data-section-id=&quot;8bpx2r&quot;&gt;이미지를 Registry에 push&lt;/li&gt;
&lt;li data-end=&quot;14871&quot; data-start=&quot;14854&quot; data-section-id=&quot;1l37e6n&quot;&gt;다른 환경에서 pull&lt;/li&gt;
&lt;li data-end=&quot;14922&quot; data-start=&quot;14872&quot; data-section-id=&quot;1s2nyq3&quot;&gt;docker run 또는 docker compose up으로 컨테이너 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;15013&quot; data-start=&quot;14924&quot; data-ke-size=&quot;size16&quot;&gt;즉, Docker는&lt;br /&gt;실행 환경을 코드처럼 정의하고,&lt;br /&gt;그 결과물을 이미지로 만들고,&lt;br /&gt;그 이미지를 어디서든 동일하게 실행할 수 있도록 해주는 구조입니다.&lt;/p&gt;
&lt;hr data-end=&quot;15089&quot; data-start=&quot;15086&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;15100&quot; data-start=&quot;15091&quot; data-section-id=&quot;yjrthw&quot; data-ke-size=&quot;size26&quot;&gt;17. 정리&lt;/h2&gt;
&lt;p data-end=&quot;15134&quot; data-start=&quot;15102&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 Docker의 기본 개념과 구조를 정리해봤습니다.&lt;/p&gt;
&lt;p data-end=&quot;15134&quot; data-start=&quot;15102&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;15223&quot; data-start=&quot;15136&quot; data-ke-size=&quot;size16&quot;&gt;Docker는 단순히 컨테이너를 띄우는 도구가 아니라,&lt;br /&gt;애플리케이션 실행 환경을 함께 묶어서&lt;br /&gt;어디서든 동일하게 실행할 수 있도록 해주는 플랫폼입니다.&lt;/p&gt;
&lt;p data-end=&quot;15223&quot; data-start=&quot;15136&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;15249&quot; data-start=&quot;15225&quot; data-ke-size=&quot;size16&quot;&gt;핵심 개념을 다시 정리하면 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;15416&quot; data-start=&quot;15251&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;15277&quot; data-start=&quot;15251&quot; data-section-id=&quot;44rbdg&quot;&gt;Docker는 실행 환경을 통째로 패키징한다&lt;/li&gt;
&lt;li data-end=&quot;15301&quot; data-start=&quot;15278&quot; data-section-id=&quot;1k6epzf&quot;&gt;Image는 실행 환경을 담은 패키지다&lt;/li&gt;
&lt;li data-end=&quot;15327&quot; data-start=&quot;15302&quot; data-section-id=&quot;s64rc3&quot;&gt;Container는 이미지를 실행한 상태다&lt;/li&gt;
&lt;li data-end=&quot;15355&quot; data-start=&quot;15328&quot; data-section-id=&quot;rl6es6&quot;&gt;Dockerfile은 이미지를 만드는 설계서다&lt;/li&gt;
&lt;li data-end=&quot;15391&quot; data-start=&quot;15356&quot; data-section-id=&quot;pg8sdo&quot;&gt;Compose는 여러 컨테이너를 관리하는 실행 설정 파일이다&lt;/li&gt;
&lt;li data-end=&quot;15416&quot; data-start=&quot;15392&quot; data-section-id=&quot;ouc1cd&quot;&gt;이미지는 불변이며 여러 레이어로 구성된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;15475&quot; data-start=&quot;15418&quot; data-ke-size=&quot;size16&quot;&gt;결국 Docker의 가장 큰 장점은&lt;br /&gt;환경 차이를 줄이고, 실행과 배포를 단순하게 만든다는 점입니다.&lt;/p&gt;
&lt;hr data-end=&quot;15480&quot; data-start=&quot;15477&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;15492&quot; data-start=&quot;15482&quot; data-section-id=&quot;13voyuf&quot; data-ke-size=&quot;size26&quot;&gt;  다음 글&lt;/h2&gt;
&lt;p data-end=&quot;15524&quot; data-start=&quot;15494&quot; data-ke-size=&quot;size16&quot;&gt;이 글에서는 Docker의 개념과 구조를 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;15615&quot; data-start=&quot;15526&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;15615&quot; data-start=&quot;15526&quot; data-ke-size=&quot;size16&quot;&gt;다음 글에서는&lt;br /&gt;실제 프로젝트(self-interior-guide)에 Docker를 적용한 과정을 통해&lt;br /&gt;이 개념들이 어떻게 활용되는지 살펴보겠습니다.&lt;/p&gt;</description>
      <category>Dev Tools</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/13</guid>
      <comments>https://dlsxo.tistory.com/13#entry13comment</comments>
      <pubDate>Mon, 13 Apr 2026 13:56:30 +0900</pubDate>
    </item>
    <item>
      <title>사이드 프로젝트 소개 | 셀프 인테리어 가이드</title>
      <link>https://dlsxo.tistory.com/12</link>
      <description>&lt;p data-end=&quot;75&quot; data-start=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. &lt;br /&gt;이번&amp;nbsp;글에서는&amp;nbsp;제가&amp;nbsp;진행한&amp;nbsp;사이드&amp;nbsp;프로젝트인 &lt;br /&gt;&lt;b&gt;self-interior-guide&lt;/b&gt;를&amp;nbsp;소개해보려고&amp;nbsp;합니다.&lt;/p&gt;
&lt;p data-end=&quot;75&quot; data-start=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;138&quot; data-start=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는&lt;br /&gt;셀프 인테리어를 처음 시작하는 사용자를 위한&lt;br /&gt;&lt;b&gt;&amp;ldquo;가이드 + 견적&amp;rdquo; 웹 서비스&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;223&quot; data-start=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;단순히 인테리어 정보를 나열하는 것이 아니라,&lt;br /&gt;실제로 사용자가 참고하면서 진행할 수 있도록&lt;br /&gt;&lt;b&gt;체크리스트형 UX&lt;/b&gt;로 설계한 것이 핵심입니다.&lt;/p&gt;
&lt;hr data-end=&quot;228&quot; data-start=&quot;225&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;268&quot; data-start=&quot;230&quot; 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;1280&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkLi8a/dJMcacCENkl/OmaTKR8XhWNFSZslSlHhr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkLi8a/dJMcacCENkl/OmaTKR8XhWNFSZslSlHhr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkLi8a/dJMcacCENkl/OmaTKR8XhWNFSZslSlHhr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkLi8a%2FdJMcacCENkl%2FOmaTKR8XhWNFSZslSlHhr1%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;1280&quot; height=&quot;842&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;268&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;323&quot; data-start=&quot;270&quot; data-ke-size=&quot;size16&quot;&gt;  서비스 바로가기&lt;br /&gt;&lt;a href=&quot;https://self-interior-guide.vercel.app/&quot;&gt;https://self-interior-guide.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;p data-end=&quot;384&quot; data-start=&quot;325&quot; data-ke-size=&quot;size16&quot;&gt;  GitHub&lt;br /&gt;&lt;a href=&quot;https://github.com/Ryuintae/self-interior-guide&quot;&gt;https://github.com/Ryuintae/self-interior-guide&lt;/a&gt;&lt;/p&gt;
&lt;hr data-end=&quot;389&quot; data-start=&quot;386&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;412&quot; data-start=&quot;391&quot; data-section-id=&quot;9w5emf&quot; data-ke-size=&quot;size26&quot;&gt;1. 왜 이 프로젝트를 만들었는가&lt;/h2&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;414&quot; data-ke-size=&quot;size16&quot;&gt;셀프 인테리어를 처음 시작하면 대부분 이런 문제를 겪습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;512&quot; data-start=&quot;449&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;468&quot; data-start=&quot;449&quot; data-section-id=&quot;m3t4s3&quot;&gt;무엇부터 해야 할지 모르겠음&lt;/li&gt;
&lt;li data-end=&quot;488&quot; data-start=&quot;469&quot; data-section-id=&quot;1re2sci&quot;&gt;순서를 몰라 시행착오가 많음&lt;/li&gt;
&lt;li data-end=&quot;512&quot; data-start=&quot;489&quot; data-section-id=&quot;swsk2r&quot;&gt;정보가 많지만 오히려 더 혼란스러움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;581&quot; data-start=&quot;514&quot; data-ke-size=&quot;size16&quot;&gt;기존 콘텐츠는 대부분 &amp;ldquo;정보 제공&amp;rdquo;에 집중되어 있고,&lt;br /&gt;실제로 따라가면서 사용할 수 있는 구조는 부족하다고 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;602&quot; data-start=&quot;583&quot; data-ke-size=&quot;size16&quot;&gt;그래서 단순한 정보 전달이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;646&quot; data-start=&quot;604&quot; data-ke-size=&quot;size16&quot;&gt;  &amp;nbsp;**&amp;ldquo;실제로 참고하면서 진행할 수 있는 구조&amp;rdquo;**를 만들고자 했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;651&quot; data-start=&quot;648&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;668&quot; data-start=&quot;653&quot; data-section-id=&quot;1mhl51l&quot; data-ke-size=&quot;size26&quot;&gt;2. 기존 방식의 한계&lt;/h2&gt;
&lt;p data-end=&quot;709&quot; data-start=&quot;670&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 인테리어 가이드는 대부분 다음과 같은 구조를 가지고 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;725&quot; data-start=&quot;711&quot; data-section-id=&quot;abbqwv&quot; data-ke-size=&quot;size23&quot;&gt;❌ 단계형 튜토리얼&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;798&quot; data-start=&quot;727&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;750&quot; data-start=&quot;727&quot; data-section-id=&quot;1l9mnrr&quot;&gt;1 &amp;rarr; 2 &amp;rarr; 3 &amp;rarr; 4 순서 강제&lt;/li&gt;
&lt;li data-end=&quot;773&quot; data-start=&quot;751&quot; data-section-id=&quot;ix04iw&quot;&gt;모든 단계를 완료해야 한다는 부담&lt;/li&gt;
&lt;li data-end=&quot;798&quot; data-start=&quot;774&quot; data-section-id=&quot;5wafep&quot;&gt;필요한 정보만 선택적으로 보기 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;832&quot; data-start=&quot;800&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제 사용자는 모든 단계를 그대로 따르지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;885&quot; data-start=&quot;834&quot; data-ke-size=&quot;size16&quot;&gt;상황에 따라 필요한 부분만 참고하고&lt;br /&gt;순서도 유동적으로 바뀌는 경우가 많습니다.&lt;/p&gt;
&lt;hr data-end=&quot;890&quot; data-start=&quot;887&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;914&quot; data-start=&quot;892&quot; data-section-id=&quot;1mc5vk2&quot; data-ke-size=&quot;size26&quot;&gt;3. 해결 방식: 체크리스트형 UX&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;859&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ey9ZYc/dJMcacCEObm/P6tPJRxKBydJ58a9QKJRK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ey9ZYc/dJMcacCEObm/P6tPJRxKBydJ58a9QKJRK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ey9ZYc/dJMcacCEObm/P6tPJRxKBydJ58a9QKJRK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fey9ZYc%2FdJMcacCEObm%2FP6tPJRxKBydJ58a9QKJRK1%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;907&quot; height=&quot;859&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;859&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;934&quot; data-start=&quot;916&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 핵심은 하나입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;956&quot; data-start=&quot;936&quot; data-section-id=&quot;105ssgm&quot; data-ke-size=&quot;size23&quot;&gt;✅ &amp;ldquo;완료&amp;rdquo;가 아니라 &amp;ldquo;확인&amp;rdquo;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;984&quot; data-start=&quot;958&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;969&quot; data-start=&quot;958&quot; data-section-id=&quot;fxetz4&quot;&gt;단계 완료 ❌&lt;/li&gt;
&lt;li data-end=&quot;984&quot; data-start=&quot;970&quot; data-section-id=&quot;19m89rk&quot;&gt;체크 기반 확인 ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;988&quot; data-start=&quot;986&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1035&quot; data-start=&quot;990&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1012&quot; data-start=&quot;990&quot; data-section-id=&quot;37dyty&quot;&gt;&amp;ldquo;다음 단계로 진행하세요&amp;rdquo; &amp;rarr; ❌&lt;/li&gt;
&lt;li data-end=&quot;1035&quot; data-start=&quot;1013&quot; data-section-id=&quot;7uhcrc&quot;&gt;&amp;ldquo;이 항목은 확인했나요?&amp;rdquo; &amp;rarr; ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1058&quot; data-start=&quot;1037&quot; data-ke-size=&quot;size16&quot;&gt;이 기준으로 UX 전체를 설계했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1058&quot; data-start=&quot;1037&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;1063&quot; data-start=&quot;1060&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1079&quot; data-start=&quot;1065&quot; data-section-id=&quot;rsjax7&quot; data-ke-size=&quot;size26&quot;&gt;4. UX 설계 핵심&lt;/h2&gt;
&lt;p data-end=&quot;1124&quot; data-start=&quot;1081&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트에서 가장 중요하게 본 것은&lt;br /&gt;사용자의 부담을 줄이는 구조입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1129&quot; data-start=&quot;1126&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1145&quot; data-start=&quot;1131&quot; data-section-id=&quot;7xwnpo&quot; data-ke-size=&quot;size23&quot;&gt;4.1 진행률 제거&lt;/h3&gt;
&lt;p data-end=&quot;1186&quot; data-start=&quot;1147&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로 많이 사용하는 진행률(%), 단계 완료 개념을 제거했습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1228&quot; data-start=&quot;1188&quot; data-ke-style=&quot;style3&quot;&gt;진행률은 사용자에게 &amp;ldquo;끝까지 해야 한다&amp;rdquo;는 압박을 주기 때문입니다.&lt;/blockquote&gt;
&lt;hr data-end=&quot;1233&quot; data-start=&quot;1230&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1254&quot; data-start=&quot;1235&quot; data-section-id=&quot;mmecmj&quot; data-ke-size=&quot;size23&quot;&gt;4.2 체크 UI 위치 변경&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;887&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chFyGa/dJMcafF8Yfk/hlqrukRTHwPv31MCWOJTu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chFyGa/dJMcafF8Yfk/hlqrukRTHwPv31MCWOJTu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chFyGa/dJMcafF8Yfk/hlqrukRTHwPv31MCWOJTu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchFyGa%2FdJMcafF8Yfk%2FhlqrukRTHwPv31MCWOJTu0%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;1029&quot; height=&quot;887&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;887&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;1023&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFYT7t/dJMcaax4xrN/Jpfsze7NSOe2UawdnFtesk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFYT7t/dJMcaax4xrN/Jpfsze7NSOe2UawdnFtesk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFYT7t/dJMcaax4xrN/Jpfsze7NSOe2UawdnFtesk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFYT7t%2FdJMcaax4xrN%2FJpfsze7NSOe2UawdnFtesk%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;1023&quot; height=&quot;881&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1298&quot; data-start=&quot;1256&quot; data-ke-size=&quot;size16&quot;&gt;초기에는 체크 UI를 상단에 배치했지만,&lt;br /&gt;현재는 하단으로 이동시켰습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1340&quot; data-start=&quot;1300&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1321&quot; data-start=&quot;1300&quot; data-section-id=&quot;1ox4d5t&quot;&gt;상단: 바로 행동 유도 &amp;rarr; 부담&lt;/li&gt;
&lt;li data-end=&quot;1340&quot; data-start=&quot;1322&quot; data-section-id=&quot;50bftk&quot;&gt;하단: 내용 확인 &amp;rarr; 체크&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1372&quot; data-start=&quot;1342&quot; data-ke-size=&quot;size16&quot;&gt;  &amp;nbsp;&amp;ldquo;읽기 &amp;rarr; 이해 &amp;rarr; 체크&amp;rdquo; 흐름으로 변경했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1377&quot; data-start=&quot;1374&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1401&quot; data-start=&quot;1379&quot; data-section-id=&quot;1bbz4t0&quot; data-ke-size=&quot;size23&quot;&gt;4.3 ResultPage 재정의&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEa6L8/dJMcagE4mKl/jRoKtfnsEYfGkpwJcZShQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEa6L8/dJMcagE4mKl/jRoKtfnsEYfGkpwJcZShQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEa6L8/dJMcagE4mKl/jRoKtfnsEYfGkpwJcZShQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEa6L8%2FdJMcagE4mKl%2FjRoKtfnsEYfGkpwJcZShQk%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;1018&quot; height=&quot;796&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1429&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size16&quot;&gt;보통 ResultPage는 &amp;ldquo;완료 화면&amp;rdquo;입니다.&lt;/p&gt;
&lt;p data-end=&quot;1444&quot; data-start=&quot;1431&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이 프로젝트에서는&lt;/p&gt;
&lt;p data-end=&quot;1483&quot; data-start=&quot;1446&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;   전체 체크리스트를 다시 확인하는 화면&lt;/b&gt;으로 설계했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1530&quot; data-start=&quot;1485&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1498&quot; data-start=&quot;1485&quot; data-section-id=&quot;1kt78vd&quot;&gt;내가 확인한 항목&lt;/li&gt;
&lt;li data-end=&quot;1514&quot; data-start=&quot;1499&quot; data-section-id=&quot;z2vy7r&quot;&gt;아직 보지 않은 항목&lt;/li&gt;
&lt;li data-end=&quot;1530&quot; data-start=&quot;1515&quot; data-section-id=&quot;dp66gm&quot;&gt;다시 보고 싶은 항목&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1539&quot; data-start=&quot;1532&quot; data-ke-size=&quot;size16&quot;&gt;을 정리하고,&lt;/p&gt;
&lt;blockquote data-end=&quot;1571&quot; data-start=&quot;1541&quot; data-ke-style=&quot;style2&quot;&gt;자연스럽게 견적 페이지로 이동하도록 구성했습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;696&quot; data-start=&quot;663&quot; data-section-id=&quot;tewua9&quot; data-ke-size=&quot;size23&quot;&gt;4.4 EstimatePage UX (행동으로 연결)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAKldM/dJMcagrvk1a/YlWqemAnDRqTqu96282TY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAKldM/dJMcagrvk1a/YlWqemAnDRqTqu96282TY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAKldM/dJMcagrvk1a/YlWqemAnDRqTqu96282TY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAKldM%2FdJMcagrvk1a%2FYlWqemAnDRqTqu96282TY1%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;1029&quot; height=&quot;848&quot; data-origin-width=&quot;1029&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;767&quot; data-start=&quot;698&quot; data-ke-size=&quot;size16&quot;&gt;가이드에서 끝나는 것이 아니라,&lt;br /&gt;사용자가 실제로 다음 행동을 할 수 있도록&lt;br /&gt;&lt;b&gt;견적 페이지로 흐름을 연결했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;795&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;EstimatePage는 단순 입력폼이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;843&quot; data-start=&quot;797&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;선택한 옵션을 시각적으로 확인하면서 견적을 비교할 수 있는 구조&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;903&quot; data-start=&quot;845&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;857&quot; data-start=&quot;845&quot; data-section-id=&quot;e9xzhd&quot;&gt;공간 타입 선택&lt;/li&gt;
&lt;li data-end=&quot;879&quot; data-start=&quot;858&quot; data-section-id=&quot;i2ecil&quot;&gt;벽 / 바닥 / 가구 색상 변경&lt;/li&gt;
&lt;li data-end=&quot;903&quot; data-start=&quot;880&quot; data-section-id=&quot;2m617&quot;&gt;선택값에 따른 예상 견적 범위 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;916&quot; data-start=&quot;905&quot; data-ke-size=&quot;size16&quot;&gt;특히 중요한 포인트는&lt;/p&gt;
&lt;p data-end=&quot;944&quot; data-start=&quot;918&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;상태 변경 &amp;rarr; 3D 화면 즉시 반영&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;956&quot; data-start=&quot;946&quot; data-ke-size=&quot;size16&quot;&gt;이라는 흐름입니다.&lt;/p&gt;
&lt;p data-end=&quot;982&quot; data-start=&quot;958&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 단순히 값을 입력하는 것이 아니라,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1017&quot; data-start=&quot;984&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;993&quot; data-start=&quot;984&quot; data-section-id=&quot;1wh8ffw&quot;&gt;직접 보고&lt;/li&gt;
&lt;li data-end=&quot;1002&quot; data-start=&quot;994&quot; data-section-id=&quot;xrzc04&quot;&gt;비교하고&lt;/li&gt;
&lt;li data-end=&quot;1017&quot; data-start=&quot;1003&quot; data-section-id=&quot;hzicos&quot;&gt;선택할 수 있습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1021&quot; data-start=&quot;1019&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-end=&quot;1055&quot; data-start=&quot;1023&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;정보 확인 &amp;rarr; 상태 정리 &amp;rarr; 실제 행동(견적)&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;1057&quot; data-ke-size=&quot;size16&quot;&gt;으로 이어지는 UX 흐름을 만들고자 했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1576&quot; data-start=&quot;1573&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1590&quot; data-start=&quot;1578&quot; data-section-id=&quot;1kxjg6m&quot; data-ke-size=&quot;size26&quot;&gt;5. 페이지 구조&lt;/h2&gt;
&lt;p data-end=&quot;1608&quot; data-start=&quot;1592&quot; data-ke-size=&quot;size16&quot;&gt;전체 흐름은 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372683062&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Home
&amp;rarr; GuideStart
&amp;rarr; GuideStep
&amp;rarr; GuideResult
&amp;rarr; Estimate&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1701&quot; data-start=&quot;1681&quot; data-ke-size=&quot;size16&quot;&gt;각 페이지의 역할은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1870&quot; data-start=&quot;1703&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1732&quot; data-start=&quot;1703&quot; data-section-id=&quot;1yafvws&quot;&gt;&lt;b&gt;HomePage&lt;/b&gt;: 서비스 소개 및 진입&lt;/li&gt;
&lt;li data-end=&quot;1766&quot; data-start=&quot;1733&quot; data-section-id=&quot;bwa33r&quot;&gt;&lt;b&gt;GuideStartPage&lt;/b&gt;: 사용자 조건 선택&lt;/li&gt;
&lt;li data-end=&quot;1799&quot; data-start=&quot;1767&quot; data-section-id=&quot;peuzm9&quot;&gt;&lt;b&gt;GuideStepPage&lt;/b&gt;: 가이드 내용 확인&lt;/li&gt;
&lt;li data-end=&quot;1836&quot; data-start=&quot;1800&quot; data-section-id=&quot;1mlqwri&quot;&gt;&lt;b&gt;GuideResultPage&lt;/b&gt;: 전체 체크 상태 정리&lt;/li&gt;
&lt;li data-end=&quot;1870&quot; data-start=&quot;1837&quot; data-section-id=&quot;kli4so&quot;&gt;&lt;b&gt;EstimatePage&lt;/b&gt;: 3D 기반 견적 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1881&quot; data-start=&quot;1872&quot; data-ke-size=&quot;size16&quot;&gt;이 구조의 핵심은&lt;/p&gt;
&lt;blockquote data-end=&quot;1917&quot; data-start=&quot;1883&quot; data-ke-style=&quot;style2&quot;&gt;&amp;nbsp;강제 흐름이 아니라 자유 탐색 구조라는 점입니다.&lt;/blockquote&gt;
&lt;hr data-end=&quot;1922&quot; data-start=&quot;1919&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;203&quot; data-start=&quot;190&quot; data-section-id=&quot;zks4m4&quot; data-ke-size=&quot;size26&quot;&gt;6. 프로젝트 구조&lt;/h2&gt;
&lt;p data-end=&quot;270&quot; data-start=&quot;205&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 단순히 페이지를 나열하는 구조가 아니라,&lt;br /&gt;&lt;b&gt;역할과 도메인 기준으로 분리된 구조&lt;/b&gt;로 설계했습니다.&lt;/p&gt;
&lt;p data-end=&quot;294&quot; data-start=&quot;272&quot; data-ke-size=&quot;size16&quot;&gt;실제 src 구조는 다음과 같습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775372697693&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src
├─ index.css
├─ main.tsx
├─ vite-env.d.ts
│
├─ app
│ ├─ RootLayout.tsx
│ └─ router.tsx
│
├─ assets
│ ├─ hero.png
│ ├─ react.svg
│ └─ vite.svg
│
├─ features
│ ├─ configurator
│ │ ├─ components
│ │ │ ├─ RoomCanvas.tsx
│ │ │ └─ RoomScene.tsx
│ │ └─ store
│ │ └─ useConfiguratorStore.ts
│ │
│ ├─ estimate
│ │ ├─ data
│ │ │ └─ estimateData.ts
│ │ └─ types
│ │ └─ estimate.ts
│ │
│ └─ guide
│ ├─ data
│ │ ├─ guideData.ts
│ │ └─ guideRecommendations.ts
│ ├─ store
│ │ └─ useGuideStore.ts
│ └─ types
│ └─ guide.ts
│
├─ pages
│ ├─ HomePage.tsx
│ ├─ GuideStartPage.tsx
│ ├─ GuideStepPage.tsx
│ ├─ GuideResultPage.tsx
│ └─ EstimatePage.tsx
│
└─ shared
└─ ui
├─ PageShell.tsx
├─ ProgressBar.tsx
├─ ScrollToTop.tsx
└─ SectionCard.tsx&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1139&quot; data-start=&quot;1136&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1156&quot; data-start=&quot;1141&quot; data-section-id=&quot;ipl35s&quot; data-ke-size=&quot;size26&quot;&gt;6.1 구조 설계 기준&lt;/h2&gt;
&lt;p data-end=&quot;1183&quot; data-start=&quot;1158&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트 구조는 다음 기준으로 나눴습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1287&quot; data-start=&quot;1185&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1214&quot; data-start=&quot;1185&quot; data-section-id=&quot;12jhz95&quot;&gt;app &amp;rarr; 앱 전체 구조 (라우팅, 레이아웃)&lt;/li&gt;
&lt;li data-end=&quot;1239&quot; data-start=&quot;1215&quot; data-section-id=&quot;xpur9f&quot;&gt;features &amp;rarr; 기능/도메인 단위&lt;/li&gt;
&lt;li data-end=&quot;1260&quot; data-start=&quot;1240&quot; data-section-id=&quot;1tah8mm&quot;&gt;pages &amp;rarr; 실제 화면 단위&lt;/li&gt;
&lt;li data-end=&quot;1287&quot; data-start=&quot;1261&quot; data-section-id=&quot;hbwjv4&quot;&gt;shared/ui &amp;rarr; 공통 UI 컴포넌트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1291&quot; data-start=&quot;1289&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-end=&quot;1330&quot; data-start=&quot;1293&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;화면&amp;rdquo;이 아니라 &amp;ldquo;역할&amp;rdquo; 기준으로 분리한 구조&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1335&quot; data-start=&quot;1332&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1356&quot; data-start=&quot;1337&quot; data-section-id=&quot;1bdl3zs&quot; data-ke-size=&quot;size26&quot;&gt;6.2 app: 앱 진입 구조&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1411&quot; data-start=&quot;1358&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1383&quot; data-start=&quot;1358&quot; data-section-id=&quot;joibi4&quot;&gt;router.tsx: 전체 라우팅 정의&lt;/li&gt;
&lt;li data-end=&quot;1411&quot; data-start=&quot;1384&quot; data-section-id=&quot;wprmdg&quot;&gt;RootLayout.tsx: 공통 레이아웃&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1432&quot; data-start=&quot;1413&quot; data-ke-size=&quot;size16&quot;&gt;이 영역은 앱의 흐름을 담당합니다.&lt;/p&gt;
&lt;p data-end=&quot;1441&quot; data-start=&quot;1434&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1458&quot; data-start=&quot;1443&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1448&quot; data-start=&quot;1443&quot; data-section-id=&quot;230ebk&quot;&gt;가이드&lt;/li&gt;
&lt;li data-end=&quot;1453&quot; data-start=&quot;1449&quot; data-section-id=&quot;yi3ug4&quot;&gt;결과&lt;/li&gt;
&lt;li data-end=&quot;1458&quot; data-start=&quot;1454&quot; data-section-id=&quot;yi3ptx&quot;&gt;견적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1480&quot; data-start=&quot;1460&quot; data-ke-size=&quot;size16&quot;&gt;처럼 페이지 간 이동이 많기 때문에,&lt;/p&gt;
&lt;p data-end=&quot;1518&quot; data-start=&quot;1482&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;라우팅 구조 자체가 UX 흐름과 연결되는 구조&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1523&quot; data-start=&quot;1520&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1551&quot; data-start=&quot;1525&quot; data-section-id=&quot;19okska&quot; data-ke-size=&quot;size26&quot;&gt;6.3 features: 도메인 중심 구조&lt;/h2&gt;
&lt;p data-end=&quot;1579&quot; data-start=&quot;1553&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트에서 가장 중요한 설계 포인트입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1602&quot; data-start=&quot;1581&quot; data-section-id=&quot;1w9neo6&quot; data-ke-size=&quot;size23&quot;&gt;왜 features로 나눴는가?&lt;/h3&gt;
&lt;p data-end=&quot;1656&quot; data-start=&quot;1604&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 pages 중심으로도 구현할 수 있지만,&lt;br /&gt;기능이 커질수록 아래 문제가 발생합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1696&quot; data-start=&quot;1658&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1670&quot; data-start=&quot;1658&quot; data-section-id=&quot;117cveb&quot;&gt;상태와 UI가 섞임&lt;/li&gt;
&lt;li data-end=&quot;1685&quot; data-start=&quot;1671&quot; data-section-id=&quot;1hbtmjw&quot;&gt;데이터와 로직이 뒤엉킴&lt;/li&gt;
&lt;li data-end=&quot;1696&quot; data-start=&quot;1686&quot; data-section-id=&quot;1p6nnis&quot;&gt;유지보수 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1717&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다음 기준으로 분리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1738&quot; data-start=&quot;1719&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;기능 단위로 묶는다&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1743&quot; data-start=&quot;1740&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1769&quot; data-start=&quot;1745&quot; data-section-id=&quot;1sqiy7s&quot; data-ke-size=&quot;size23&quot;&gt;6.3.1 guide (핵심 도메인)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372725637&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;guide
├─ data
├─ store
└─ types&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1832&quot; data-start=&quot;1815&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 핵심 기능입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1946&quot; data-start=&quot;1834&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1860&quot; data-start=&quot;1834&quot; data-section-id=&quot;10z0gzd&quot;&gt;guideData.ts &amp;rarr; 가이드 콘텐츠&lt;/li&gt;
&lt;li data-end=&quot;1896&quot; data-start=&quot;1861&quot; data-section-id=&quot;p7rgti&quot;&gt;guideRecommendations.ts &amp;rarr; 추천 로직&lt;/li&gt;
&lt;li data-end=&quot;1925&quot; data-start=&quot;1897&quot; data-section-id=&quot;13ey5dw&quot;&gt;useGuideStore.ts &amp;rarr; 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;1946&quot; data-start=&quot;1926&quot; data-section-id=&quot;1b7uo1t&quot;&gt;guide.ts &amp;rarr; 타입 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1977&quot; data-start=&quot;1948&quot; data-ke-size=&quot;size16&quot;&gt;UI / 상태 / 데이터 / 타입을 분리한 구조&lt;/p&gt;
&lt;p data-end=&quot;1987&quot; data-start=&quot;1979&quot; data-ke-size=&quot;size16&quot;&gt;이 구조 덕분에&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2013&quot; data-start=&quot;1989&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1997&quot; data-start=&quot;1989&quot; data-section-id=&quot;yf7ycx&quot;&gt;데이터 수정&lt;/li&gt;
&lt;li data-end=&quot;2005&quot; data-start=&quot;1998&quot; data-section-id=&quot;m50b1k&quot;&gt;상태 변경&lt;/li&gt;
&lt;li data-end=&quot;2013&quot; data-start=&quot;2006&quot; data-section-id=&quot;17cuvbd&quot;&gt;UI 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2040&quot; data-start=&quot;2015&quot; data-ke-size=&quot;size16&quot;&gt;이 서로 영향을 덜 받도록 만들 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2045&quot; data-start=&quot;2042&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2076&quot; data-start=&quot;2047&quot; data-section-id=&quot;1kxcwk3&quot; data-ke-size=&quot;size23&quot;&gt;6.3.2 estimate (견적 계산 영역)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372740531&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;estimate
├─ data
└─ types&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2121&quot; data-start=&quot;2116&quot; data-ke-size=&quot;size16&quot;&gt;이 영역은&lt;/p&gt;
&lt;p data-end=&quot;2146&quot; data-start=&quot;2123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;견적 계산 기준을 담당합니다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2176&quot; data-start=&quot;2148&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2156&quot; data-start=&quot;2148&quot; data-section-id=&quot;o5210o&quot;&gt;옵션별 가격&lt;/li&gt;
&lt;li data-end=&quot;2165&quot; data-start=&quot;2157&quot; data-section-id=&quot;1c1h5rk&quot;&gt;공간별 비용&lt;/li&gt;
&lt;li data-end=&quot;2176&quot; data-start=&quot;2166&quot; data-section-id=&quot;1s7kccx&quot;&gt;계산 로직 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2226&quot; data-start=&quot;2178&quot; data-ke-size=&quot;size16&quot;&gt;UI와 분리했기 때문에&lt;br /&gt;나중에 계산 방식이 바뀌어도 영향 범위를 줄일 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2231&quot; data-start=&quot;2228&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2263&quot; data-start=&quot;2233&quot; data-section-id=&quot;egjxin&quot; data-ke-size=&quot;size23&quot;&gt;6.3.3 configurator (3D 영역)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775372752763&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;configurator
├─ components
└─ store&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2318&quot; data-start=&quot;2313&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2318&quot; data-start=&quot;2313&quot; data-ke-size=&quot;size16&quot;&gt;이 영역은&lt;/p&gt;
&lt;p data-end=&quot;2352&quot; data-start=&quot;2320&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3D 시각화 + 사용자 인터랙션&lt;/b&gt;을 담당합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2435&quot; data-start=&quot;2354&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2377&quot; data-start=&quot;2354&quot; data-section-id=&quot;nlu54&quot;&gt;RoomCanvas &amp;rarr; 렌더링 영역&lt;/li&gt;
&lt;li data-end=&quot;2402&quot; data-start=&quot;2378&quot; data-section-id=&quot;12ettbj&quot;&gt;RoomScene &amp;rarr; 실제 공간 구성&lt;/li&gt;
&lt;li data-end=&quot;2435&quot; data-start=&quot;2403&quot; data-section-id=&quot;135u68i&quot;&gt;useConfiguratorStore &amp;rarr; 상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2439&quot; data-start=&quot;2437&quot; data-ke-size=&quot;size16&quot;&gt;특히&lt;/p&gt;
&lt;p data-end=&quot;2465&quot; data-start=&quot;2441&quot; data-ke-size=&quot;size16&quot;&gt;Canvas와 Scene을 분리한 구조&lt;/p&gt;
&lt;p data-end=&quot;2480&quot; data-start=&quot;2467&quot; data-ke-size=&quot;size16&quot;&gt;는 중요한 포인트입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2517&quot; data-start=&quot;2482&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2499&quot; data-start=&quot;2482&quot; data-section-id=&quot;k5qvxq&quot;&gt;Canvas &amp;rarr; 렌더링 환경&lt;/li&gt;
&lt;li data-end=&quot;2517&quot; data-start=&quot;2500&quot; data-section-id=&quot;1fswjjo&quot;&gt;Scene &amp;rarr; 오브젝트 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2522&quot; data-start=&quot;2519&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2547&quot; data-start=&quot;2524&quot; data-section-id=&quot;ot5xbe&quot; data-ke-size=&quot;size26&quot;&gt;6.4 pages: 사용자 화면 단위&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372763491&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pages
├─ HomePage
├─ GuideStartPage
├─ GuideStepPage
├─ GuideResultPage
└─ EstimatePage&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2669&quot; data-start=&quot;2649&quot; data-ke-size=&quot;size16&quot;&gt;이 폴더는 단순 화면 모음이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;2698&quot; data-start=&quot;2671&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용자 흐름을 구성하는 레이어&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2760&quot; data-start=&quot;2700&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2711&quot; data-start=&quot;2700&quot; data-section-id=&quot;1welr84&quot;&gt;Home &amp;rarr; 진입&lt;/li&gt;
&lt;li data-end=&quot;2727&quot; data-start=&quot;2712&quot; data-section-id=&quot;o0dt08&quot;&gt;Guide &amp;rarr; 정보 탐색&lt;/li&gt;
&lt;li data-end=&quot;2744&quot; data-start=&quot;2728&quot; data-section-id=&quot;bmngqr&quot;&gt;Result &amp;rarr; 상태 확인&lt;/li&gt;
&lt;li data-end=&quot;2760&quot; data-start=&quot;2745&quot; data-section-id=&quot;1im4ccc&quot;&gt;Estimate &amp;rarr; 행동&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2764&quot; data-start=&quot;2762&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;2783&quot; data-start=&quot;2766&quot; data-ke-style=&quot;style2&quot;&gt;페이지 = UX 흐름 단위&lt;/blockquote&gt;
&lt;hr data-end=&quot;2788&quot; data-start=&quot;2785&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2813&quot; data-start=&quot;2790&quot; data-section-id=&quot;19xswc4&quot; data-ke-size=&quot;size26&quot;&gt;6.5 shared/ui: 공통 UI&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372774327&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;shared/ui
├─ PageShell
├─ SectionCard
├─ ScrollToTop
└─ ProgressBar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2915&quot; data-start=&quot;2895&quot; data-ke-size=&quot;size16&quot;&gt;이 영역은 UI 일관성을 담당합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2926&quot; data-start=&quot;2917&quot; data-section-id=&quot;h68ko3&quot; data-ke-size=&quot;size23&quot;&gt;주요 역할&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3026&quot; data-start=&quot;2928&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2951&quot; data-start=&quot;2928&quot; data-section-id=&quot;5kvle6&quot;&gt;PageShell &amp;rarr; 페이지 구조 통일&lt;/li&gt;
&lt;li data-end=&quot;2976&quot; data-start=&quot;2952&quot; data-section-id=&quot;d5rgu2&quot;&gt;SectionCard &amp;rarr; 카드 UI 통일&lt;/li&gt;
&lt;li data-end=&quot;2998&quot; data-start=&quot;2977&quot; data-section-id=&quot;c8qf1y&quot;&gt;ScrollToTop &amp;rarr; UX 개선&lt;/li&gt;
&lt;li data-end=&quot;3026&quot; data-start=&quot;2999&quot; data-section-id=&quot;hds96y&quot;&gt;ProgressBar &amp;rarr; 초기 UX 실험 흔적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3043&quot; data-start=&quot;3028&quot; data-ke-size=&quot;size16&quot;&gt;특히 SectionCard는&lt;/p&gt;
&lt;p data-end=&quot;3084&quot; data-start=&quot;3045&quot; data-ke-size=&quot;size16&quot;&gt;가이드, 옵션, 설명을 같은 톤으로 묶어주는 핵심 컴포넌트입니다.&lt;/p&gt;
&lt;hr data-end=&quot;3089&quot; data-start=&quot;3086&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3114&quot; data-start=&quot;3091&quot; data-section-id=&quot;1vwa28y&quot; data-ke-size=&quot;size26&quot;&gt;6.6 구조 설계에서 중요했던 포인트&lt;/h2&gt;
&lt;p data-end=&quot;3139&quot; data-start=&quot;3116&quot; data-ke-size=&quot;size16&quot;&gt;이 구조에서 중요하게 본 것은 다음입니다.&lt;/p&gt;
&lt;h3 data-end=&quot;3153&quot; data-start=&quot;3141&quot; data-section-id=&quot;pzuj17&quot; data-ke-size=&quot;size23&quot;&gt;1) 역할 분리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3178&quot; data-start=&quot;3155&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3178&quot; data-start=&quot;3155&quot; data-section-id=&quot;12xqf5r&quot;&gt;UI / 상태 / 데이터 / 타입 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3183&quot; data-start=&quot;3180&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3201&quot; data-start=&quot;3185&quot; data-section-id=&quot;17ij9mw&quot; data-ke-size=&quot;size23&quot;&gt;2) 도메인 중심 설계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3236&quot; data-start=&quot;3203&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3236&quot; data-start=&quot;3203&quot; data-section-id=&quot;1p5fjz5&quot;&gt;guide / estimate / configurator&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3241&quot; data-start=&quot;3238&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3253&quot; data-start=&quot;3243&quot; data-section-id=&quot;76xagt&quot; data-ke-size=&quot;size23&quot;&gt;3) 확장성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3286&quot; data-start=&quot;3255&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3269&quot; data-start=&quot;3255&quot; data-section-id=&quot;el7eow&quot;&gt;API 연동 가능 구조&lt;/li&gt;
&lt;li data-end=&quot;3286&quot; data-start=&quot;3270&quot; data-section-id=&quot;1crq8fp&quot;&gt;기능 추가 시 영향 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3291&quot; data-start=&quot;3288&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3302&quot; data-start=&quot;3293&quot; data-section-id=&quot;zo5as3&quot; data-ke-size=&quot;size26&quot;&gt;6.7 정리&lt;/h2&gt;
&lt;p data-end=&quot;325&quot; data-start=&quot;284&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트 구조는 단순한 파일 분리가 아니라,&lt;/p&gt;
&lt;p data-end=&quot;395&quot; data-start=&quot;327&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가이드 UX, 상태 관리, 3D 견적 기능을 명확히 분리하여&lt;br /&gt;확장성과 유지보수를 고려한 구조로 설계한 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;408&quot; data-start=&quot;397&quot; data-ke-size=&quot;size16&quot;&gt;결국 느낀 점은,&lt;/p&gt;
&lt;p data-end=&quot;471&quot; data-start=&quot;410&quot; data-ke-size=&quot;size16&quot;&gt;작은 프로젝트라도 구조를 어떻게 잡느냐에 따라&lt;br /&gt;이후의 확장성과 유지보수 난이도가 크게 달라진다는 것입니다.&lt;/p&gt;
&lt;hr data-end=&quot;3237&quot; data-start=&quot;3234&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;136&quot; data-start=&quot;118&quot; data-section-id=&quot;1ess4v4&quot; data-ke-size=&quot;size26&quot;&gt;7. 기술 스택과 선택 이유&lt;/h2&gt;
&lt;p data-end=&quot;220&quot; data-start=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 단순 UI 구현이 아니라&lt;br /&gt;UX 흐름, 상태 관리, 3D 인터랙션까지 포함되어 있기 때문에&lt;br /&gt;각 역할에 맞게 기술을 선택했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;225&quot; data-start=&quot;222&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;253&quot; data-start=&quot;227&quot; data-section-id=&quot;znjy8j&quot; data-ke-size=&quot;size23&quot;&gt;7.1 React + TypeScript&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;275&quot; data-start=&quot;255&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;262&quot; data-start=&quot;255&quot; data-section-id=&quot;179haax&quot;&gt;React&lt;/li&gt;
&lt;li data-end=&quot;275&quot; data-start=&quot;263&quot; data-section-id=&quot;3kl673&quot;&gt;TypeScript&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;314&quot; data-start=&quot;277&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 페이지 흐름이 많고, 상태 변화도 다양한 구조입니다.&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;316&quot; data-ke-size=&quot;size16&quot;&gt;단순 정적인 페이지가 아니라&lt;br /&gt;&lt;u&gt;가이드 &amp;rarr; 체크 상태 &amp;rarr; 견적 &amp;rarr; 3D 반영까지&lt;/u&gt; 이어지는 구조이기 때문에&lt;/p&gt;
&lt;p data-end=&quot;416&quot; data-start=&quot;381&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트 기반 구조와 상태 흐름 관리가 중요한 프로젝트였습니다.&lt;/p&gt;
&lt;p data-end=&quot;442&quot; data-start=&quot;418&quot; data-ke-size=&quot;size16&quot;&gt;React를 선택한 이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;491&quot; data-start=&quot;444&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;466&quot; data-start=&quot;444&quot; data-section-id=&quot;1b46y6h&quot;&gt;컴포넌트 단위로 UI를 분리하기 용이&lt;/li&gt;
&lt;li data-end=&quot;481&quot; data-start=&quot;467&quot; data-section-id=&quot;1pq52k8&quot;&gt;상태 기반 렌더링 구조&lt;/li&gt;
&lt;li data-end=&quot;491&quot; data-start=&quot;482&quot; data-section-id=&quot;1a44d0g&quot;&gt;생태계가 풍부&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;512&quot; data-start=&quot;493&quot; data-ke-size=&quot;size16&quot;&gt;TypeScript를 사용한 이유는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;557&quot; data-start=&quot;514&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;529&quot; data-start=&quot;514&quot; data-section-id=&quot;hcplw&quot;&gt;가이드 데이터 구조 관리&lt;/li&gt;
&lt;li data-end=&quot;544&quot; data-start=&quot;530&quot; data-section-id=&quot;1tstj38&quot;&gt;상태 구조 안정성 확보&lt;/li&gt;
&lt;li data-end=&quot;557&quot; data-start=&quot;545&quot; data-section-id=&quot;1ffo775&quot;&gt;확장 시 오류 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;639&quot; data-start=&quot;559&quot; data-ke-size=&quot;size16&quot;&gt;특히 이 프로젝트는&lt;br /&gt;guideData, estimateData, 상태 구조 등이 명확해야 하기 때문에&lt;br /&gt;타입 안정성이 중요했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;644&quot; data-start=&quot;641&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;658&quot; data-start=&quot;646&quot; data-section-id=&quot;crqtmr&quot; data-ke-size=&quot;size23&quot;&gt;7.2 Vite&lt;/h3&gt;
&lt;p data-end=&quot;692&quot; data-start=&quot;660&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 Vite를 사용해 개발 환경을 구성했습니다.&lt;/p&gt;
&lt;p data-end=&quot;704&quot; data-start=&quot;694&quot; data-ke-size=&quot;size16&quot;&gt;이유는 단순합니다.&lt;/p&gt;
&lt;p data-end=&quot;729&quot; data-start=&quot;706&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발 속도와 DX(개발 경험)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;770&quot; data-start=&quot;731&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;749&quot; data-start=&quot;731&quot; data-section-id=&quot;1sjdpsf&quot;&gt;빠른 dev server 실행&lt;/li&gt;
&lt;li data-end=&quot;760&quot; data-start=&quot;750&quot; data-section-id=&quot;1h68u8e&quot;&gt;즉각적인 HMR&lt;/li&gt;
&lt;li data-end=&quot;770&quot; data-start=&quot;761&quot; data-section-id=&quot;snhmb5&quot;&gt;설정이 단순함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;841&quot; data-start=&quot;772&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 UI를 계속 수정하고 실험하는 과정이 많기 때문에&lt;br /&gt;빌드 속도보다 &lt;b&gt;개발 반복 속도&lt;/b&gt;가 더 중요했습니다.&lt;/p&gt;
&lt;p data-end=&quot;851&quot; data-start=&quot;843&quot; data-ke-size=&quot;size16&quot;&gt;또한 Vite는&lt;/p&gt;
&lt;p data-end=&quot;895&quot; data-start=&quot;853&quot; data-ke-size=&quot;size16&quot;&gt;▶ 개발 환경에서는 ESM 기반&lt;br /&gt;▶ &amp;nbsp;빌드 시에는 Rollup 사용&lt;/p&gt;
&lt;p data-end=&quot;944&quot; data-start=&quot;897&quot; data-ke-size=&quot;size16&quot;&gt;이라는 구조이기 때문에&lt;br /&gt;최근 프론트엔드 환경에도 잘 맞는 선택이라고 판단했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;949&quot; data-start=&quot;946&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;974&quot; data-start=&quot;951&quot; data-section-id=&quot;rn61vj&quot; data-ke-size=&quot;size23&quot;&gt;7.3 Zustand (상태 관리)&lt;/h3&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;976&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트에서는 Redux 대신 Zustand를 사용했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1026&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1074&quot; data-start=&quot;1028&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1041&quot; data-start=&quot;1028&quot; data-section-id=&quot;7u4u4p&quot;&gt;보일러플레이트가 적음&lt;/li&gt;
&lt;li data-end=&quot;1054&quot; data-start=&quot;1042&quot; data-section-id=&quot;nt3kdd&quot;&gt;직관적인 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;1074&quot; data-start=&quot;1055&quot; data-section-id=&quot;1q9h7e6&quot;&gt;작은 프로젝트에서도 과하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1103&quot; data-start=&quot;1076&quot; data-ke-size=&quot;size16&quot;&gt;특히 이 프로젝트의 핵심 상태는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1148&quot; data-start=&quot;1105&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1115&quot; data-start=&quot;1105&quot; data-section-id=&quot;16ws57z&quot;&gt;가이드 선택 값&lt;/li&gt;
&lt;li data-end=&quot;1123&quot; data-start=&quot;1116&quot; data-section-id=&quot;rt6qjx&quot;&gt;체크 상태&lt;/li&gt;
&lt;li data-end=&quot;1137&quot; data-start=&quot;1124&quot; data-section-id=&quot;187ehlh&quot;&gt;시나리오별 상태 분리&lt;/li&gt;
&lt;li data-end=&quot;1148&quot; data-start=&quot;1138&quot; data-section-id=&quot;2xz6hh&quot;&gt;견적 옵션 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1201&quot; data-start=&quot;1150&quot; data-ke-size=&quot;size16&quot;&gt;이 구조는 전역 상태가 필요하지만,&lt;br /&gt;Redux처럼 복잡한 구조까지는 필요하지 않았습니다.&lt;/p&gt;
&lt;p data-end=&quot;1206&quot; data-start=&quot;1203&quot; data-ke-size=&quot;size16&quot;&gt;그래서&lt;/p&gt;
&lt;p data-end=&quot;1235&quot; data-start=&quot;1208&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ▶ 가볍지만 확장 가능한 상태 관리 도구&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1255&quot; data-start=&quot;1237&quot; data-ke-size=&quot;size16&quot;&gt;로 Zustand를 선택했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1260&quot; data-start=&quot;1257&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1282&quot; data-start=&quot;1262&quot; data-section-id=&quot;6maxs1&quot; data-ke-size=&quot;size23&quot;&gt;7.4 React Router&lt;/h3&gt;
&lt;p data-end=&quot;1310&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 사용자 흐름이 중요한 구조입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1353&quot; data-start=&quot;1312&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1353&quot; data-start=&quot;1312&quot; data-section-id=&quot;1cw6dn4&quot;&gt;Home &amp;rarr; Guide &amp;rarr; Step &amp;rarr; Result &amp;rarr; Estimate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1401&quot; data-start=&quot;1355&quot; data-ke-size=&quot;size16&quot;&gt;단순 페이지 이동이 아니라&lt;br /&gt;UX 흐름 자체가 중요한 프로젝트이기 때문에&lt;/p&gt;
&lt;p data-end=&quot;1421&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size16&quot;&gt;라우팅 구조가 명확해야 했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1444&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size16&quot;&gt;React Router를 사용한 이유는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1499&quot; data-start=&quot;1446&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1456&quot; data-start=&quot;1446&quot; data-section-id=&quot;1aehygw&quot;&gt;선언적인 라우팅&lt;/li&gt;
&lt;li data-end=&quot;1486&quot; data-start=&quot;1457&quot; data-section-id=&quot;40yibm&quot;&gt;동적 라우트 지원 (/step/:stepId)&lt;/li&gt;
&lt;li data-end=&quot;1499&quot; data-start=&quot;1487&quot; data-section-id=&quot;1s9vnhq&quot;&gt;SPA 구조에 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1504&quot; data-start=&quot;1501&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1526&quot; data-start=&quot;1506&quot; data-section-id=&quot;1lrosvh&quot; data-ke-size=&quot;size23&quot;&gt;7.5 Tailwind CSS&lt;/h3&gt;
&lt;p data-end=&quot;1555&quot; data-start=&quot;1528&quot; data-ke-size=&quot;size16&quot;&gt;스타일링은 Tailwind CSS를 사용했습니다.&lt;/p&gt;
&lt;p data-end=&quot;1570&quot; data-start=&quot;1557&quot; data-ke-size=&quot;size16&quot;&gt;이유는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1611&quot; data-start=&quot;1572&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1582&quot; data-start=&quot;1572&quot; data-section-id=&quot;1gbqxr8&quot;&gt;빠른 UI 구현&lt;/li&gt;
&lt;li data-end=&quot;1599&quot; data-start=&quot;1583&quot; data-section-id=&quot;163w0gg&quot;&gt;일관된 디자인 시스템 유지&lt;/li&gt;
&lt;li data-end=&quot;1611&quot; data-start=&quot;1600&quot; data-section-id=&quot;2x4vd8&quot;&gt;커스터마이징 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1667&quot; data-start=&quot;1613&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 카드 UI, 체크리스트 UI, 옵션 UI 등&lt;br /&gt;비슷한 패턴이 반복되는 구조입니다.&lt;/p&gt;
&lt;p data-end=&quot;1683&quot; data-start=&quot;1669&quot; data-ke-size=&quot;size16&quot;&gt;Tailwind를 사용하면&lt;/p&gt;
&lt;p data-end=&quot;1738&quot; data-start=&quot;1685&quot; data-ke-size=&quot;size16&quot;&gt;✅ &amp;nbsp;클래스 기반으로 빠르게 UI를 조합할 수 있고&lt;br /&gt;✅ &amp;nbsp;디자인 일관성을 유지하기 쉽습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1743&quot; data-start=&quot;1740&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1781&quot; data-start=&quot;1745&quot; data-section-id=&quot;179uib2&quot; data-ke-size=&quot;size23&quot;&gt;7.6 Three.js + React Three Fiber&lt;/h3&gt;
&lt;p data-end=&quot;1828&quot; data-start=&quot;1783&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트에서 가장 특징적인 부분은&lt;br /&gt;&lt;b&gt;3D 기반 견적 UI&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;1847&quot; data-start=&quot;1830&quot; data-ke-size=&quot;size16&quot;&gt;이를 위해 다음을 사용했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1899&quot; data-start=&quot;1849&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1859&quot; data-start=&quot;1849&quot; data-section-id=&quot;mkx69d&quot;&gt;Three.js&lt;/li&gt;
&lt;li data-end=&quot;1879&quot; data-start=&quot;1860&quot; data-section-id=&quot;13e2hgd&quot;&gt;React Three Fiber&lt;/li&gt;
&lt;li data-end=&quot;1899&quot; data-start=&quot;1880&quot; data-section-id=&quot;13vxe5b&quot;&gt;@react-three/drei&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1904&quot; data-start=&quot;1901&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1922&quot; data-start=&quot;1906&quot; data-ke-size=&quot;size20&quot;&gt;왜 3D를 사용했는가&lt;/h4&gt;
&lt;p data-end=&quot;1939&quot; data-start=&quot;1924&quot; data-ke-size=&quot;size16&quot;&gt;단순 견적 입력폼이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;1979&quot; data-start=&quot;1941&quot; data-ke-size=&quot;size16&quot;&gt;사용자가 공간을 &amp;ldquo;보면서&amp;rdquo; 선택할 수 있도록 하기 위해서입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2012&quot; data-start=&quot;1981&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1990&quot; data-start=&quot;1981&quot; data-section-id=&quot;e3eqio&quot;&gt;벽 색상 변경&lt;/li&gt;
&lt;li data-end=&quot;2001&quot; data-start=&quot;1991&quot; data-section-id=&quot;ykj11o&quot;&gt;바닥 색상 변경&lt;/li&gt;
&lt;li data-end=&quot;2012&quot; data-start=&quot;2002&quot; data-section-id=&quot;1tqeuoh&quot;&gt;가구 색상 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2062&quot; data-start=&quot;2014&quot; data-ke-size=&quot;size16&quot;&gt;이러한 선택을 숫자가 아니라&lt;br /&gt;&lt;b&gt;시각적으로 확인할 수 있도록&lt;/b&gt; 설계했습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2067&quot; data-start=&quot;2064&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;2099&quot; data-start=&quot;2069&quot; data-ke-size=&quot;size20&quot;&gt;React Three Fiber를 선택한 이유&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2164&quot; data-start=&quot;2101&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2122&quot; data-start=&quot;2101&quot; data-section-id=&quot;1mpmjyq&quot;&gt;React 방식으로 3D 구성 가능&lt;/li&gt;
&lt;li data-end=&quot;2141&quot; data-start=&quot;2123&quot; data-section-id=&quot;1f8bi0b&quot;&gt;상태와 3D를 자연스럽게 연결&lt;/li&gt;
&lt;li data-end=&quot;2164&quot; data-start=&quot;2142&quot; data-section-id=&quot;1vdp51u&quot;&gt;컴포넌트 단위로 Scene 구성 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2172&quot; data-start=&quot;2166&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2205&quot; data-start=&quot;2174&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2189&quot; data-start=&quot;2174&quot; data-section-id=&quot;p7lvp0&quot;&gt;상태 변경 &amp;rarr; 3D 반영&lt;/li&gt;
&lt;li data-end=&quot;2205&quot; data-start=&quot;2190&quot; data-section-id=&quot;1vdnicp&quot;&gt;선택 값 &amp;rarr; 즉시 시각화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2230&quot; data-start=&quot;2207&quot; data-ke-size=&quot;size16&quot;&gt;이 흐름을 자연스럽게 구현할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2235&quot; data-start=&quot;2232&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2246&quot; data-start=&quot;2237&quot; data-section-id=&quot;xsfoj6&quot; data-ke-size=&quot;size26&quot;&gt;7.7 정리&lt;/h2&gt;
&lt;p data-end=&quot;2285&quot; data-start=&quot;2248&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트의 기술 스택은 단순히 최신 기술을 사용한 것이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;2306&quot; data-start=&quot;2287&quot; data-ke-size=&quot;size16&quot;&gt;각 역할에 맞게 선택했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2398&quot; data-start=&quot;2308&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2323&quot; data-start=&quot;2308&quot; data-section-id=&quot;1cfe2t7&quot;&gt;React &amp;rarr; UI 구조&lt;/li&gt;
&lt;li data-end=&quot;2341&quot; data-start=&quot;2324&quot; data-section-id=&quot;78qlxk&quot;&gt;Zustand &amp;rarr; 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;2356&quot; data-start=&quot;2342&quot; data-section-id=&quot;1ggy71t&quot;&gt;Vite &amp;rarr; 개발 경험&lt;/li&gt;
&lt;li data-end=&quot;2376&quot; data-start=&quot;2357&quot; data-section-id=&quot;1x5cxwe&quot;&gt;Tailwind &amp;rarr; UI 생산성&lt;/li&gt;
&lt;li data-end=&quot;2398&quot; data-start=&quot;2377&quot; data-section-id=&quot;1508vg6&quot;&gt;Three.js &amp;rarr; 시각적 인터랙션&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2411&quot; data-start=&quot;2400&quot; data-ke-size=&quot;size16&quot;&gt;결과적으로 이 조합은&lt;/p&gt;
&lt;p data-end=&quot;2446&quot; data-start=&quot;2413&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UX 중심 프로젝트를 빠르게 구현하기 위한 구조&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2460&quot; data-start=&quot;2448&quot; data-ke-size=&quot;size16&quot;&gt;라고 볼 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3786&quot; data-start=&quot;3783&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3807&quot; data-start=&quot;3788&quot; data-section-id=&quot;5z7vn2&quot; data-ke-size=&quot;size26&quot;&gt;8. 구현에서 중요했던 포인트&lt;/h2&gt;
&lt;h3 data-end=&quot;3830&quot; data-start=&quot;3809&quot; data-section-id=&quot;1jf3i7k&quot; data-ke-size=&quot;size23&quot;&gt;8.1 시나리오 기반 상태 분리&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372984677&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const scenarioKey = `${spaceType}-${scope}`;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;3891&quot; data-start=&quot;3888&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3909&quot; data-start=&quot;3893&quot; data-section-id=&quot;1halwuz&quot; data-ke-size=&quot;size23&quot;&gt;8.2 체크 상태 구조&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775372990673&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;stepStatusByScenario[scenarioKey][stepId]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;3967&quot; data-start=&quot;3964&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3988&quot; data-start=&quot;3969&quot; data-section-id=&quot;bwg104&quot; data-ke-size=&quot;size23&quot;&gt;8.3 가이드 &amp;rarr; 견적 연결&lt;/h3&gt;
&lt;blockquote data-end=&quot;4026&quot; data-start=&quot;3990&quot; data-ke-style=&quot;style3&quot;&gt;&amp;nbsp;&amp;ldquo;읽고 끝&amp;rdquo;이 아니라&lt;br /&gt;행동으로 이어지는 구조&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;4144&quot; data-start=&quot;4141&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;111&quot; data-start=&quot;100&quot; data-section-id=&quot;1vq6dff&quot; data-ke-size=&quot;size26&quot;&gt;10. 정리하며&lt;/h2&gt;
&lt;p data-end=&quot;183&quot; data-start=&quot;113&quot; data-ke-size=&quot;size16&quot;&gt;복잡한 정보를 최대한 쉽게 전달하려고 했지만,&lt;br /&gt;사용자 입장에서는 여전히 어렵게 느껴지는 부분이 있을 수 있다고 생각합니다.&lt;/p&gt;
&lt;p data-end=&quot;260&quot; data-start=&quot;185&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트를 통해&lt;br /&gt;기능을 구현하는 것보다&lt;br /&gt;&lt;u&gt;&lt;b&gt;사용자가 어떻게 이해하고 받아들이는지가 더 중요하다는 것&lt;/b&gt;&lt;/u&gt;을 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;262&quot; data-ke-size=&quot;size16&quot;&gt;앞으로는 화면 설계와 기획을 통해&lt;br /&gt;사용자가 더 자연스럽게 이해하고 사용할 수 있도록 개선해 나가고자 합니다.&lt;/p&gt;
&lt;hr data-end=&quot;329&quot; data-start=&quot;326&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;268&quot; data-start=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 복잡한 인테리어 과정을&lt;br /&gt;체크리스트 UX로 단순화하고&lt;br /&gt;3D 견적까지 연결한 서비스입니다.&lt;/p&gt;
&lt;p data-end=&quot;330&quot; data-start=&quot;270&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 기술보다&lt;br /&gt;&lt;b&gt;사용자의 부담을 줄이는 구조&lt;/b&gt;였으며,&lt;br /&gt;이 방향으로 계속 개선해 나갈 예정입니다.&lt;/p&gt;
&lt;p data-end=&quot;330&quot; data-start=&quot;270&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;528&quot; data-start=&quot;516&quot; data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>프로젝트 회고록</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/12</guid>
      <comments>https://dlsxo.tistory.com/12#entry12comment</comments>
      <pubDate>Mon, 6 Apr 2026 12:52:48 +0900</pubDate>
    </item>
    <item>
      <title>Webpack vs Vite: 구조적 차이 정리</title>
      <link>https://dlsxo.tistory.com/11</link>
      <description>&lt;p data-end=&quot;281&quot; data-start=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;br /&gt;이전 글에서는 번들러가 내부에서 어떻게 동작하는지, 그리고 의존성 그래프를 생성하고 트리쉐이킹과 코드 스플리팅을 수행하는 과정을 정리했습니다.&lt;/p&gt;
&lt;p data-end=&quot;320&quot; data-start=&quot;283&quot; data-ke-size=&quot;size16&quot;&gt;이러한 번들링 과정은 실제 번들러마다 구현 방식에 차이가 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 대표적인 번들러인 &lt;b&gt;Webpack&lt;/b&gt;과 &lt;b&gt;Vite&lt;/b&gt;의 구조적 차이를 살펴보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;448&quot; data-start=&quot;381&quot; data-ke-size=&quot;size16&quot;&gt;단순히 &amp;ldquo;Vite가 더 빠르다&amp;rdquo;는 수준이 아니라,&lt;br /&gt;&lt;b&gt;왜 그런 차이가 발생하는지&lt;/b&gt;를 구조 중심으로 정리해보겠습니다.&lt;/p&gt;
&lt;hr data-end=&quot;453&quot; data-start=&quot;450&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;483&quot; data-start=&quot;455&quot; data-section-id=&quot;a6yyqh&quot; data-ke-size=&quot;size26&quot;&gt;1. 왜 Webpack과 Vite를 비교하는가&lt;/h2&gt;
&lt;p data-end=&quot;567&quot; data-start=&quot;485&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 오랜 기간 프론트엔드 빌드 도구의 표준으로 사용되어 왔고,&lt;br /&gt;Vite는 빠른 개발 환경을 기반으로 최근 빠르게 확산되고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;616&quot; data-start=&quot;569&quot; data-ke-size=&quot;size16&quot;&gt;두 도구는 같은 번들링 영역의 도구이지만,&lt;br /&gt;&lt;b&gt;근본적인 동작 방식이 다릅니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;621&quot; data-start=&quot;618&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;640&quot; data-start=&quot;623&quot; data-section-id=&quot;t2ecqc&quot; data-ke-size=&quot;size26&quot;&gt;2. Webpack의 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0ekVS/dJMcabDIWBq/XRJITK09yDANv4LId6Nk6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0ekVS/dJMcabDIWBq/XRJITK09yDANv4LId6Nk6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0ekVS/dJMcabDIWBq/XRJITK09yDANv4LId6Nk6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0ekVS%2FdJMcabDIWBq%2FXRJITK09yDANv4LId6Nk6k%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;800&quot; height=&quot;413&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;658&quot; data-start=&quot;642&quot; data-section-id=&quot;e4ix7j&quot; data-ke-size=&quot;size23&quot;&gt;2.1 기본 동작 방식&lt;/h3&gt;
&lt;p data-end=&quot;723&quot; data-start=&quot;660&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 프로젝트의 모든 모듈을 분석해&lt;br /&gt;&lt;b&gt;하나의 의존성 그래프를 만든 뒤 번들 파일을 생성&lt;/b&gt;합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775199647120&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;entry
&amp;darr;
dependency graph 생성
&amp;darr;
전체 번들 생성
&amp;darr;
dev server 제공&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;826&quot; data-start=&quot;796&quot; data-ke-size=&quot;size16&quot;&gt;핵심: &lt;b&gt;개발 환경에서도 전체 번들링을 수행&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;831&quot; data-start=&quot;828&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;843&quot; data-start=&quot;833&quot; data-section-id=&quot;50lsqs&quot; data-ke-size=&quot;size23&quot;&gt;2.2 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;891&quot; data-start=&quot;845&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;859&quot; data-start=&quot;845&quot; data-section-id=&quot;1xwafc9&quot;&gt;모든 모듈을 미리 분석&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;860&quot; data-section-id=&quot;1r7okd3&quot;&gt;하나의 번들로 묶어서 제공&lt;/li&gt;
&lt;li data-end=&quot;891&quot; data-start=&quot;877&quot; data-section-id=&quot;1e7azlt&quot;&gt;강력한 플러그인 생태계&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;896&quot; data-start=&quot;893&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;908&quot; data-start=&quot;898&quot; data-section-id=&quot;5157ip&quot; data-ke-size=&quot;size23&quot;&gt;2.3 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;967&quot; data-start=&quot;910&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;929&quot; data-start=&quot;910&quot; data-section-id=&quot;84htrg&quot;&gt;초기 실행 속도가 느릴 수 있음&lt;/li&gt;
&lt;li data-end=&quot;951&quot; data-start=&quot;930&quot; data-section-id=&quot;1mpwbhl&quot;&gt;프로젝트가 커질수록 빌드 시간 증가&lt;/li&gt;
&lt;li data-end=&quot;967&quot; data-start=&quot;952&quot; data-section-id=&quot;s7auih&quot;&gt;설정이 복잡해질 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;972&quot; data-start=&quot;969&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;988&quot; data-start=&quot;974&quot; data-section-id=&quot;13zwgxe&quot; data-ke-size=&quot;size26&quot;&gt;3. Vite의 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JqUzo/dJMcabcCyCi/DwWhN1hfOn1YWkqi5KO7v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JqUzo/dJMcabcCyCi/DwWhN1hfOn1YWkqi5KO7v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JqUzo/dJMcabcCyCi/DwWhN1hfOn1YWkqi5KO7v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJqUzo%2FdJMcabcCyCi%2FDwWhN1hfOn1YWkqi5KO7v1%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;1280&quot; height=&quot;800&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;1003&quot; data-start=&quot;990&quot; data-section-id=&quot;wpukju&quot; data-ke-size=&quot;size23&quot;&gt;3.1 핵심 철학&lt;/h3&gt;
&lt;blockquote data-end=&quot;1027&quot; data-start=&quot;1005&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1027&quot; data-start=&quot;1007&quot; data-ke-size=&quot;size16&quot;&gt;개발 환경에서는 번들링을 하지 않는다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1032&quot; data-start=&quot;1029&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1056&quot; data-start=&quot;1034&quot; data-section-id=&quot;lub5pj&quot; data-ke-size=&quot;size23&quot;&gt;3.2 동작 방식 (ESM 기반)&lt;/h3&gt;
&lt;p data-end=&quot;1094&quot; data-start=&quot;1058&quot; data-ke-size=&quot;size16&quot;&gt;Vite는 브라우저의 ES Module 기능을 그대로 활용합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775199662561&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;브라우저 &amp;rarr; main.js 요청
&amp;rarr; import 따라 개별 요청
&amp;rarr; 필요한 파일만 변환&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1196&quot; data-start=&quot;1172&quot; data-ke-size=&quot;size16&quot;&gt;핵심: &lt;b&gt;필요한 모듈만 즉시 처리&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1201&quot; data-start=&quot;1198&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1216&quot; data-start=&quot;1203&quot; data-section-id=&quot;1xnk9xc&quot; data-ke-size=&quot;size23&quot;&gt;3.3 내부 구조&lt;/h3&gt;
&lt;p data-end=&quot;1243&quot; data-start=&quot;1218&quot; data-ke-size=&quot;size16&quot;&gt;Vite는 개발과 빌드를 분리해서 처리합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1287&quot; data-start=&quot;1245&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1266&quot; data-start=&quot;1245&quot; data-section-id=&quot;1almesf&quot;&gt;개발 환경 &amp;rarr; &lt;b&gt;esbuild&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1287&quot; data-start=&quot;1267&quot; data-section-id=&quot;1sk53tj&quot;&gt;빌드 환경 &amp;rarr; &lt;b&gt;Rollup&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1296&quot; data-start=&quot;1289&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;정리하면&lt;/p&gt;
&lt;blockquote data-end=&quot;1355&quot; data-start=&quot;1298&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1355&quot; data-start=&quot;1300&quot; data-ke-size=&quot;size16&quot;&gt;Vite는 개발 서버 + 빌드 도구이며,&lt;br /&gt;빌드 시 Rollup을 사용해 번들링을 수행합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1360&quot; data-start=&quot;1357&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1393&quot; data-start=&quot;1362&quot; data-section-id=&quot;i8bb6z&quot; data-ke-size=&quot;size26&quot;&gt;4. Rollup이란 무엇인가 (Vite와의 관계)&lt;/h2&gt;
&lt;h3 data-end=&quot;1412&quot; data-start=&quot;1395&quot; data-section-id=&quot;1h4qyzi&quot; data-ke-size=&quot;size23&quot;&gt;4.1 Rollup이란?&lt;/h3&gt;
&lt;p data-end=&quot;1456&quot; data-start=&quot;1414&quot; data-ke-size=&quot;size16&quot;&gt;Rollup은 &lt;b&gt;ES Module 기반 번들링에 최적화된 번들러&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1503&quot; data-start=&quot;1458&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1469&quot; data-start=&quot;1458&quot; data-section-id=&quot;1e449cc&quot;&gt;트리쉐이킹에 강함&lt;/li&gt;
&lt;li data-end=&quot;1487&quot; data-start=&quot;1470&quot; data-section-id=&quot;2j898x&quot;&gt;불필요한 코드 제거에 최적화&lt;/li&gt;
&lt;li data-end=&quot;1503&quot; data-start=&quot;1488&quot; data-section-id=&quot;ja5ylw&quot;&gt;라이브러리 번들링에 강점&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1508&quot; data-start=&quot;1505&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1528&quot; data-start=&quot;1510&quot; data-section-id=&quot;7wfrnd&quot; data-ke-size=&quot;size23&quot;&gt;4.2 Vite에서의 역할&lt;/h3&gt;
&lt;p data-end=&quot;1584&quot; data-start=&quot;1530&quot; data-ke-size=&quot;size16&quot;&gt;Vite는 개발 환경에서는 번들링을 하지 않지만,&lt;br /&gt;배포 시점에서는 반드시 번들링이 필요합니다.&lt;/p&gt;
&lt;p data-end=&quot;1612&quot; data-start=&quot;1586&quot; data-ke-size=&quot;size16&quot;&gt;이때 &lt;b&gt;Rollup이 번들링을 담당&lt;/b&gt;합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775199674630&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;개발 &amp;rarr; ESM + esbuild
빌드 &amp;rarr; Rollup&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1661&quot; data-start=&quot;1658&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1680&quot; data-start=&quot;1663&quot; data-section-id=&quot;elqjh0&quot; data-ke-size=&quot;size26&quot;&gt;5. 왜 Vite가 빠른가&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgHCzz/dJMcaiiwW0B/8NGyu4sHOZA9RJulanuZj0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgHCzz/dJMcaiiwW0B/8NGyu4sHOZA9RJulanuZj0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgHCzz/dJMcaiiwW0B/8NGyu4sHOZA9RJulanuZj0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgHCzz%2FdJMcaiiwW0B%2F8NGyu4sHOZA9RJulanuZj0%2Fimg.webp&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;800&quot; height=&quot;600&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;1699&quot; data-start=&quot;1682&quot; data-section-id=&quot;7jsto1&quot; data-ke-size=&quot;size23&quot;&gt;5.1 번들링 시점 차이&lt;/h3&gt;
&lt;p data-end=&quot;1708&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;Webpack&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775199685491&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;전체 번들 생성 &amp;rarr; 서버 시작&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1744&quot; data-start=&quot;1740&quot; data-ke-size=&quot;size16&quot;&gt;Vite&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1775199690260&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;서버 시작 &amp;rarr; 요청된 모듈만 처리&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1795&quot; data-start=&quot;1778&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;초기 실행 속도 차이 발생&lt;/p&gt;
&lt;hr data-end=&quot;1800&quot; data-start=&quot;1797&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1838&quot; data-start=&quot;1802&quot; data-section-id=&quot;9gfgpa&quot; data-ke-size=&quot;size23&quot;&gt;5.2 HMR (Hot Module Replacement)&lt;/h3&gt;
&lt;h4 data-end=&quot;1851&quot; data-start=&quot;1840&quot; data-ke-size=&quot;size20&quot;&gt;HMR이란?&lt;/h4&gt;
&lt;p data-end=&quot;1900&quot; data-start=&quot;1853&quot; data-ke-size=&quot;size16&quot;&gt;HMR은 &lt;b&gt;페이지 전체를 새로고침하지 않고, 변경된 모듈만 교체하는 기능&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;1905&quot; data-start=&quot;1902&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1937&quot; data-start=&quot;1907&quot; data-section-id=&quot;1w3aux3&quot; data-ke-size=&quot;size23&quot;&gt;5.3 Webpack vs Vite HMR 차이&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDJHJr/dJMcaaEPGQh/oIGj6FKcTGuZLeKcRKQfRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDJHJr/dJMcaaEPGQh/oIGj6FKcTGuZLeKcRKQfRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDJHJr/dJMcaaEPGQh/oIGj6FKcTGuZLeKcRKQfRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDJHJr%2FdJMcaaEPGQh%2FoIGj6FKcTGuZLeKcRKQfRk%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;1136&quot; height=&quot;690&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1946&quot; data-start=&quot;1939&quot; data-ke-size=&quot;size16&quot;&gt;Webpack&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1990&quot; data-start=&quot;1948&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1975&quot; data-start=&quot;1948&quot; data-section-id=&quot;1i0xcy8&quot;&gt;변경된 모듈이 전체 그래프에 미치는 영향 분석&lt;/li&gt;
&lt;li data-end=&quot;1990&quot; data-start=&quot;1976&quot; data-section-id=&quot;1x19qs9&quot;&gt;리빌드 과정 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1996&quot; data-start=&quot;1992&quot; data-ke-size=&quot;size16&quot;&gt;Vite&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2027&quot; data-start=&quot;1998&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2013&quot; data-start=&quot;1998&quot; data-section-id=&quot;wsc0mc&quot;&gt;변경된 모듈만 다시 요청&lt;/li&gt;
&lt;li data-end=&quot;2027&quot; data-start=&quot;2014&quot; data-section-id=&quot;8z5z0&quot;&gt;브라우저가 직접 교체&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2034&quot; data-start=&quot;2029&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;결과&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2078&quot; data-start=&quot;2036&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2058&quot; data-start=&quot;2036&quot; data-section-id=&quot;1fbwein&quot;&gt;Webpack &amp;rarr; 상대적으로 느림&lt;/li&gt;
&lt;li data-end=&quot;2078&quot; data-start=&quot;2059&quot; data-section-id=&quot;l97fil&quot;&gt;Vite &amp;rarr; 거의 즉각 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2083&quot; data-start=&quot;2080&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2104&quot; data-start=&quot;2085&quot; data-section-id=&quot;1sdt9j0&quot; data-ke-size=&quot;size26&quot;&gt;6. 구조적 차이 한눈에 보기&lt;/h2&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-end=&quot;2278&quot; data-start=&quot;2106&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;2181&quot; data-start=&quot;2155&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2163&quot; data-start=&quot;2155&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;2171&quot; data-start=&quot;2163&quot; data-col-size=&quot;sm&quot;&gt;Webpack&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;2181&quot; data-start=&quot;2171&quot; data-col-size=&quot;sm&quot;&gt;Vite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;개발 방식&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;번들 기반&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;ESM 기반&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;2204&quot; data-start=&quot;2182&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2190&quot; data-start=&quot;2182&quot;&gt;초기 실행&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2195&quot; data-start=&quot;2190&quot;&gt;느림&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2204&quot; data-start=&quot;2195&quot;&gt;매우 빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;2231&quot; data-start=&quot;2205&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2211&quot; data-start=&quot;2205&quot;&gt;HMR&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2222&quot; data-start=&quot;2211&quot;&gt;상대적으로 느림&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2231&quot; data-start=&quot;2222&quot;&gt;매우 빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;2259&quot; data-start=&quot;2232&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2237&quot; data-start=&quot;2232&quot;&gt;빌드&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2246&quot; data-start=&quot;2237&quot;&gt;자체 번들링&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2259&quot; data-start=&quot;2246&quot;&gt;Rollup 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;2278&quot; data-start=&quot;2260&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2265&quot; data-start=&quot;2260&quot;&gt;구조&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2271&quot; data-start=&quot;2265&quot;&gt;통합형&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2278&quot; data-start=&quot;2271&quot;&gt;분리형&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2283&quot; data-start=&quot;2280&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2305&quot; data-start=&quot;2285&quot; data-section-id=&quot;1lxc8uu&quot; data-ke-size=&quot;size26&quot;&gt;7. 언제 무엇을 선택해야 할까&lt;/h2&gt;
&lt;h3 data-end=&quot;2326&quot; data-start=&quot;2307&quot; data-section-id=&quot;1s2w9s2&quot; data-ke-size=&quot;size23&quot;&gt;Webpack이 적합한 경우&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2369&quot; data-start=&quot;2328&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2338&quot; data-start=&quot;2328&quot; data-section-id=&quot;1p3rfld&quot;&gt;레거시 프로젝트&lt;/li&gt;
&lt;li data-end=&quot;2350&quot; data-start=&quot;2339&quot; data-section-id=&quot;13pxqip&quot;&gt;복잡한 설정 필요&lt;/li&gt;
&lt;li data-end=&quot;2369&quot; data-start=&quot;2351&quot; data-section-id=&quot;1n9wz8g&quot;&gt;기존 Webpack 환경 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2374&quot; data-start=&quot;2371&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2392&quot; data-start=&quot;2376&quot; data-section-id=&quot;s6yryp&quot; data-ke-size=&quot;size23&quot;&gt;Vite가 적합한 경우&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2431&quot; data-start=&quot;2394&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2403&quot; data-start=&quot;2394&quot; data-section-id=&quot;1fj9tm1&quot;&gt;신규 프로젝트&lt;/li&gt;
&lt;li data-end=&quot;2417&quot; data-start=&quot;2404&quot; data-section-id=&quot;1izzgat&quot;&gt;빠른 개발 환경 필요&lt;/li&gt;
&lt;li data-end=&quot;2431&quot; data-start=&quot;2418&quot; data-section-id=&quot;i4pcft&quot;&gt;최신 프론트엔드 스택&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2436&quot; data-start=&quot;2433&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2446&quot; data-start=&quot;2438&quot; data-section-id=&quot;zprawa&quot; data-ke-size=&quot;size26&quot;&gt;8. 정리&lt;/h2&gt;
&lt;p data-end=&quot;3073&quot; data-start=&quot;3038&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 Webpack과 Vite의 구조적 차이를 살펴봤습니다.&lt;/p&gt;
&lt;p data-end=&quot;3111&quot; data-start=&quot;3075&quot; data-ke-size=&quot;size16&quot;&gt;두 도구의 가장 큰 차이는 &lt;b&gt;번들링을 언제 수행하느냐&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;3213&quot; data-start=&quot;3113&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 개발 환경에서도 번들링을 수행하는 &lt;b&gt;번들 중심 구조&lt;/b&gt;이고,&lt;br /&gt;Vite는 개발 환경에서는 브라우저의 ES Module을 활용하는 &lt;b&gt;ESM 중심 구조&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;3265&quot; data-start=&quot;3215&quot; data-ke-size=&quot;size16&quot;&gt;이 구조적 차이가 개발 서버 속도, HMR 성능, 그리고 개발 경험에 큰 영향을 미칩니다.&lt;/p&gt;
&lt;p data-end=&quot;3295&quot; data-start=&quot;3267&quot; data-ke-size=&quot;size16&quot;&gt;결국 두 도구는 각각 다른 철학을 가지고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3351&quot; data-start=&quot;3297&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3321&quot; data-start=&quot;3297&quot; data-section-id=&quot;1g0gq1u&quot;&gt;Webpack &amp;rarr; 강력한 범용 번들러&lt;/li&gt;
&lt;li data-end=&quot;3351&quot; data-start=&quot;3322&quot; data-section-id=&quot;82ai5w&quot;&gt;Vite &amp;rarr; 빠른 개발 경험 중심의 빌드 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3392&quot; data-start=&quot;3353&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트의 특성과 환경에 따라 적절한 도구를 선택하는 것이 중요합니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3406&quot; data-start=&quot;3394&quot; data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>Frontend Basic (기초 이론)</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/11</guid>
      <comments>https://dlsxo.tistory.com/11#entry11comment</comments>
      <pubDate>Fri, 3 Apr 2026 16:11:02 +0900</pubDate>
    </item>
    <item>
      <title>번들러 동작 원리 이해하기</title>
      <link>https://dlsxo.tistory.com/10</link>
      <description>&lt;p data-end=&quot;105&quot; data-start=&quot;46&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;br /&gt;이번 글에서는 &lt;b&gt;번들러가 내부에서 어떻게 동작하는지&lt;/b&gt;를 구조적으로 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;252&quot; data-start=&quot;107&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 프로젝트를 진행하다 보면 Webpack, Vite, Rollup 같은 번들러를 자연스럽게 사용하게 됩니다. 하지만 대부분은 &amp;ldquo;빌드 도구&amp;rdquo; 정도로만 이해하고 실제로 &lt;b&gt;번들러가 내부에서 어떤 과정을 거치는지&lt;/b&gt;는 깊이 생각해보지 않는 경우가 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;312&quot; data-start=&quot;254&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 단순히 여러 파일을 하나로 합치는 도구가 아닙니다.&lt;br /&gt;실제로는 다음과 같은 작업을 수행합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;477&quot; data-start=&quot;314&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;368&quot; data-start=&quot;314&quot; data-section-id=&quot;1a6ql2j&quot;&gt;모듈 간 의존성을 분석해 &lt;b&gt;의존성 그래프(Dependency Graph)&lt;/b&gt; 를 생성하고&lt;/li&gt;
&lt;li data-end=&quot;420&quot; data-start=&quot;369&quot; data-section-id=&quot;gi0qgt&quot;&gt;사용하지 않는 코드를 제거하는 &lt;b&gt;트리쉐이킹(Tree Shaking)&lt;/b&gt; 을 수행하며&lt;/li&gt;
&lt;li data-end=&quot;477&quot; data-start=&quot;421&quot; data-section-id=&quot;si5hnc&quot;&gt;필요한 코드만 로딩할 수 있도록 &lt;b&gt;코드 스플리팅(Code Splitting)&lt;/b&gt; 을 적용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;529&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 번들러가 이 과정을 &lt;b&gt;어떤 순서로 처리하는지&lt;/b&gt;를 중심으로 살펴보겠습니다.&lt;/p&gt;
&lt;hr data-end=&quot;534&quot; data-start=&quot;531&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;557&quot; data-start=&quot;536&quot; data-section-id=&quot;1itk2we&quot;&gt;1. 번들러는 무엇을 하는 도구일까&lt;/h1&gt;
&lt;p data-end=&quot;584&quot; data-start=&quot;559&quot; data-ke-size=&quot;size16&quot;&gt;먼저 번들러의 역할을 간단히 정리해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;647&quot; data-start=&quot;586&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 &lt;b&gt;여러 개의 모듈 파일을 분석하여 하나 또는 여러 개의 최적화된 결과물로 만들어주는 도구&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;681&quot; data-start=&quot;649&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 프로젝트 구조가 다음과 같다고 가정해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585892984&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src
├─ main.js
├─ utils.js
├─ api.js
└─ components
└─ Button.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;793&quot; data-start=&quot;766&quot; data-ke-size=&quot;size16&quot;&gt;각 파일은 서로 import로 연결되어 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;862&quot; data-start=&quot;795&quot; data-ke-size=&quot;size16&quot;&gt;브라우저는 기본적으로 &lt;b&gt;파일 단위로 네트워크 요청을 보내기 때문에&lt;/b&gt;, 모듈이 많아질수록 요청 횟수가 증가하게 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;882&quot; data-start=&quot;864&quot; data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하기 위해 번들러는&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;935&quot; data-start=&quot;884&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;900&quot; data-start=&quot;884&quot; data-section-id=&quot;1blb6hj&quot;&gt;모든 모듈을 분석하고&lt;/li&gt;
&lt;li data-end=&quot;916&quot; data-start=&quot;901&quot; data-section-id=&quot;ju205z&quot;&gt;하나의 구조로 묶고&lt;/li&gt;
&lt;li data-end=&quot;935&quot; data-start=&quot;917&quot; data-section-id=&quot;4u9jtq&quot;&gt;최적화된 파일을 생성합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;965&quot; data-start=&quot;937&quot; data-ke-size=&quot;size16&quot;&gt;이 과정의 핵심이 바로 &lt;b&gt;의존성 그래프&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr data-end=&quot;970&quot; data-start=&quot;967&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;990&quot; data-start=&quot;972&quot; data-section-id=&quot;1yxhk86&quot;&gt;2. 의존성 그래프 생성 과정&lt;/h1&gt;
&lt;h2 data-end=&quot;1017&quot; data-start=&quot;992&quot; data-section-id=&quot;1t5v0x8&quot; data-ke-size=&quot;size26&quot;&gt;2.1 번들링은 엔트리 파일에서 시작된다&lt;/h2&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;1019&quot; data-ke-size=&quot;size16&quot;&gt;번들링은 항상 &lt;b&gt;엔트리 파일(entry file)&lt;/b&gt; 에서 시작합니다.&lt;/p&gt;
&lt;p data-end=&quot;1091&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 코드가 있다고 가정해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585900556&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { add } from &quot;./utils.js&quot;;
import Button from &quot;./components/Button.js&quot;;

console.log(add(2, 3));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1239&quot; data-start=&quot;1216&quot; data-ke-size=&quot;size16&quot;&gt;이 파일이 바로 번들링의 시작점이 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1275&quot; data-start=&quot;1241&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 이 파일을 읽은 뒤 내부에서 다음 작업을 수행합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1324&quot; data-start=&quot;1277&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1291&quot; data-start=&quot;1277&quot; data-section-id=&quot;181a0mo&quot;&gt;import 문을 분석&lt;/li&gt;
&lt;li data-end=&quot;1309&quot; data-start=&quot;1292&quot; data-section-id=&quot;3ux679&quot;&gt;어떤 파일을 참조하는지 확인&lt;/li&gt;
&lt;li data-end=&quot;1324&quot; data-start=&quot;1310&quot; data-section-id=&quot;1nhwzgw&quot;&gt;해당 파일을 다시 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1329&quot; data-start=&quot;1326&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1359&quot; data-start=&quot;1331&quot; data-section-id=&quot;1l4u3xi&quot; data-ke-size=&quot;size26&quot;&gt;2.2 import를 따라가며 그래프를 만든다&lt;/h2&gt;
&lt;p data-end=&quot;1396&quot; data-start=&quot;1361&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 utils.js가 다음과 같다고 가정해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585907380&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export function add(a, b) {
return a + b;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1493&quot; data-start=&quot;1463&quot; data-ke-size=&quot;size16&quot;&gt;그리고 Button.js가 다음과 같다고 해봅시다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585915539&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { fetchData } from &quot;../api.js&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1582&quot; data-start=&quot;1553&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 되면 번들러는 다음과 같은 구조를 파악합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585921753&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;main.js
├─ utils.js
└─ Button.js
└─ api.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1687&quot; data-start=&quot;1644&quot; data-ke-size=&quot;size16&quot;&gt;이 구조가 바로 &lt;b&gt;의존성 그래프(Dependency Graph)&lt;/b&gt; 입니다.&lt;/p&gt;
&lt;p data-end=&quot;1727&quot; data-start=&quot;1689&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 이 그래프를 기반으로 전체 프로젝트 구조를 이해하게 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;1732&quot; data-start=&quot;1729&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1756&quot; data-start=&quot;1734&quot; data-section-id=&quot;4gpztk&quot;&gt;3. 코드 분석 단계 (AST 분석)&lt;/h1&gt;
&lt;p data-end=&quot;1783&quot; data-start=&quot;1758&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 코드를 단순 문자열로 읽지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;1831&quot; data-start=&quot;1785&quot; data-ke-size=&quot;size16&quot;&gt;코드를 &lt;b&gt;AST(Abstract Syntax Tree)&lt;/b&gt; 로 변환해 분석합니다.&lt;/p&gt;
&lt;p data-end=&quot;1859&quot; data-start=&quot;1833&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 코드가 있다고 가정해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585929993&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { add } from &quot;./utils.js&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1939&quot; data-start=&quot;1914&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 이를 다음과 같은 구조로 파악합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1773585935193&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ImportDeclaration
├─ specifier: add
└─ source: &quot;./utils.js&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2045&quot; data-start=&quot;2012&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 다음과 같은 정보들을 정확하게 알 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2104&quot; data-start=&quot;2047&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2066&quot; data-start=&quot;2047&quot; data-section-id=&quot;1c03ozx&quot;&gt;어떤 모듈을 import 하는지&lt;/li&gt;
&lt;li data-end=&quot;2085&quot; data-start=&quot;2067&quot; data-section-id=&quot;133i851&quot;&gt;어떤 export가 사용되는지&lt;/li&gt;
&lt;li data-end=&quot;2104&quot; data-start=&quot;2086&quot; data-section-id=&quot;zr0keg&quot;&gt;사용되지 않는 코드가 무엇인지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2134&quot; data-start=&quot;2106&quot; data-ke-size=&quot;size16&quot;&gt;이 분석이 바로 &lt;b&gt;트리쉐이킹의 기반&lt;/b&gt;이 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;2139&quot; data-start=&quot;2136&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2165&quot; data-start=&quot;2141&quot; data-section-id=&quot;8xpl0j&quot;&gt;4. 트리쉐이킹(Tree Shaking)&lt;/h1&gt;
&lt;h2 data-end=&quot;2186&quot; data-start=&quot;2167&quot; data-section-id=&quot;1r23vqw&quot; data-ke-size=&quot;size26&quot;&gt;4.1 트리쉐이킹이란 무엇인가&lt;/h2&gt;
&lt;p data-end=&quot;2226&quot; data-start=&quot;2188&quot; data-ke-size=&quot;size16&quot;&gt;트리쉐이킹은 &lt;b&gt;사용하지 않는 코드를 제거하는 최적화 기법&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;2254&quot; data-start=&quot;2228&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 코드가 있다고 가정해보겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585943402&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export function add() {}
export function subtract() {}
export function multiply() {}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2383&quot; data-start=&quot;2360&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다른 파일에서 다음처럼 사용합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585949458&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { add } from &quot;./math.js&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2467&quot; data-start=&quot;2437&quot; data-ke-size=&quot;size16&quot;&gt;이 경우 실제로 필요한 코드는 add 함수뿐입니다.&lt;/p&gt;
&lt;p data-end=&quot;2494&quot; data-start=&quot;2469&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 이를 분석하여 다음처럼 최적화합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585954679&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;math.js
└─ add()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2523&quot; data-ke-size=&quot;size16&quot;&gt;subtract와 multiply는 번들에 포함되지 않습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2566&quot; data-start=&quot;2563&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2588&quot; data-start=&quot;2568&quot; data-section-id=&quot;vilna5&quot; data-ke-size=&quot;size26&quot;&gt;4.2 트리쉐이킹이 가능한 이유&lt;/h2&gt;
&lt;p data-end=&quot;2624&quot; data-start=&quot;2590&quot; data-ke-size=&quot;size16&quot;&gt;트리쉐이킹은 &lt;b&gt;ES Module 구조 덕분에 가능&lt;/b&gt;합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585960663&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { add } from &quot;./math.js&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2701&quot; data-start=&quot;2678&quot; data-ke-size=&quot;size16&quot;&gt;이 문법은 정적으로 분석할 수 있기 때문에&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2735&quot; data-start=&quot;2703&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2717&quot; data-start=&quot;2703&quot; data-section-id=&quot;13t5ie9&quot;&gt;어떤 함수가 사용되는지&lt;/li&gt;
&lt;li data-end=&quot;2735&quot; data-start=&quot;2718&quot; data-section-id=&quot;1iaf9s&quot;&gt;어떤 export가 필요한지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2760&quot; data-start=&quot;2737&quot; data-ke-size=&quot;size16&quot;&gt;빌드 시점에 정확하게 파악할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2762&quot; data-ke-size=&quot;size16&quot;&gt;반면 CommonJS의 경우&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585966647&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const math = require(&quot;./math&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2884&quot; data-start=&quot;2830&quot; data-ke-size=&quot;size16&quot;&gt;이 구조는 런타임에 결정되기 때문에&lt;br /&gt;번들러가 어떤 코드가 필요한지 정확히 판단하기 어렵습니다.&lt;/p&gt;
&lt;hr data-end=&quot;2889&quot; data-start=&quot;2886&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2919&quot; data-start=&quot;2891&quot; data-section-id=&quot;5u7chq&quot;&gt;5. 코드 스플리팅(Code Splitting)&lt;/h1&gt;
&lt;h2 data-end=&quot;2943&quot; data-start=&quot;2921&quot; data-section-id=&quot;wy8hqa&quot; data-ke-size=&quot;size26&quot;&gt;5.1 왜 코드 스플리팅이 필요한가&lt;/h2&gt;
&lt;p data-end=&quot;2980&quot; data-start=&quot;2945&quot; data-ke-size=&quot;size16&quot;&gt;모든 코드를 하나의 파일로 묶는 것이 항상 좋은 것은 아닙니다.&lt;/p&gt;
&lt;p data-end=&quot;3008&quot; data-start=&quot;2982&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 기능이 있다고 가정해보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3037&quot; data-start=&quot;3010&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3018&quot; data-start=&quot;3010&quot; data-section-id=&quot;9ovlag&quot;&gt;메인 페이지&lt;/li&gt;
&lt;li data-end=&quot;3028&quot; data-start=&quot;3019&quot; data-section-id=&quot;1i1ujdk&quot;&gt;관리자 페이지&lt;/li&gt;
&lt;li data-end=&quot;3037&quot; data-start=&quot;3029&quot; data-section-id=&quot;dyujjp&quot;&gt;통계 페이지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3065&quot; data-start=&quot;3039&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 대부분 메인 페이지만 먼저 접근합니다.&lt;/p&gt;
&lt;p data-end=&quot;3097&quot; data-start=&quot;3067&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 관리자 코드까지 함께 로딩할 필요는 없습니다.&lt;/p&gt;
&lt;hr data-end=&quot;3102&quot; data-start=&quot;3099&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3120&quot; data-start=&quot;3104&quot; data-section-id=&quot;1grvn8p&quot; data-ke-size=&quot;size26&quot;&gt;5.2 동적 import&lt;/h2&gt;
&lt;p data-end=&quot;3154&quot; data-start=&quot;3122&quot; data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하는 방법이 &lt;b&gt;동적 import&lt;/b&gt;입니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1773585972874&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import(&quot;./admin.js&quot;).then(module =&amp;gt; {
module.initAdmin();
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3276&quot; data-start=&quot;3239&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3276&quot; data-start=&quot;3239&quot; data-ke-size=&quot;size16&quot;&gt;이 코드는 admin.js를 &lt;b&gt;필요한 순간에만 로딩&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-end=&quot;3304&quot; data-start=&quot;3278&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 이를 분석해 별도의 파일로 분리합니다.&lt;/p&gt;
&lt;p data-end=&quot;3335&quot; data-start=&quot;3306&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 결과물은 다음과 같이 생성될 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1773585987933&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dist
├─ main.js
├─ vendor.js
└─ admin.chunk.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3422&quot; data-start=&quot;3396&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 초기 로딩 속도가 크게 개선됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;3427&quot; data-start=&quot;3424&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3442&quot; data-start=&quot;3429&quot; data-section-id=&quot;x49tgn&quot;&gt;6. 최종 번들 생성&lt;/h1&gt;
&lt;p data-end=&quot;3474&quot; data-start=&quot;3444&quot; data-ke-size=&quot;size16&quot;&gt;모든 분석이 끝나면 번들러는 최종 결과물을 생성합니다.&lt;/p&gt;
&lt;p data-end=&quot;3497&quot; data-start=&quot;3476&quot; data-ke-size=&quot;size16&quot;&gt;보통 다음과 같은 최적화가 적용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3554&quot; data-start=&quot;3499&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3515&quot; data-start=&quot;3499&quot; data-section-id=&quot;p4qt4t&quot;&gt;코드 압축 (minify)&lt;/li&gt;
&lt;li data-end=&quot;3526&quot; data-start=&quot;3516&quot; data-section-id=&quot;l4cqm1&quot;&gt;변수 이름 축소&lt;/li&gt;
&lt;li data-end=&quot;3539&quot; data-start=&quot;3527&quot; data-section-id=&quot;532nd4&quot;&gt;불필요한 코드 제거&lt;/li&gt;
&lt;li data-end=&quot;3554&quot; data-start=&quot;3540&quot; data-section-id=&quot;124esk1&quot;&gt;해시 기반 파일명 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3583&quot; data-start=&quot;3556&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 결과물은 다음처럼 생성될 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1773585995869&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dist
├─ index.html
├─ app.34ab29.js
├─ vendor.82cd11.js
└─ style.91ac20.css&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3707&quot; data-start=&quot;3674&quot; data-ke-size=&quot;size16&quot;&gt;해시 파일명은 &lt;b&gt;브라우저 캐시 관리&lt;/b&gt;를 위해 사용됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;3712&quot; data-start=&quot;3709&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;192&quot; data-start=&quot;185&quot; data-section-id=&quot;1xj7k1y&quot;&gt;7. 정리&lt;/h1&gt;
&lt;p data-end=&quot;229&quot; data-start=&quot;194&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 번들러가 내부에서 어떤 과정을 거치는지 살펴보았습니다.&lt;/p&gt;
&lt;p data-end=&quot;263&quot; data-start=&quot;231&quot; data-ke-size=&quot;size16&quot;&gt;번들러는 단순히 여러 파일을 하나로 합치는 도구가 아니라,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;500&quot; data-start=&quot;265&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;291&quot; data-start=&quot;265&quot; data-section-id=&quot;1uf9fy3&quot;&gt;엔트리 파일을 기준으로 모듈을 분석하고&lt;/li&gt;
&lt;li data-end=&quot;347&quot; data-start=&quot;292&quot; data-section-id=&quot;o8bj1v&quot;&gt;import 관계를 따라 &lt;b&gt;의존성 그래프(Dependency Graph)&lt;/b&gt; 를 생성하며&lt;/li&gt;
&lt;li data-end=&quot;375&quot; data-start=&quot;348&quot; data-section-id=&quot;tlsgs2&quot;&gt;AST 분석을 통해 코드 구조를 이해하고&lt;/li&gt;
&lt;li data-end=&quot;428&quot; data-start=&quot;376&quot; data-section-id=&quot;ooowje&quot;&gt;사용되지 않는 코드를 제거하는 &lt;b&gt;트리쉐이킹(Tree Shaking)&lt;/b&gt; 을 수행하고&lt;/li&gt;
&lt;li data-end=&quot;474&quot; data-start=&quot;429&quot; data-section-id=&quot;6cbfu1&quot;&gt;필요에 따라 &lt;b&gt;코드 스플리팅(Code Splitting)&lt;/b&gt; 을 적용해&lt;/li&gt;
&lt;li data-end=&quot;500&quot; data-start=&quot;475&quot; data-section-id=&quot;1ydtcv7&quot;&gt;최종적으로 최적화된 번들을 만들어냅니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;547&quot; data-start=&quot;502&quot; data-ke-size=&quot;size16&quot;&gt;즉 번들러는 &lt;b&gt;모듈을 분석하고 최적화하는 빌드 시스템&lt;/b&gt;이라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;547&quot; data-start=&quot;502&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;291&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 번들러가 내부에서 어떻게 동작하는지 정리해봤습니다.&lt;/p&gt;
&lt;p data-end=&quot;375&quot; data-start=&quot;326&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 실제로 많이 사용되는 번들러들은&lt;br /&gt;이 과정을 어떤 방식으로 처리하고 있을까요?&lt;/p&gt;
&lt;p data-end=&quot;685&quot; data-start=&quot;622&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;257&quot; data-start=&quot;203&quot; data-ke-size=&quot;size16&quot;&gt;다음 글에서는 대표적인 번들러인 &lt;b&gt;Webpack과 Vite의 구조적 차이와 설계철학을&lt;/b&gt;&amp;nbsp;비교해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;699&quot; data-start=&quot;687&quot; data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>Frontend Basic (기초 이론)</category>
      <author>IT의 IT 블로그</author>
      <guid isPermaLink="true">https://dlsxo.tistory.com/10</guid>
      <comments>https://dlsxo.tistory.com/10#entry10comment</comments>
      <pubDate>Sun, 15 Mar 2026 23:57:45 +0900</pubDate>
    </item>
  </channel>
</rss>