<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코딩하는퇴근길</title>
    <link>https://jjung2ing.tistory.com/</link>
    <description>출근은 의무, 코딩은 운명.
야근보다 더한 퇴근 후 코딩 이야기.</description>
    <language>ko</language>
    <pubDate>Tue, 7 Jul 2026 10:10:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>콘솔로그</managingEditor>
    <item>
      <title>[개발읽기 vol.10] 프론트엔드 개발자를 위한 Node.js와 npm 기초 완벽 정리</title>
      <link>https://jjung2ing.tistory.com/94</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-17 오전 10.14.57.png&quot; data-origin-width=&quot;2974&quot; data-origin-height=&quot;1434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7n450/btsQCH9tc6o/sp2wGzERqQOpAoiaVMsqak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7n450/btsQCH9tc6o/sp2wGzERqQOpAoiaVMsqak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7n450/btsQCH9tc6o/sp2wGzERqQOpAoiaVMsqak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7n450%2FbtsQCH9tc6o%2Fsp2wGzERqQOpAoiaVMsqak%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;2974&quot; height=&quot;1434&quot; data-filename=&quot;스크린샷 2025-09-17 오전 10.14.57.png&quot; data-origin-width=&quot;2974&quot; data-origin-height=&quot;1434&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사나 프로젝트에서 프론트엔드 개발을 시작할 때, 우리가 가장 먼저 하는 일은 깃(Git)에서 소스를 받아오는 것입니다.&lt;br /&gt;그리고 소스를 받은 뒤 거의 자동처럼 입력하는 명령어가 있죠.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;바로 npm install 입니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;이 명령어 하나로 수많은 라이브러리와 패키지가 설치되고, 프로젝트가 실행 가능한 상태로 세팅됩니다.&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;그런데 잠깐, 여기서 궁금증이 생깁니다.&lt;br /&gt;npm이 도대체 뭐길래 이런 일을 해주는 걸까요?&lt;br /&gt;그리고 이 npm을 사용하기 위해 꼭 필요한 Node.js는 왜 존재하는 걸까요?&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 &lt;b&gt;프론트엔드 개발자라면 반드시 알아야 할 Node.js와 npm&lt;/b&gt;에 대해,&lt;br /&gt;그 배경과 역할, 그리고 왜 생겨났는지를 차근차근 풀어보려 합니다.&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;들어가기 이전에 미리 알고 가야하는 개념이 있어요.&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발자가 코드를 작성을 하고 코드를 실행할 수 있는 &amp;ldquo;실행 환경&amp;rdquo;이 필요해요.&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어,&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;  자전거 = JavaScript 코드&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;139&quot; data-start=&quot;116&quot;&gt;자전거 자체만으로는 이동할 수 없음&lt;/li&gt;
&lt;li data-end=&quot;195&quot; data-start=&quot;140&quot;&gt;자전거는 &lt;b&gt;규칙과 기능&lt;/b&gt;만 가지고 있음 (페달 밟으면 굴러간다, 핸들 돌리면 방향 전환)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;  사람 = 런타임 환경(실행 환경)&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;241&quot; data-start=&quot;217&quot;&gt;사람이 페달을 밟아야 자전거가 움직임 (런타임이 없으면 코드가 실행되지 않는다)&lt;/li&gt;
&lt;li data-end=&quot;291&quot; data-start=&quot;242&quot;&gt;브라우저나 Node.js 같은 &lt;b&gt;런타임 환경이 코드 실행을 가능하게 하는 힘&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;338&quot; data-start=&quot;292&quot;&gt;사람이 자전거를 조종하듯, 런타임이 JavaScript 코드를 해석하고 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;이 개념을 잘 기억하고, 이제 본격적으로 Node.js에 대해 설명해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;469&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;236&quot; data-start=&quot;206&quot; data-ke-size=&quot;size26&quot;&gt;  브라우저 = JavaScript 런타임 환경&lt;/h2&gt;
&lt;p data-end=&quot;294&quot; data-start=&quot;237&quot; data-ke-size=&quot;size16&quot;&gt;브라우저는 원래 &lt;b&gt;웹 페이지를 실행&lt;/b&gt;하기 위해 만들어졌습니다.&lt;br /&gt;따라서 브라우저 런타임에서는 아래와 같은 기능과 API를 제공해요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;425&quot; data-start=&quot;295&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;295&quot;&gt;JavaScript 엔진 (예: Chrome=V8, Firefox=SpiderMonkey)&lt;/li&gt;
&lt;li data-end=&quot;408&quot; data-start=&quot;350&quot;&gt;Web API (DOM, BOM, Fetch API, Cookies, localStorage 등)&lt;/li&gt;
&lt;li data-end=&quot;425&quot; data-start=&quot;409&quot;&gt;이벤트 루프, 콜백 큐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;467&quot; data-start=&quot;427&quot; data-ke-size=&quot;size16&quot;&gt;  덕분에 버튼 클릭, 화면 변경, Ajax 요청 같은 동작이 가능&lt;/p&gt;
&lt;hr data-end=&quot;472&quot; data-start=&quot;469&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;507&quot; data-start=&quot;474&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ Node.js = JavaScript 런타임 환경&lt;/h2&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;508&quot; data-ke-size=&quot;size16&quot;&gt;Node.js는 &lt;b&gt;브라우저 밖에서 JavaScript 실행&lt;/b&gt;을 가능하게 만든 런타임입니다.&lt;br /&gt;Node 런타임에서는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;아래와 같은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기능과 API를 제공해요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;677&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;&gt;JavaScript 엔진 (V8)&lt;/li&gt;
&lt;li data-end=&quot;657&quot; data-start=&quot;601&quot;&gt;Node 전용 API (파일 시스템 fs, 네트워크 net/http, OS, 이벤트 모듈 등)&lt;/li&gt;
&lt;li data-end=&quot;677&quot; data-start=&quot;658&quot;&gt;이벤트 루프, 비동기 I/O&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;720&quot; data-start=&quot;679&quot; data-ke-size=&quot;size16&quot;&gt;  덕분에 서버 실행, DB 연결, 파일 읽기/쓰기 같은 동작이 가능&lt;/p&gt;
&lt;h2 data-end=&quot;155&quot; data-start=&quot;136&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;155&quot; data-start=&quot;136&quot; data-ke-size=&quot;size26&quot;&gt;Node.js란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;Node.js는 &lt;b&gt;오픈 소스이자 크로스 플랫폼 JavaScript 런타임 환경&lt;/b&gt;입니다.&lt;br /&gt;자바스크립트(JavaScript)는 원래 &lt;b&gt;웹 페이지 안에서 동작하도록 만들어진 언어&lt;/b&gt;예요.&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 브라우저(Chrome, Safari, Firefox 등)에서:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;314&quot; data-start=&quot;276&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;299&quot; data-start=&quot;276&quot;&gt;버튼을 클릭했을 때 글씨를 바꾸거나&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;300&quot;&gt;팝업을 띄우는 동작&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;369&quot; data-start=&quot;316&quot; data-ke-size=&quot;size16&quot;&gt;이 모든 것이 &lt;b&gt;브라우저 안에서 JavaScript 코드가 실행&lt;/b&gt;되기 때문에 가능합니다.&lt;/p&gt;
&lt;p data-end=&quot;369&quot; data-start=&quot;316&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;Node.js를 설치하면 브라우저 없이도&lt;/b&gt; 컴퓨터 터미널에서 JavaScript를 바로 실행할 수 있습니다.&lt;br /&gt;실제로 실행해보려면:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;242&quot; data-start=&quot;156&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;170&quot; data-start=&quot;156&quot;&gt;터미널을 엽니다.&lt;/li&gt;
&lt;li data-end=&quot;199&quot; data-start=&quot;171&quot;&gt;node라고 입력하고 엔터를 누릅니다.&lt;/li&gt;
&lt;li data-end=&quot;242&quot; data-start=&quot;200&quot;&gt;이제 바로 JavaScript 코드를 입력하고 실행할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-17 오후 1.23.48.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AQJmE/btsQBk14yws/LJKlP4REvxPfhvi0gGvXWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AQJmE/btsQBk14yws/LJKlP4REvxPfhvi0gGvXWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AQJmE/btsQBk14yws/LJKlP4REvxPfhvi0gGvXWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAQJmE%2FbtsQBk14yws%2FLJKlP4REvxPfhvi0gGvXWK%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;434&quot; height=&quot;296&quot; data-filename=&quot;스크린샷 2025-09-17 오후 1.23.48.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-end=&quot;297&quot; data-start=&quot;156&quot; data-ke-style=&quot;style2&quot;&gt;한 줄 요약: 런타임 환경 = JavaScript 코드가 실행되고, 주변 기능을 제공받는 환경입니다.&lt;/blockquote&gt;
&lt;h3 data-end=&quot;93&quot; data-start=&quot;67&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node.js는 어떤 특징을 가지고 있는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;93&quot; data-start=&quot;67&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;93&quot; data-start=&quot;67&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;1️⃣ V8 엔진 기반의 높은 성능&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;271&quot; data-start=&quot;94&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;168&quot; data-start=&quot;94&quot;&gt;Node.js는 &lt;b&gt;Google Chrome의 핵심 엔진인 V8 JavaScript 엔진&lt;/b&gt;을 브라우저 외부에서도 실행합니다.&lt;/li&gt;
&lt;li data-end=&quot;226&quot; data-start=&quot;169&quot;&gt;덕분에:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;226&quot; data-start=&quot;178&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;197&quot; data-start=&quot;178&quot;&gt;매우 빠른 성능과 효율성 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;⚡&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;226&quot; data-start=&quot;200&quot;&gt;최신 ECMAScript 표준 지원 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;271&quot; data-start=&quot;227&quot;&gt;즉, 브라우저 없이도 빠르고 현대적인 자바스크립트를 활용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758067018405&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Node.js에서 최신 JavaScript 문법 바로 사용 가능
const greet = (name) =&amp;gt; {
  console.log(`Hello, ${name}!`);
};

greet(&quot;Node.js&quot;); // Hello, Node.js!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;87&quot; data-start=&quot;58&quot; data-ke-size=&quot;size18&quot;&gt;2️⃣ 비동기 I/O와 논블로킹 아키텍처&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;268&quot; data-start=&quot;88&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;142&quot; data-start=&quot;88&quot;&gt;Node.js는 &lt;b&gt;요청마다 새로운 스레드를 생성하지 않고 단일 프로세스로 실행&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;li data-end=&quot;209&quot; data-start=&quot;143&quot;&gt;덕분에:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;209&quot; data-start=&quot;152&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;183&quot; data-start=&quot;152&quot;&gt;동시에 많은 요청 처리 가능 (고성능 서버)&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;⏱️&lt;span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt; &lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;단일쓰레드인데 어떻게 동시에 많은 요청이 처리 가능한걸까?&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;비동기 I/O 덕분에 동시에 처리 가능. &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;Node.js가 I/O 작업(파일 읽기, HTTP 요청 등)을 만나면 자바스크립트 코드 실행은 멈추지 않고 작업을 백그라운드로 넘김&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt; &lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;-&amp;gt; &lt;/span&gt;작업이 끝나면 콜백 함수, Promise, async/await 등을 통해 결과를 다시 처리&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;209&quot; data-start=&quot;186&quot;&gt;블로킹 없이 빠른 I/O 처리 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;210&quot;&gt;즉, 서버가 다른 작업을 기다리지 않고 &lt;b&gt;효율적으로 여러 작업을 동시에 처리&lt;/b&gt;할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;779&quot; data-start=&quot;642&quot; data-ke-style=&quot;style2&quot;&gt;단일 프로세스(Single Process) : 프로그램이 하나의 프로세스만 사용하여 실행되는 것&lt;br /&gt;즉, Node.js 앱을 실행하면 하나의 프로세스 안에서 모든 코드가 돌아감&lt;br /&gt;&lt;br /&gt;프로세스 : 프로그램이 실행 중인 상태를 운영체제에서 관리하는 단위&lt;br /&gt;예시) 브라우저 하나를 열면 하나의 프로세스가 생성 메모장에서 메모장 프로그램을 열면 또 다른 프로세스가 생성&lt;/blockquote&gt;
&lt;p data-end=&quot;779&quot; data-start=&quot;642&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;비동기 I/O 방식을 사용하여 CPU 자원을 효율적으로 활용하며,&lt;br /&gt;네트워크, 데이터베이스, 파일 시스템 작업 시에도 스레드를 차단하지 않습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758067036784&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 파일을 비동기적으로 읽는 예시
const fs = require(&quot;fs&quot;);

fs.readFile(&quot;example.txt&quot;, &quot;utf8&quot;, (err, data) =&amp;gt; {
  if (err) {
    console.error(&quot;파일 읽기 에러:&quot;, err);
    return;
  }
  console.log(&quot;파일 내용:&quot;, data);
});

console.log(&quot;읽기 요청 완료&quot;); // 이 부분이 먼저 실행됨&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1063&quot; data-start=&quot;1039&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1063&quot; data-start=&quot;1039&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1063&quot; data-start=&quot;1039&quot; data-ke-size=&quot;size18&quot;&gt;3️⃣ 스레드 관리의 부담 없는 개발 환경&lt;/p&gt;
&lt;p data-end=&quot;1188&quot; data-start=&quot;1064&quot; data-ke-size=&quot;size16&quot;&gt;전통적인 서버 환경에서는 스레드 동시성 관리가 버그의 주요 원인이 되곤 합니다.&lt;br /&gt;그러나 Node.js는 기본적으로 &lt;b&gt;논블로킹 패러다임&lt;/b&gt;을 따르기 때문에&lt;br /&gt;개발자가 스레드 동기화 문제에 신경 쓰지 않아도 됩니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1188&quot; data-start=&quot;1064&quot; data-ke-style=&quot;style2&quot;&gt;블로킹(Blocking) vs 논블로킹(Non-blocking)&lt;br /&gt;블로킹 : 어떤 작업이 끝날 때까지 다음 코드 실행을 기다리는 방식&lt;br /&gt;논블로킹: 작업을 요청하고, 결과가 올 때까지 기다리지 않고 다음 코드 실행 완료되면 콜백이나 Promise가 결과를 알려줌&lt;br /&gt;&lt;br /&gt;Node.js는 I/O 작업(파일 읽기, 네트워크 요청 등)을 논블로킹 방식으로 처리 단일 스레드로도 수천 개 동시 요청을 처리할 수 있는 이유 이벤트 루프(Event Loop)와 함께 동작하여, 작업 완료 시 콜백 함수나 Promise를 통해 결과 처리&lt;/blockquote&gt;
&lt;pre id=&quot;code_1758067055995&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// setTimeout으로 확인하는 비동기 동작
console.log(&quot;첫 번째 출력&quot;);

setTimeout(() =&amp;gt; {
  console.log(&quot;비동기 출력 (2초 후 실행)&quot;);
}, 2000);

console.log(&quot;두 번째 출력&quot;);
// 실행 순서: 첫 번째 &amp;rarr; 두 번째 &amp;rarr; 비동기 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1402&quot; data-start=&quot;1379&quot; data-ke-size=&quot;size18&quot;&gt;4️⃣ ECMAScript 활용의 유연성&lt;/p&gt;
&lt;p data-end=&quot;1482&quot; data-start=&quot;1403&quot; data-ke-size=&quot;size16&quot;&gt;Node.js에서는 브라우저 호환성을 기다릴 필요 없이&lt;br /&gt;&lt;b&gt;새로운 ECMAScript 기능을 바로 사용할 수 있는 장점&lt;/b&gt;이 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758067074010&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 최신 ECMAScript 기능: optional chaining
const user = { profile: { name: &quot;콘솔로그&quot; } };

console.log(user?.profile?.name); // &quot;콘솔로그&quot;
console.log(user?.account?.email); // undefined (에러 아님)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;108&quot; data-start=&quot;92&quot; data-ke-size=&quot;size18&quot;&gt;5️⃣&amp;nbsp;네트워킹과 서버 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js는 네트워킹에 대한 &lt;b&gt;최고 수준의 지원&lt;/b&gt;을 포함한 훌륭한 표준 라이브러리를 제공합니다.&lt;br /&gt;그중 대표적인 것이 http 모듈이며, 이를 통해 손쉽게 웹 서버를 만들 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;338&quot; data-start=&quot;214&quot; data-ke-size=&quot;size16&quot;&gt;createServer() 메서드는 새로운 HTTP 서버를 생성하고 반환합니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;338&quot; data-start=&quot;214&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;HTTP 서버를 생성한다&lt;/b&gt;&lt;br /&gt;우리가 평소에 웹사이트를 열 때는 브라우저 주소창에 주소(URL)를 입력합니다.&lt;br /&gt;그러면 브라우저는 서버에게&amp;nbsp;&amp;ldquo;이 페이지 좀 보여줘!&amp;rdquo;&amp;nbsp;하고 요청(Request)을 보내고,&lt;br /&gt;서버는 그에 맞는 데이터를 찾아서 응답(Response)을 돌려줍니다.&lt;br /&gt;&lt;br /&gt;&quot;HTTP 서버를 생성한다&quot;는 말은, Node.js가 브라우저의 요청을 받아주고 알맞은 답을 돌려주는 프로그램을 만든다는 뜻입니다.&lt;br /&gt;쉽게 말해,&lt;br /&gt;&quot;누군가 나에게 들어오면 받아줄 준비를 하자&quot; &amp;rarr; 서버 열기 (server.listen())&quot;들어온 요청을 확인하고 답장을 보내자&quot; &lt;br /&gt;&amp;rarr; 요청 처리 (req, res)&lt;br /&gt;이 과정을 가능하게 해주는 것이 바로 http.createServer() 입니다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1758067180486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Node.js에서 가장 간단한 서버 만들기
const http = require(&quot;http&quot;);

const server = http.createServer((req, res) =&amp;gt; {
  res.end(&quot;안녕하세요! 여기는 Node.js 서버입니다  &quot;);
});

// 3000번 포트에서 요청을 받아줄 준비
server.listen(3000, () =&amp;gt; {
  console.log(&quot;서버 실행 중 &amp;rarr; http://localhost:3000&quot;);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;957&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;957&quot; data-ke-size=&quot;size16&quot;&gt;위 코드를 실행한 뒤 브라우저에서 http://localhost:3000 으로 접속하면,&lt;br /&gt;&amp;ldquo;안녕하세요! 여기는 Node.js 서버입니다  &amp;rdquo; 이라는 문구가 화면에 출력됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;957&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;895&quot; data-ke-size=&quot;size16&quot;&gt;즉, Node.js는 복잡한 설정 없이도 &lt;b&gt;웹 브라우저의 요청을 받아주는 서버 역할&lt;/b&gt;을&lt;br /&gt;아주 간단한 코드 몇 줄로 구현할 수 있는 강력한 도구입니다.&lt;/p&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;895&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;895&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;895&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;162&quot; data-start=&quot;122&quot; data-ke-size=&quot;size26&quot;&gt;Node.js를 배우기 전에 알아두면 좋을 JavaScript 기초&lt;/h2&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;Node.js를 배우기 전, &lt;b&gt;JavaScript 기초를 어느 정도 알고 있는 것이 큰 도움이 됩니다.&lt;/b&gt;&lt;br /&gt;프로그래밍 초보라면 코딩하면서 &amp;ldquo;이건 JavaScript이고, 이건 Node.js인가?&amp;rdquo; 하고 혼란스러울 수 있어요.&lt;br /&gt;Node.js를 깊이 이해하려면 먼저 JavaScript의 기본 개념을 확실히 해두는 것이 좋습니다.&lt;/p&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;아래는 노드 공식 홈페이지에 나와있는 Node.js를 깊이 있게 공부하기 전에 무엇을 배우는 것이 좋을 개념들입니다.&lt;/p&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;링크도 첨부해드릴께요.&lt;/p&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://nodejs.org/ko/learn/getting-started/how-much-javascript-do-you-need-to-know-to-use-nodejs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nodejs.org/ko/learn/getting-started/how-much-javascript-do-you-need-to-know-to-use-nodejs&lt;/a&gt;)&lt;/p&gt;
&lt;h3 data-end=&quot;377&quot; data-start=&quot;355&quot; data-ke-size=&quot;size23&quot;&gt;JavaScript 기초 개념&lt;/h3&gt;
&lt;p data-end=&quot;452&quot; data-start=&quot;379&quot; data-ke-size=&quot;size16&quot;&gt;아래 개념들을 알고 있다면, 브라우저 환경과 Node.js 환경 모두에서&lt;br /&gt;원활하게 개발할 수 있는 기반을 다질 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;900&quot; data-start=&quot;454&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;486&quot; data-start=&quot;454&quot;&gt;&lt;b&gt;어휘 구조 &amp;amp; 표현&lt;/b&gt;: 문법과 기본 표현 방식&lt;/li&gt;
&lt;li data-end=&quot;521&quot; data-start=&quot;487&quot;&gt;&lt;b&gt;데이터 유형&lt;/b&gt;: 숫자, 문자열, 불리언, 객체 등&lt;/li&gt;
&lt;li data-end=&quot;560&quot; data-start=&quot;522&quot;&gt;&lt;b&gt;변수 &amp;amp; 상수&lt;/b&gt;: var, let, const&lt;/li&gt;
&lt;li data-end=&quot;604&quot; data-start=&quot;561&quot;&gt;&lt;b&gt;함수 &amp;amp; 화살표 함수&lt;/b&gt;: function, () =&amp;gt; {}&lt;/li&gt;
&lt;li data-end=&quot;637&quot; data-start=&quot;605&quot;&gt;&lt;b&gt;this 연산자&lt;/b&gt;: 객체와 함수 컨텍스트 이해&lt;/li&gt;
&lt;li data-end=&quot;686&quot; data-start=&quot;638&quot;&gt;&lt;b&gt;루프 &amp;amp; 조건문&lt;/b&gt;: for, while, if, switch&lt;/li&gt;
&lt;li data-end=&quot;720&quot; data-start=&quot;687&quot;&gt;&lt;b&gt;배열과 객체&lt;/b&gt;: 데이터를 저장하고 조작하는 방법&lt;/li&gt;
&lt;li data-end=&quot;756&quot; data-start=&quot;721&quot;&gt;&lt;b&gt;템플릿 리터럴&lt;/b&gt;: ${}로 문자열 내 변수 사용&lt;/li&gt;
&lt;li data-end=&quot;795&quot; data-start=&quot;757&quot;&gt;&lt;b&gt;엄격 모드&lt;/b&gt;: &quot;use strict&quot;;로 안전한 코딩&lt;/li&gt;
&lt;li data-end=&quot;848&quot; data-start=&quot;796&quot;&gt;&lt;b&gt;ES6 이후 문법&lt;/b&gt;: class, let/const, 구조 분해, 모듈 등&lt;/li&gt;
&lt;li data-end=&quot;900&quot; data-start=&quot;849&quot;&gt;&lt;b&gt;비동기 JavaScript 기초&lt;/b&gt;: 콜백, Promise, async/await&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;933&quot; data-start=&quot;907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;933&quot; data-start=&quot;907&quot; data-ke-size=&quot;size26&quot;&gt;Node.js 핵심: 비동기 프로그래밍&lt;/h2&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;935&quot; data-ke-size=&quot;size16&quot;&gt;Node.js를 이해하려면 &lt;b&gt;비동기 프로그래밍&lt;/b&gt;에 익숙해져야 합니다.&lt;br /&gt;Node.js는 요청 처리, 파일 I/O, 네트워크 작업 등에서 &lt;b&gt;블로킹 없이 빠르게 처리&lt;/b&gt;하도록 설계되어 있기 때문입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1292&quot; data-start=&quot;1053&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1084&quot; data-start=&quot;1053&quot;&gt;&lt;b&gt;콜백 함수&lt;/b&gt;: 작업이 끝난 후 실행되는 함수&lt;/li&gt;
&lt;li data-end=&quot;1142&quot; data-start=&quot;1085&quot;&gt;&lt;b&gt;타이머&lt;/b&gt;: 일정 시간 후 실행되는 함수(setTimeout, setInterval)&lt;/li&gt;
&lt;li data-end=&quot;1178&quot; data-start=&quot;1143&quot;&gt;&lt;b&gt;Promise&lt;/b&gt;: 비동기 작업의 결과를 다루는 객체&lt;/li&gt;
&lt;li data-end=&quot;1221&quot; data-start=&quot;1179&quot;&gt;&lt;b&gt;async/await&lt;/b&gt;: 비동기 코드를 동기 코드처럼 쉽게 작성&lt;/li&gt;
&lt;li data-end=&quot;1248&quot; data-start=&quot;1222&quot;&gt;&lt;b&gt;클로저&lt;/b&gt;: 함수 내부에서 변수 유지&lt;/li&gt;
&lt;li data-end=&quot;1292&quot; data-start=&quot;1249&quot;&gt;&lt;b&gt;이벤트 루프&lt;/b&gt;: Node.js가 비동기 작업을 관리하는 핵심 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1375&quot; data-start=&quot;1294&quot; data-ke-size=&quot;size16&quot;&gt;이러한 개념을 숙지하면, Node.js에서 발생하는 &lt;b&gt;비동기 I/O, 이벤트 처리, 서버 요청 관리&lt;/b&gt; 등을 자연스럽게 이해할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1375&quot; data-start=&quot;1294&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1375&quot; data-start=&quot;1294&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-end=&quot;165&quot; data-start=&quot;142&quot; data-ke-size=&quot;size26&quot;&gt;Node.js와 브라우저의 차이점&lt;/h2&gt;
&lt;p data-end=&quot;301&quot; data-start=&quot;167&quot; data-ke-size=&quot;size16&quot;&gt;Node.js와 브라우저는 모두 &lt;b&gt;JavaScript&lt;/b&gt;를 사용하지만,&lt;br /&gt;실제로 앱을 만들 때 경험은 크게 다릅니다.&lt;br /&gt;프론트엔드 개발자 입장에서는, &lt;b&gt;프론트와 백엔드를 모두 같은 언어로 개발할 수 있다&lt;/b&gt;는 것이 큰 장점입니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;421&quot; data-start=&quot;303&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;421&quot; data-start=&quot;305&quot; data-ke-size=&quot;size16&quot;&gt;Node.js를 이용하면 브라우저(JavaScript)와 서버(Node.js) 모두에서 같은 언어를 사용할 수 있어, 큰 이점을 갖게 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-end=&quot;92&quot; data-start=&quot;64&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;92&quot; data-start=&quot;64&quot; data-ke-size=&quot;size23&quot;&gt;차이점 1️⃣ 환경과 제공되는 API의 차이&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;380&quot; data-start=&quot;93&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;217&quot; data-start=&quot;93&quot;&gt;&lt;b&gt;브라우저 JavaScript&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;217&quot; data-start=&quot;119&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;181&quot; data-start=&quot;119&quot;&gt;주로 &lt;b&gt;DOM 조작, Cookies, localStorage&lt;/b&gt; 등 Web Platform API 사용&lt;/li&gt;
&lt;li data-end=&quot;217&quot; data-start=&quot;184&quot;&gt;document, window 같은 객체 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;380&quot; data-start=&quot;219&quot;&gt;&lt;b&gt;Node.js&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;380&quot; data-start=&quot;237&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;267&quot; data-start=&quot;237&quot;&gt;document, window 객체 없음&lt;/li&gt;
&lt;li data-end=&quot;319&quot; data-start=&quot;270&quot;&gt;대신 &lt;b&gt;파일 시스템 접근, 네트워크 요청, 서버 관리&lt;/b&gt; 등 다양한 API 제공&lt;/li&gt;
&lt;li data-end=&quot;380&quot; data-start=&quot;322&quot;&gt;즉, &lt;b&gt;브라우저용 JavaScript와 Node.js는 실행 환경과 사용 가능한 기능이 다름&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;브라우저 JavaScript는 화면과 상호작용, Node.js는 서버와 시스템 제어에 특화되어 있다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1758067640356&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 브라우저에서는 불가능한 예시: Node.js 파일 읽기
const fs = require(&quot;fs&quot;);

fs.readFile(&quot;example.txt&quot;, &quot;utf8&quot;, (err, data) =&amp;gt; {
  if (err) throw err;
  console.log(data);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;81&quot; data-start=&quot;64&quot; data-ke-size=&quot;size23&quot;&gt;차이점 2️⃣ 환경 제어&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;272&quot; data-start=&quot;82&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;166&quot; data-start=&quot;82&quot;&gt;&lt;b&gt;Node.js&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;166&quot; data-start=&quot;100&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;134&quot; data-start=&quot;100&quot;&gt;개발자가 &lt;b&gt;어떤 버전에서 실행할지 직접 결정&lt;/b&gt; 가능&lt;/li&gt;
&lt;li data-end=&quot;166&quot; data-start=&quot;137&quot;&gt;최신 ES2015+ 문법을 바로 사용 가능 ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;272&quot; data-start=&quot;168&quot;&gt;&lt;b&gt;브라우저 JavaScript&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;272&quot; data-start=&quot;194&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;229&quot; data-start=&quot;194&quot;&gt;사용자가 어떤 브라우저를 쓰는지 개발자가 제어할 수 없음&lt;/li&gt;
&lt;li data-end=&quot;272&quot; data-start=&quot;232&quot;&gt;호환성을 위해 &lt;b&gt;Babel 같은 트랜스파일러&lt;/b&gt; 사용 필요 ⚠️&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Node.js는 실행 환경을 개발자가 직접 제어할 수 있어 최신 문법 사용이 자유롭다. 브라우저는 사용자 환경에 따라 제약이 생긴다.&lt;/blockquote&gt;
&lt;p data-end=&quot;1078&quot; data-start=&quot;977&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1078&quot; data-start=&quot;977&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;73&quot; data-start=&quot;55&quot; data-ke-size=&quot;size23&quot;&gt;차이점 3️⃣ 모듈 시스템&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;327&quot; data-start=&quot;74&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;180&quot; data-start=&quot;74&quot;&gt;&lt;b&gt;Node.js&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;180&quot; data-start=&quot;92&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;145&quot; data-start=&quot;92&quot;&gt;CommonJS(require())와 ES Modules(import) 모두 지원&lt;/li&gt;
&lt;li data-end=&quot;180&quot; data-start=&quot;148&quot;&gt;오래된 코드와 최신 문법을 &lt;b&gt;동시에 활용 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;182&quot;&gt;&lt;b&gt;브라우저 JavaScript&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;327&quot; data-start=&quot;208&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;245&quot; data-start=&quot;208&quot;&gt;최근에야 ES Modules(import) 표준이 도입됨&lt;/li&gt;
&lt;li data-end=&quot;273&quot; data-start=&quot;248&quot;&gt;require()는 사용할 수 없음&lt;/li&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;276&quot;&gt;호환성을 위해 &lt;b&gt;번들러(예: Webpack, Vite, Parcel)&lt;/b&gt; 사용 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Node.js는 다양한 모듈 방식을 지원하지만, 브라우저는 주로 최신 import만 지원하며, 구형 방식인 require()는 사용할 수 없다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1758067665220&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Node.js에서는 이렇게도 가능
const fs = require(&quot;fs&quot;); // CommonJS
import path from &quot;path&quot;;   // ES Module&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-17 오전 9.08.04.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yE54N/btsQBP7SAwn/qNkvVXnMMEgeRYCkktllck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yE54N/btsQBP7SAwn/qNkvVXnMMEgeRYCkktllck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yE54N/btsQBP7SAwn/qNkvVXnMMEgeRYCkktllck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyE54N%2FbtsQBP7SAwn%2FqNkvVXnMMEgeRYCkktllck%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;1646&quot; height=&quot;458&quot; data-filename=&quot;스크린샷 2025-09-17 오전 9.08.04.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;224&quot; data-start=&quot;196&quot;&gt; ️ V8 JavaScript 엔진 완벽 정리&lt;/h1&gt;
&lt;h3 data-end=&quot;252&quot; data-start=&quot;226&quot; data-ke-size=&quot;size23&quot;&gt;1. V8 JavaScript 엔진이란?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;373&quot; data-start=&quot;253&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;324&quot; data-start=&quot;253&quot;&gt;&lt;b&gt;V8&lt;/b&gt;은 Google이 개발한 JavaScript 엔진으로,&lt;br /&gt;Chrome 브라우저의 핵심 동작을 담당합니다.&lt;/li&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;325&quot;&gt;역할: 우리가 작성한 &lt;b&gt;JavaScript 코드를 실제로 실행하는 프로그램&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;402&quot; data-start=&quot;380&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;402&quot; data-start=&quot;380&quot; data-ke-size=&quot;size23&quot;&gt;2.   브라우저와 V8의 관계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;580&quot; data-start=&quot;403&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;463&quot; data-start=&quot;403&quot;&gt;브라우저에는 DOM, Cookies, Fetch API 등 &lt;b&gt;다양한 Web API&lt;/b&gt;가 존재합니다.&lt;/li&gt;
&lt;li data-end=&quot;507&quot; data-start=&quot;464&quot;&gt;하지만 V8은 오직 &lt;b&gt;JavaScript 코드 실행만 담당&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li data-end=&quot;580&quot; data-start=&quot;508&quot;&gt;이 &lt;b&gt;독립성&lt;/b&gt; 덕분에 브라우저 밖에서도 V8을 활용할 수 있었고,&lt;br /&gt;바로 그 결과물이 &lt;b&gt;Node.js&lt;/b&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;608&quot; data-start=&quot;587&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;608&quot; data-start=&quot;587&quot; data-ke-size=&quot;size23&quot;&gt;3.   Node.js와 V8&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;789&quot; data-start=&quot;609&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;652&quot; data-start=&quot;609&quot;&gt;&lt;b&gt;2009년&lt;/b&gt; Node.js가 만들어질 때, 엔진으로 V8이 선택됨&lt;/li&gt;
&lt;li data-end=&quot;718&quot; data-start=&quot;653&quot;&gt;이후:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;718&quot; data-start=&quot;661&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;684&quot; data-start=&quot;661&quot;&gt;  Node.js의 폭발적인 성장&lt;/li&gt;
&lt;li data-end=&quot;718&quot; data-start=&quot;687&quot;&gt;  서버 사이드 JavaScript 생태계 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;789&quot; data-start=&quot;719&quot;&gt;V8은 브라우저 밖에서도 동작할 수 있었기에, &lt;b&gt;Node.js와 Electron 같은 플랫폼의 기반&lt;/b&gt;이 되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;825&quot; data-start=&quot;796&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;825&quot; data-start=&quot;796&quot; data-ke-size=&quot;size23&quot;&gt;4.   브라우저별 JavaScript 엔진&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1007&quot; data-start=&quot;826&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;845&quot; data-start=&quot;826&quot;&gt;Chrome &amp;rarr; &lt;b&gt;V8&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;846&quot;&gt;Firefox &amp;rarr; &lt;b&gt;SpiderMonkey&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;916&quot; data-start=&quot;877&quot;&gt;Safari &amp;rarr; &lt;b&gt;JavaScriptCore (Nitro)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;980&quot; data-start=&quot;917&quot;&gt;Edge
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;980&quot; data-start=&quot;928&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;946&quot; data-start=&quot;928&quot;&gt;과거: &lt;b&gt;Chakra&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;980&quot; data-start=&quot;949&quot;&gt;현재: &lt;b&gt;Chromium 기반 &amp;rarr; V8 사용&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1007&quot; data-start=&quot;981&quot;&gt;그 외: 각 브라우저마다 자체 엔진 보유&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1041&quot; data-start=&quot;1014&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1041&quot; data-start=&quot;1014&quot; data-ke-size=&quot;size23&quot;&gt;5.   브라우저 엔진과 크로스 브라우징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1274&quot; data-start=&quot;1042&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1180&quot; data-start=&quot;1042&quot;&gt;브라우저 엔진 = &lt;b&gt;코드 실행의 핵심&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1180&quot; data-start=&quot;1072&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1131&quot; data-start=&quot;1072&quot;&gt;JavaScript &amp;rarr; JS 엔진 (V8, SpiderMonkey, JavaScriptCore 등)&lt;/li&gt;
&lt;li data-end=&quot;1180&quot; data-start=&quot;1134&quot;&gt;HTML/CSS &amp;rarr; 렌더링 엔진 (Blink, Gecko, WebKit 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1222&quot; data-start=&quot;1181&quot;&gt;문제: 엔진마다 &lt;b&gt;지원 기능, 최적화 방식, 구현 시점이 다름&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1274&quot; data-start=&quot;1223&quot;&gt;결과: 동일한 코드라도 브라우저마다 다르게 동작 &amp;rarr; &lt;b&gt;크로스 브라우징 이슈&lt;/b&gt; 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1281&quot; data-start=&quot;1276&quot; data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1402&quot; data-start=&quot;1282&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1353&quot; data-start=&quot;1282&quot;&gt;Chrome(V8)에서는 async/await이 빠르게 지원 &amp;rarr; Safari(JavaScriptCore)는 늦게 반영&lt;/li&gt;
&lt;li data-end=&quot;1402&quot; data-start=&quot;1354&quot;&gt;CSS grid, flexbox 초창기에는 브라우저별 레이아웃 차이 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1422&quot; data-start=&quot;1409&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1422&quot; data-start=&quot;1409&quot; data-ke-size=&quot;size23&quot;&gt;6.   공통점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1494&quot; data-start=&quot;1423&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1463&quot; data-start=&quot;1423&quot;&gt;모든 엔진은 &lt;b&gt;ECMAScript(ES-262)&lt;/b&gt; 표준을 구현&lt;/li&gt;
&lt;li data-end=&quot;1494&quot; data-start=&quot;1464&quot;&gt;역할: JavaScript 코드를 해석하고 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1520&quot; data-start=&quot;1501&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1520&quot; data-start=&quot;1501&quot; data-ke-size=&quot;size23&quot;&gt;7. ⚡ V8의 성능과 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1686&quot; data-start=&quot;1521&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1547&quot; data-start=&quot;1521&quot;&gt;C++로 작성, &lt;b&gt;지속적 성능 개선&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1587&quot; data-start=&quot;1548&quot;&gt;Mac, Windows, Linux 등 &lt;b&gt;다양한 OS 지원&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1640&quot; data-start=&quot;1588&quot;&gt;Node.js뿐만 아니라 &lt;b&gt;Electron, 서버리스 환경, 데스크탑 앱&lt;/b&gt;에도 활용&lt;/li&gt;
&lt;li data-end=&quot;1686&quot; data-start=&quot;1641&quot;&gt;&lt;b&gt;Just-In-Time(JIT) 컴파일&lt;/b&gt;을 통해 빠른 실행 속도 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1056&quot; data-start=&quot;1031&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-end=&quot;132&quot; data-start=&quot;108&quot; data-ke-size=&quot;size26&quot;&gt;JavaScript 컴파일과 JIT&lt;/h2&gt;
&lt;h3 data-end=&quot;165&quot; data-start=&quot;134&quot; data-ke-size=&quot;size23&quot;&gt;1. 전통적인 JavaScript 실행 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;261&quot; data-start=&quot;166&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;212&quot; data-start=&quot;166&quot;&gt;과거에는 &lt;b&gt;인터프리터 언어&lt;/b&gt;로 분류 &amp;rarr; 코드를 한 줄씩 읽고 곧바로 실행&lt;/li&gt;
&lt;li data-end=&quot;232&quot; data-start=&quot;213&quot;&gt;장점: 실행이 빠르게 시작됨&lt;/li&gt;
&lt;li data-end=&quot;261&quot; data-start=&quot;233&quot;&gt;단점: 실행 속도가 느리고, 최적화가 부족함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;298&quot; data-start=&quot;268&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;298&quot; data-start=&quot;268&quot; data-ke-size=&quot;size23&quot;&gt;2. 현대 JavaScript 엔진의 변화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;407&quot; data-start=&quot;299&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;342&quot; data-start=&quot;299&quot;&gt;현대 엔진(V8, SpiderMonkey 등)은 단순 해석만 하지 않음&lt;/li&gt;
&lt;li data-end=&quot;375&quot; data-start=&quot;343&quot;&gt;&lt;b&gt;컴파일 과정&lt;/b&gt;을 도입해 실행 속도를 크게 개선&lt;/li&gt;
&lt;li data-end=&quot;407&quot; data-start=&quot;376&quot;&gt;즉, &amp;ldquo;&lt;b&gt;인터프리터 + 컴파일러&lt;/b&gt; 혼합 구조&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;445&quot; data-start=&quot;414&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;445&quot; data-start=&quot;414&quot; data-ke-size=&quot;size23&quot;&gt;3. JIT(Just-In-Time) 컴파일&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;615&quot; data-start=&quot;446&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;500&quot; data-start=&quot;446&quot;&gt;&lt;b&gt;정의&lt;/b&gt;: 프로그램 실행 도중, 필요한 시점(Just In Time)에 기계어로 컴파일&lt;/li&gt;
&lt;li data-end=&quot;574&quot; data-start=&quot;501&quot;&gt;특징:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;574&quot; data-start=&quot;511&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;543&quot; data-start=&quot;511&quot;&gt;자주 실행되는 코드는 &lt;b&gt;최적화된 기계어&lt;/b&gt;로 변환&lt;/li&gt;
&lt;li data-end=&quot;574&quot; data-start=&quot;546&quot;&gt;불필요한 코드는 굳이 컴파일하지 않아 효율적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;575&quot;&gt;결과: 브라우저에서도 &lt;b&gt;네이티브 애플리케이션 수준 성능&lt;/b&gt; 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;646&quot; data-start=&quot;622&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;646&quot; data-start=&quot;622&quot; data-ke-size=&quot;size23&quot;&gt;4. JIT 덕분에 가능한 것들&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;766&quot; data-start=&quot;647&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;647&quot;&gt;브라우저에서 &lt;b&gt;수 시간 동안 실행되는 복잡한 앱&lt;/b&gt;도 원활히 동작&lt;/li&gt;
&lt;li data-end=&quot;731&quot; data-start=&quot;689&quot;&gt;예: 게임, IDE, 영상 편집기 같은 &lt;b&gt;고성능 웹 애플리케이션&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;766&quot; data-start=&quot;732&quot;&gt;서버 사이드(Node.js)에서도 빠른 실행 환경 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;462&quot; data-start=&quot;417&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;462&quot; data-start=&quot;419&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 호출즉, &amp;ldquo;필요할 때 바로 번역해서 실행&amp;rdquo;하는 방식 &amp;rarr; Just-In-Time&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;415&quot; data-start=&quot;299&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;335&quot; data-start=&quot;299&quot;&gt;코드가 처음 실행될 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;인터프리터처럼 한 줄씩 실행&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;383&quot; data-start=&quot;336&quot;&gt;반복적으로 실행되는 함수나 코드 블록을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;동적으로 최적화하여 기계어로 변환&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;384&quot;&gt;변환된 기계어 코드로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;빠르게 반복 실행 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;462&quot; data-start=&quot;419&quot; data-ke-size=&quot;size16&quot;&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1758075144082&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function sumUpTo(n) {
  let total = 0;
  for (let i = 1; i &amp;lt;= n; i++) {
    total += i;
  }
  return total;
}

// 반복 호출
console.log(sumUpTo(1000000));
console.log(sumUpTo(1000000));
console.log(sumUpTo(1000000));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;첫 번째 호출&lt;br /&gt;console.log(sumUpTo(1000000)); 은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;151&quot; data-start=&quot;117&quot;&gt;엔진이 함수 코드를 &lt;b&gt;인터프리터처럼 한 줄씩 실행&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 최적화되지 않았기 때문에 &lt;b&gt;약간 느릴 수 있음&lt;br /&gt;&lt;br /&gt;두 번째, 세 번째 호출&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;304&quot;&gt;&lt;b&gt;엔진이 &amp;ldquo;이 함수 반복 실행되네?&amp;rdquo; 판단&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;362&quot; data-start=&quot;334&quot;&gt;&lt;b&gt;&lt;b&gt;동적으로 최적화된 기계어 코드로 변환&lt;/b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;392&quot; data-start=&quot;366&quot;&gt;&lt;b&gt;이미 최적화된 코드로 실행 &amp;rarr; 훨씬 빠름&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1211&quot; data-start=&quot;1142&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;96&quot; data-start=&quot;74&quot; data-ke-size=&quot;size23&quot;&gt;  Node.js와 JIT의 관계&lt;/h3&gt;
&lt;h4 data-end=&quot;125&quot; data-start=&quot;98&quot; data-ke-size=&quot;size20&quot;&gt;1. Node.js는 V8 위에서 동작한다&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;249&quot; data-start=&quot;126&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;167&quot; data-start=&quot;126&quot;&gt;Node.js 자체에는 &lt;b&gt;JavaScript 실행 엔진이 없음&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;200&quot; data-start=&quot;168&quot;&gt;대신 &lt;b&gt;Google V8 엔진&lt;/b&gt;을 기반으로 동작&lt;/li&gt;
&lt;li data-end=&quot;249&quot; data-start=&quot;201&quot;&gt;즉, &lt;b&gt;Node.js = (V8 + Node 전용 API + 런타임)&lt;/b&gt; 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;287&quot; data-start=&quot;256&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;287&quot; data-start=&quot;256&quot; data-ke-size=&quot;size20&quot;&gt;2. V8의 JIT 최적화 &amp;rarr; Node.js 성능&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;450&quot; data-start=&quot;288&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;368&quot; data-start=&quot;288&quot;&gt;V8이 JIT을 사용해 코드를 &lt;b&gt;기계어로 컴파일&lt;/b&gt;하기 때문에
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;368&quot; data-start=&quot;330&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;368&quot; data-start=&quot;330&quot;&gt;파일 처리, 네트워크 요청 같은 서버 로직도 빠르게 실행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;450&quot; data-start=&quot;369&quot;&gt;Node.js가 &lt;b&gt;싱글 스레드 + 이벤트 루프 구조&lt;/b&gt;임에도&lt;br /&gt;수많은 요청을 감당할 수 있는 배경에는 V8 JIT의 성능 덕분이 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;473&quot; data-start=&quot;457&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;473&quot; data-start=&quot;457&quot; data-ke-size=&quot;size20&quot;&gt;3. JIT이 없다면?&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;603&quot; data-start=&quot;474&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;528&quot; data-start=&quot;474&quot;&gt;단순 인터프리터였다면 &amp;rarr; Node.js는 &lt;b&gt;고성능 서버 환경&lt;/b&gt;에서 경쟁력이 부족했을 것&lt;/li&gt;
&lt;li data-end=&quot;603&quot; data-start=&quot;529&quot;&gt;하지만 JIT 덕분에 &lt;b&gt;JavaScript = 느리다&lt;/b&gt;라는 고정관념을 깨고,&lt;br /&gt;서버 사이드 개발에도 쓰일 수 있게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;622&quot; data-start=&quot;610&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;622&quot; data-start=&quot;610&quot; data-ke-size=&quot;size20&quot;&gt;4. 실제 영향&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;772&quot; data-start=&quot;623&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;706&quot; data-start=&quot;623&quot;&gt;Node.js가 &lt;b&gt;API 서버, 채팅 서버, 실시간 스트리밍, 마이크로서비스&lt;/b&gt; 등에 활용 가능한 건&lt;br /&gt;&lt;b&gt;V8의 JIT 성능&lt;/b&gt; 덕분&lt;/li&gt;
&lt;li data-end=&quot;772&quot; data-start=&quot;707&quot;&gt;또, JIT 최적화가 계속 발전하면서 &amp;rarr; Node.js도 버전이 올라갈수록 &lt;b&gt;속도 개선 효과&lt;/b&gt;를 함께 누림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1211&quot; data-start=&quot;1142&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발자가 Node.js를 배우면서 V8의 동작 원리를 이해하면,&lt;/p&gt;
&lt;p data-end=&quot;1211&quot; data-start=&quot;1142&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;성능 최적화와 비동기 처리&lt;/b&gt;를 더 잘 이해할 수 있는 큰 장점이 됩니다.  &lt;/p&gt;
&lt;p data-end=&quot;1211&quot; data-start=&quot;1142&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1211&quot; data-start=&quot;1142&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;188&quot; data-start=&quot;133&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;188&quot; data-start=&quot;133&quot; data-ke-size=&quot;size26&quot;&gt;Node.js: 개발 환경(Development)과 운영 환경(Production)의 차이&lt;/h2&gt;
&lt;p data-end=&quot;423&quot; data-start=&quot;291&quot; data-ke-size=&quot;size16&quot;&gt;Node.js 자체는 개발 환경과 운영 환경 간에 특별한 설정 차이가 없습니다.&lt;br /&gt;즉, Node.js는 개발 환경에서 실행하든 운영 환경에서 실행하든 기본 동작은 동일하며, 바로 프로덕션 환경에서도 실행할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;375&quot; data-start=&quot;176&quot; data-ke-size=&quot;size16&quot;&gt;하지만 일부 npm 라이브러리는 NODE_ENV 환경 변수를 참고하여 기본값을 development로 두고, 개발용 기능과 운영용 기능을 구분해 동작합니다.&lt;br /&gt;따라서 운영 환경에서 Node.js 애플리케이션을 실행할 때는, 라이브러리 최적화와 성능 확보를 위해&lt;/p&gt;
&lt;p data-end=&quot;375&quot; data-start=&quot;176&quot; data-ke-size=&quot;size16&quot;&gt;NODE_ENV=production 을 명시적으로 설정하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-end=&quot;423&quot; data-start=&quot;291&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;183&quot; data-start=&quot;128&quot; data-ke-size=&quot;size16&quot;&gt;하지만 여기서 한 가지 주의할 점이 있습니다.&lt;br /&gt;바로 NODE_ENV를 &lt;b&gt;개발용 코드 분기나 조건문에 남용할 경우 발생할 수 있는 문제&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;183&quot; data-start=&quot;128&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;운영 환경에서 단순히 NODE_ENV만을 기준으로 기능을 켜고 끄면, 테스트 신뢰성이나 코드 안정성에 예상치 못한 영향을 줄 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;292&quot; data-start=&quot;231&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이제부터는 &lt;b&gt;NODE_ENV를 사용할 때 발생할 수 있는 위험과 올바른 활용법&lt;/b&gt;을 살펴보겠습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;292&quot; data-start=&quot;231&quot; data-ke-style=&quot;style2&quot;&gt;보통 프로젝트에서는 두 가지 방식으로 개발 환경과 운영 환경을 구분합니다.&lt;br /&gt;&lt;br /&gt;1️⃣ .env 파일에서 상수를 정의하여 환경별 설정값을 관리하는 경우&lt;br /&gt;2️⃣ NODE_ENV를 활용하여 코드 자체에서 실행 환경을 나누고, 개발용 코드와 운영용 코드를 분기하는 경우&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-17 오전 11.25.22.png&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pcIEI/btsQArNLJU6/SfTgbUxd3UONbqh3b5x091/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pcIEI/btsQArNLJU6/SfTgbUxd3UONbqh3b5x091/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pcIEI/btsQArNLJU6/SfTgbUxd3UONbqh3b5x091/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpcIEI%2FbtsQArNLJU6%2FSfTgbUxd3UONbqh3b5x091%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;1596&quot; height=&quot;302&quot; data-filename=&quot;스크린샷 2025-09-17 오전 11.25.22.png&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;67&quot; data-start=&quot;49&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NODE_ENV와 안티패턴&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;67&quot; data-start=&quot;49&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;69&quot; data-ke-size=&quot;size16&quot;&gt;앞서 살펴본 것처럼, NODE_ENV는 코드 실행/포함 분기와 라이브러리 최적화를 위해 사용됩니다.&lt;br /&gt;하지만 &lt;b&gt;NODE_ENV를 남용하면 안티패턴(Anti-pattern)이 될 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-end=&quot;203&quot; data-start=&quot;187&quot; data-ke-size=&quot;size20&quot;&gt;왜 안티패턴이 될까?&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;276&quot; data-start=&quot;204&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;204&quot;&gt;개발용 코드와 운영용 코드가 &lt;b&gt;NODE_ENV 조건문에 직접 의존&lt;/b&gt;하면, 환경별 테스트 신뢰성이 떨어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758068167209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (process.env.NODE_ENV === 'development') {
  // 개발용 기능
}
if (process.env.NODE_ENV === 'production') {
  // 운영용 기능
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;473&quot; data-start=&quot;406&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;473&quot; data-start=&quot;406&quot;&gt;이런 방식은 운영 환경에서 기능이 제대로 동작하는지 테스트하기 어렵고, 코드 유지보수 시 혼동을 줄 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;485&quot; data-start=&quot;475&quot; data-ke-size=&quot;size20&quot;&gt;권장 방식&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;655&quot; data-start=&quot;486&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;533&quot; data-start=&quot;486&quot;&gt;&lt;b&gt;환경별 값&lt;/b&gt;은 .env 파일로 분리 &amp;rarr; Configuration 관리&lt;/li&gt;
&lt;li data-end=&quot;600&quot; data-start=&quot;534&quot;&gt;&lt;b&gt;개발용 코드/디버깅 코드&lt;/b&gt;는 NODE_ENV로 분기 &amp;rarr; Behavior &amp;amp; Optimization 관리&lt;/li&gt;
&lt;li data-end=&quot;655&quot; data-start=&quot;601&quot;&gt;핵심 비즈니스 로직은 &lt;b&gt;NODE_ENV에 의존하지 않고&lt;/b&gt; 기능 플래그나 설정값으로 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;761&quot; data-start=&quot;657&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;664&quot; data-start=&quot;659&quot; data-ke-size=&quot;size16&quot;&gt;요약:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;761&quot; data-start=&quot;667&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;687&quot; data-start=&quot;667&quot;&gt;.env &amp;rarr; 값/설정 분기&lt;/li&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;690&quot;&gt;NODE_ENV &amp;rarr; 코드 실행/최적화 분기&lt;/li&gt;
&lt;li data-end=&quot;761&quot; data-start=&quot;722&quot;&gt;NODE_ENV를 코드 로직 분기용으로 남용 X &amp;rarr; 안티패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;612&quot; data-start=&quot;565&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;612&quot; data-start=&quot;565&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;612&quot; data-start=&quot;565&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;단순 디버거용 코드를 개발기에서만 해보고 싶을 경우,&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1123&quot; data-start=&quot;1060&quot; data-ke-size=&quot;size16&quot;&gt;단순 &lt;b&gt;디버그용 코드나 오류 검사용 코드&lt;/b&gt;는&lt;/p&gt;
&lt;p data-end=&quot;1123&quot; data-start=&quot;1060&quot; data-ke-size=&quot;size16&quot;&gt;.env 상수보다 process.env.NODE_ENV === 'development'로 분기하는 게 낫다고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;155&quot; data-start=&quot;135&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;155&quot; data-start=&quot;135&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;361&quot; data-start=&quot;156&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;272&quot; data-start=&quot;156&quot;&gt;개발용 로그나 DevTools 초기화 코드를 NODE_ENV 조건문으로 감싸면,&lt;br /&gt;운영 빌드(NODE_ENV=production) 시 Webpack 등 번들러가 &lt;b&gt;코드를 아예 제거&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li data-end=&quot;361&quot; data-start=&quot;273&quot;&gt;.env 상수로 DEBUG=true/false를 쓰면 런타임에서 조건문을 평가하게 되어, 코드 자체는 번들에 남아 있어 &lt;b&gt;최적화가 제한&lt;/b&gt;됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758068719073&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 권장: NODE_ENV 분기
if (process.env.NODE_ENV === 'development') {
  console.log(&quot;개발용 로그&quot;); // 운영 빌드에서 제거 가능
}

// 비권장: .env 상수
if (config.debug) {
  console.log(&quot;개발용 로그&quot;); // 운영 빌드에 남음
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;560&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;560&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;693&quot; data-start=&quot;580&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;637&quot; data-start=&quot;580&quot;&gt;NODE_ENV 분기는 &lt;b&gt;환경 자체를 기준&lt;/b&gt;으로 하므로, 운영 환경에서는 절대 실행되지 않음&lt;/li&gt;
&lt;li data-end=&quot;693&quot; data-start=&quot;638&quot;&gt;반대로 .env 상수는 설정 실수로 DEBUG=true가 운영 환경에서도 적용될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;716&quot; data-start=&quot;695&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;821&quot; data-start=&quot;717&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;767&quot; data-start=&quot;717&quot;&gt;대부분의 라이브러리와 프레임워크가 개발/운영 분기를 NODE_ENV 기준으로 최적화&lt;/li&gt;
&lt;li data-end=&quot;821&quot; data-start=&quot;768&quot;&gt;React, Vue, Express 등에서 NODE_ENV 조건 분기 사용 예제 다수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그럼 만약 신규 기능 로직 등을 개발기 환경에만 적용하고 싶은경우는?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상황에 맞게 &lt;b&gt;적절히 선택하거나 필요에 따라 같이 사용&lt;/b&gt;하는 것이 안전하고 실무에서 권장되는 방법.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, NODE_ENV만 쓰는 경우&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;202&quot; data-end=&quot;230&quot;&gt;✅ 장점: 운영 환경에서 절대 실행되지 않음&lt;/li&gt;
&lt;li data-start=&quot;231&quot; data-end=&quot;286&quot;&gt;❌ 단점: 기능이 개발용인지 운영용인지 판단하기 어렵고, 기능 켜고 끄는 세밀한 제어가 힘듦&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758076751750&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (process.env.NODE_ENV === 'development') {
  newFeature(); // 개발 환경에서만 실행
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능 플래그를 활용하는 경우 (권장)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ 장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;693&quot; data-end=&quot;785&quot;&gt;
&lt;li data-start=&quot;693&quot; data-end=&quot;718&quot;&gt;개발 환경에서 기능을 자유롭게 테스트 가능&lt;/li&gt;
&lt;li data-start=&quot;721&quot; data-end=&quot;749&quot;&gt;운영 환경에서는 절대 실행되지 않아 안정성 확보&lt;/li&gt;
&lt;li data-start=&quot;752&quot; data-end=&quot;785&quot;&gt;배포 준비 시 플래그만 변경하면 바로 운영 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1758072804676&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//.env.development
FEATURE_NEW=true

//.env.production
FEATURE_NEW=false&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758072841875&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// config.js
export const config = {
  newDashboard: process.env.FEATURE_NEW_DASHBOARD === 'true',
};&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758072851756&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { config } from './config.js';

if (config.newDashboard) {
  newFeature(); // 개발 환경에서만 실행, 운영 환경에서는 실행되지 않음
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;90&quot; data-start=&quot;63&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-end=&quot;163&quot; data-start=&quot;126&quot; data-ke-size=&quot;size23&quot;&gt;NODE_ENV로 라이브러리 성능 최적화 및 운영용 번들 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NODE_ENV는 &lt;b&gt;라이브러리와 프레임워크의 최적화 동작&lt;/b&gt;에 직접적인 영향을 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;165&quot; data-ke-size=&quot;size16&quot;&gt;Node.js와 프론트엔드 프로젝트를 운영할 때,&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;165&quot; data-ke-size=&quot;size16&quot;&gt;NODE_ENV는 &lt;b&gt;라이브러리와 프레임워크가 개발용 기능과 운영용 기능을 구분하도록 하는 핵심&lt;/b&gt;입니다.&lt;br /&gt;하지만 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;코드 분기를 위한 용도가 아니라,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;라이브러리 내부 동작을 최적화&lt;/b&gt;할 때도 사용됩니다.&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;165&quot; data-ke-size=&quot;size16&quot;&gt;이 설정 하나만으로 실제 성능과 번들 크기에도 큰 영향을 줄 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;165&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;57&quot; data-start=&quot;30&quot; data-ke-size=&quot;size18&quot;&gt;NODE_ENV가 성능 최적화에 좋은 이유&lt;/p&gt;
&lt;p data-end=&quot;90&quot; data-start=&quot;59&quot; data-ke-size=&quot;size16&quot;&gt;1️⃣ &lt;b&gt;개발용 코드와 운영용 코드를 분리 가능&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;330&quot; data-start=&quot;91&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;166&quot; data-start=&quot;91&quot;&gt;라이브러리나 프레임워크는 NODE_ENV 값에 따라 &lt;b&gt;개발용 기능과 운영용 기능&lt;/b&gt;을 다르게 동작하도록 설계되어 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;167&quot;&gt;예시: React
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;330&quot; data-start=&quot;181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;249&quot; data-start=&quot;181&quot;&gt;NODE_ENV=development &amp;rarr; 디버그용 경고 메시지, PropTypes 검증, 상세 오류 메시지 출력&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;252&quot;&gt;NODE_ENV=production &amp;rarr; 디버그 메시지 제거, PropTypes 검증 비활성화 &amp;rarr; 번들 크기 축소, 실행 속도 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;370&quot; data-start=&quot;332&quot; data-ke-size=&quot;size16&quot;&gt;2️⃣ &lt;b&gt;불필요한 코드 제거 (Tree-shaking 가능)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;456&quot; data-start=&quot;371&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;456&quot; data-start=&quot;371&quot;&gt;번들러(Webpack, Vite 등)는 process.env.NODE_ENV 조건문을 보고 &lt;b&gt;개발 전용 코드를 운영 빌드에서 제거&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li data-end=&quot;456&quot; data-start=&quot;371&quot;&gt;결과: 번들 크기 축소, 로딩 속도 향상, 불필요한 코드 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;616&quot; data-start=&quot;593&quot; data-ke-size=&quot;size16&quot;&gt;3️⃣ &lt;b&gt;환경별 최적화 자동 적용&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;729&quot; data-start=&quot;617&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;617&quot;&gt;라이브러리들은 운영 환경에서는 불필요한 연산이나 체크를 비활성화하고, 개발 환경에서는 디버깅과 안전성을 강화합니다.&lt;/li&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;686&quot;&gt;즉, 개발 시 편리함을 유지하면서 운영에서는 성능을 극대화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;750&quot; data-start=&quot;731&quot; data-ke-size=&quot;size16&quot;&gt;4️⃣ &lt;b&gt;안정적 배포 지원&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;861&quot; data-start=&quot;751&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;832&quot; data-start=&quot;751&quot;&gt;운영 환경에서는 항상 NODE_ENV=production을 설정하여 &lt;b&gt;라이브러리가 최적화된 상태&lt;/b&gt;로 실행되도록 강제할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;861&quot; data-start=&quot;833&quot;&gt;이로 인해 예측 가능한 성능과 일관된 동작 보장&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;h2 data-end=&quot;84&quot; data-start=&quot;50&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;84&quot; data-start=&quot;50&quot; data-ke-size=&quot;size26&quot;&gt;  운영용 번들 생성 (Production Build)&lt;/h2&gt;
&lt;p data-end=&quot;181&quot; data-start=&quot;86&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발에서는 &lt;b&gt;개발 환경&lt;/b&gt;과 &lt;b&gt;운영 환경&lt;/b&gt;에서 필요한 코드와 설정이 다릅니다.&lt;br /&gt;운영 환경에서는 &lt;b&gt;최적화된 번들&lt;/b&gt;을 만들어 배포하는 것이 중요합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;204&quot; data-start=&quot;183&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ 운영 번들이 필요한 이유&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;373&quot; data-start=&quot;205&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;267&quot; data-start=&quot;205&quot;&gt;개발 환경에서는 &lt;b&gt;디버그용 로그, PropTypes, 상세 오류 메시지&lt;/b&gt; 등 디버깅용 코드가 포함됩니다.&lt;/li&gt;
&lt;li data-end=&quot;328&quot; data-start=&quot;268&quot;&gt;이런 코드는 운영 환경에서는 &lt;b&gt;불필요&lt;/b&gt;하며, 그대로 두면 번들 크기가 커지고 실행 속도가 느려집니다.&lt;/li&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;329&quot;&gt;따라서 &lt;b&gt;개발용 코드 제거, 압축, 최적화&lt;/b&gt;를 거쳐야 성능이 향상됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;394&quot; data-start=&quot;375&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ NODE_ENV 활용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;589&quot; data-start=&quot;395&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;474&quot; data-start=&quot;395&quot;&gt;번들을 생성할 때 NODE_ENV=production을 설정하면, 라이브러리와 프레임워크가 &lt;b&gt;운영 환경 최적화 모드&lt;/b&gt;로 동작합니다.&lt;br /&gt;운영 환경 최적화 모드(Production Mode)란?&lt;br /&gt;&lt;b&gt;운영 환경 최적화 모드&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;는 말 그대로 &lt;/span&gt;&lt;b&gt;배포된 서비스에서 성능을 최대한 끌어올리기 위해 라이브러리와 번들이 동작하는 방식&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;을 뜻합니다. &lt;/span&gt;프론트엔드 라이브러리(예: React, Vue)나 Node.js 패키지들은 &lt;b&gt;개발 환경과 운영 환경에서 다른 동작&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;을 하도록 설계되어 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;이제 어느 정도 node.js에 대해 알아보았으니 npm 에 대해서 알아볼께요.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;327&quot; data-start=&quot;309&quot; data-ke-size=&quot;size23&quot;&gt;npm의 기본 역할&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;536&quot; data-start=&quot;329&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;385&quot; data-start=&quot;329&quot;&gt;&lt;b&gt;패키지 관리&lt;/b&gt;: 프로젝트에서 필요한 라이브러리, 모듈, 프레임워크를 설치하고 버전을 관리&lt;/li&gt;
&lt;li data-end=&quot;464&quot; data-start=&quot;386&quot;&gt;&lt;b&gt;프로젝트 실행 환경 구성&lt;/b&gt;: npm install 한 번이면 수많은 라이브러리를 설치하고 프로젝트가 실행 가능한 상태로 세팅&lt;/li&gt;
&lt;li data-end=&quot;536&quot; data-start=&quot;465&quot;&gt;&lt;b&gt;스크립트 관리&lt;/b&gt;: package.json에 등록한 명령어(npm run build, npm start) 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;238&quot; data-start=&quot;220&quot; data-ke-size=&quot;size23&quot;&gt;npm의 주요 기능&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;612&quot; data-start=&quot;240&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;240&quot;&gt;&lt;b&gt;패키지 저장소(레지스트리)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;348&quot; data-start=&quot;267&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;306&quot; data-start=&quot;267&quot;&gt;수많은 오픈소스 자바스크립트 패키지가 등록된 온라인 데이터베이스&lt;/li&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;310&quot;&gt;필요한 기능을 검색하고 다운로드하여 프로젝트에 바로 활용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;501&quot; data-start=&quot;350&quot;&gt;&lt;b&gt;명령줄 인터페이스(CLI)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;501&quot; data-start=&quot;377&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;465&quot; data-start=&quot;377&quot;&gt;npm install [패키지 이름], npm update, npm uninstall 등 명령어를 통해 패키지를 쉽게 설치, 업데이트, 삭제&lt;/li&gt;
&lt;li data-end=&quot;501&quot; data-start=&quot;469&quot;&gt;터미널에서 바로 프로젝트에 패키지를 추가하거나 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;612&quot; data-start=&quot;503&quot;&gt;&lt;b&gt;의존성 관리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;612&quot; data-start=&quot;522&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;569&quot; data-start=&quot;522&quot;&gt;프로젝트에 필요한 패키지 목록과 버전을 package.json 파일에 기록&lt;/li&gt;
&lt;li data-end=&quot;612&quot; data-start=&quot;573&quot;&gt;다른 개발자와 협업하거나 프로젝트 배포 시 의존성을 손쉽게 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;639&quot; data-start=&quot;619&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;639&quot; data-start=&quot;619&quot; data-ke-size=&quot;size23&quot;&gt;npm과 Node.js의 관계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;869&quot; data-start=&quot;713&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;759&quot; data-start=&quot;713&quot;&gt;&lt;b&gt;Node.js&lt;/b&gt;: JavaScript 런타임, 서버 사이드 코드를 실행&lt;/li&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;760&quot;&gt;&lt;b&gt;npm&lt;/b&gt;: Node.js 프로젝트에서 필요한 라이브러리를 쉽게 설치하고 관리하는 도구&lt;/li&gt;
&lt;li data-end=&quot;869&quot; data-start=&quot;815&quot;&gt;즉, npm 없이는 Node.js 기반 프로젝트의 라이브러리 의존성을 관리하기 어렵습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;639&quot; data-start=&quot;619&quot; data-ke-size=&quot;size23&quot;&gt;npm을 사용하는 이유&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;794&quot; data-start=&quot;641&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;689&quot; data-start=&quot;641&quot;&gt;&lt;b&gt;개발 시간 단축&lt;/b&gt;: 이미 만들어진 패키지를 활용해 복잡한 기능을 쉽게 구현&lt;/li&gt;
&lt;li data-end=&quot;744&quot; data-start=&quot;690&quot;&gt;&lt;b&gt;관리 효율성 향상&lt;/b&gt;: 여러 패키지를 package.json 하나로 통합 관리 가능&lt;/li&gt;
&lt;li data-end=&quot;794&quot; data-start=&quot;745&quot;&gt;&lt;b&gt;생태계 공유&lt;/b&gt;: 전 세계 개발자들이 패키지를 공유하는 오픈소스 생태계의 중심&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;npm 주요 명령어&lt;/h2&gt;
&lt;h3 data-end=&quot;84&quot; data-start=&quot;72&quot; data-ke-size=&quot;size23&quot;&gt;⚡ 패키지 설치&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;345&quot; data-start=&quot;85&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;142&quot; data-start=&quot;85&quot;&gt;npm install &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 특정 패키지를 설치하고 node_modules에 저장&lt;/li&gt;
&lt;li data-end=&quot;192&quot; data-start=&quot;143&quot;&gt;npm install &lt;br /&gt;&amp;rarr; package.json에 정의된 모든 의존성 설치&lt;/li&gt;
&lt;li data-end=&quot;260&quot; data-start=&quot;193&quot;&gt;npm install &amp;lt;패키지&amp;gt; --save-dev &lt;br /&gt;&amp;rarr; 개발용 패키지 설치 (devDependencies)&lt;/li&gt;
&lt;li data-end=&quot;312&quot; data-start=&quot;261&quot;&gt;npm install -g &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 글로벌 설치, 터미널 어디서든 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;345&quot; data-start=&quot;313&quot;&gt;npx &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 설치 없이 바로 실행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;372&quot; data-start=&quot;352&quot; data-ke-size=&quot;size23&quot;&gt;  패키지 제거 및 업데이트&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;499&quot; data-start=&quot;373&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;411&quot; data-start=&quot;373&quot;&gt;npm uninstall &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 설치된 패키지 제거&lt;/li&gt;
&lt;li data-end=&quot;457&quot; data-start=&quot;412&quot;&gt;npm update &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 특정 패키지를 최신 버전으로 업데이트&lt;/li&gt;
&lt;li data-end=&quot;499&quot; data-start=&quot;458&quot;&gt;npm outdated &lt;br /&gt;&amp;rarr; 설치된 패키지 버전과 최신 버전 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;521&quot; data-start=&quot;506&quot; data-ke-size=&quot;size23&quot;&gt;  프로젝트 초기화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;600&quot; data-start=&quot;522&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;566&quot; data-start=&quot;522&quot;&gt;npm init &lt;br /&gt;&amp;rarr; 프로젝트 초기화, package.json 생성&lt;/li&gt;
&lt;li data-end=&quot;600&quot; data-start=&quot;567&quot;&gt;npm init -y &lt;br /&gt;&amp;rarr; 기본값으로 빠르게 초기화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;623&quot; data-start=&quot;607&quot; data-ke-size=&quot;size23&quot;&gt;  패키지 정보 조회&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;743&quot; data-start=&quot;624&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;668&quot; data-start=&quot;624&quot;&gt;npm view &amp;lt;패키지&amp;gt; &lt;br /&gt;&amp;rarr; 패키지 정보 조회 (버전, 의존성 등)&lt;/li&gt;
&lt;li data-end=&quot;699&quot; data-start=&quot;669&quot;&gt;npm list &lt;br /&gt;&amp;rarr; 설치된 패키지 트리 확인&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;700&quot;&gt;npm list -g --depth=0 &lt;br /&gt;&amp;rarr; 글로벌 설치 패키지 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;764&quot; data-start=&quot;750&quot; data-ke-size=&quot;size23&quot;&gt;  스크립트 실행&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;958&quot; data-start=&quot;765&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;815&quot; data-start=&quot;765&quot;&gt;npm run &amp;lt;스크립트명&amp;gt; &lt;br /&gt;&amp;rarr; package.json의 scripts 실행&lt;/li&gt;
&lt;li data-end=&quot;865&quot; data-start=&quot;816&quot;&gt;npm start &lt;br /&gt;&amp;rarr; 앱 시작용 스크립트 실행 (npm run start)&lt;/li&gt;
&lt;li data-end=&quot;911&quot; data-start=&quot;866&quot;&gt;npm test &lt;br /&gt;&amp;rarr; 테스트 스크립트 실행 (npm run test)&lt;/li&gt;
&lt;li data-end=&quot;958&quot; data-start=&quot;912&quot;&gt;npm build &lt;br /&gt;&amp;rarr; 빌드 스크립트 실행 (npm run build)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;981&quot; data-start=&quot;965&quot; data-ke-size=&quot;size23&quot;&gt;  패키지 캐시 관리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1059&quot; data-start=&quot;982&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1024&quot; data-start=&quot;982&quot;&gt;npm cache clean --force &lt;br /&gt;&amp;rarr; npm 캐시 초기화&lt;/li&gt;
&lt;li data-end=&quot;1059&quot; data-start=&quot;1025&quot;&gt;npm cache verify &lt;br /&gt;&amp;rarr; 캐시 무결성 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 로그/오늘의 개발읽기</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/94</guid>
      <comments>https://jjung2ing.tistory.com/94#entry94comment</comments>
      <pubDate>Wed, 17 Sep 2025 12:58:12 +0900</pubDate>
    </item>
    <item>
      <title>[개발읽기 vol.9] 클라우드 아키텍처 진화: 모놀리식에서 MSA까지 완벽 정리</title>
      <link>https://jjung2ing.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 &lt;b&gt;Yarn Berry&lt;/b&gt;랑 &lt;b&gt;pnpm&lt;/b&gt;을 공부하다 보니까, 자연스럽게 모노레포(Monorepo)라는 개념을 알게 되었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;291&quot; data-start=&quot;173&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 단순히 패키지 관리나 프로젝트 구조를 조금 더 효율적으로 만드는 방법 정도로만 생각했는데, 조금 더 깊이 공부해보니 이게 프로젝트 구조뿐만 아니라 &lt;b&gt;전체 아키텍처와도 연결&lt;/b&gt;돼 있다는 걸 깨달았죠.&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;293&quot; data-ke-size=&quot;size16&quot;&gt;모노레포에서 시작해서 점점 &lt;b&gt;서비스 지향 아키텍처(SOA)&lt;/b&gt;, 그리고 MSA(마이크로서비스 아키텍처)까지 아키텍처가 진화하는 과정을 보면서, 단순한 코드 관리 이상의 의미가 있다는 걸 알게 되었어요.&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;293&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;293&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특히 저희 회사도 이미 MSA 구조를 쓰고 있어서, &quot;MSA가 뭔지 모르고 쓰는 건 안 되겠다&quot;는 생각이 들었습니다.&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;293&quot; data-ke-size=&quot;size16&quot;&gt;단순히 백엔드 개발자만 아는 지식이 아니라, 프론트 개발자에게도 꼭 필요한 내용이라는 점이죠.&lt;/p&gt;
&lt;p data-end=&quot;728&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;공부를 이어가면서 서비스별 독립 배포, API 호출 구조, 장애 대응 방식 같은 MSA 요소들을 이해하면, 프론트 개발에서도 훨씬 효율적이고 안정적으로 구현할 수 있다는 걸 깨달았죠.&lt;/p&gt;
&lt;p data-end=&quot;728&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;결국 단순히 패키지를 설치하고 프로젝트를 관리하는 단계에서 시작했지만, 점점 &lt;b&gt;클라우드 아키텍처와 MSA의 중요성&lt;/b&gt;을 몸소 체감하게 되었습니다.&lt;/p&gt;
&lt;p data-end=&quot;728&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;728&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번 글에서는 &lt;b&gt;모노레포부터 MSA까지 아키텍처가 어떻게 진화했는지&lt;/b&gt;, 그리고 각각의 구조가 갖는 의미와 장단점을 쉽게 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;읽으시는 분들께도 도움이 되었으면 좋겠어요.&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;  프론트엔드인데 왜 클라우드 아키텍처를 알아야할까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;83&quot; data-start=&quot;62&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1️⃣ 배포와 운영 이해&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;260&quot; data-start=&quot;84&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;122&quot; data-start=&quot;84&quot;&gt;프론트엔드도 서버/클라우드 환경에서 돌아가는 경우가 많습니다.&lt;/li&gt;
&lt;li data-end=&quot;211&quot; data-start=&quot;123&quot;&gt;정적 파일(HTML, JS, CSS)을 클라우드에 배포할 때, &lt;b&gt;CDN, 서버, 스토리지&lt;/b&gt; 구조를 이해하면 문제 해결과 최적화가 쉬워집니다.&lt;/li&gt;
&lt;li data-end=&quot;260&quot; data-start=&quot;212&quot;&gt;예: AWS S3 + CloudFront로 빠른 페이지 로딩, 트래픽 폭주 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;293&quot; data-start=&quot;267&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2️⃣ MSA와 API 구조 이해&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;478&quot; data-start=&quot;294&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;339&quot; data-start=&quot;294&quot;&gt;현대 클라우드 환경에서 백엔드는 대부분 &lt;b&gt;MSA&lt;/b&gt;로 구성되어 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;478&quot; data-start=&quot;340&quot;&gt;프론트엔드는 &lt;b&gt;여러 마이크로서비스 API&lt;/b&gt;를 호출하게 되는데,
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;478&quot; data-start=&quot;383&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;383&quot;&gt;서비스별 엔드포인트 구조&lt;/li&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;403&quot;&gt;인증/권한 처리&lt;/li&gt;
&lt;li data-end=&quot;478&quot; data-start=&quot;418&quot;&gt;장애 처리 및 fallback 로직&lt;br /&gt;이런 것을 이해하면 &lt;b&gt;효율적 프론트 개발&lt;/b&gt;이 가능해집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;508&quot; data-start=&quot;485&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3️⃣ 확장성과 성능 최적화&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;639&quot; data-start=&quot;509&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;550&quot; data-start=&quot;509&quot;&gt;클라우드 아키텍처를 이해하면, 프론트 성능 최적화가 더 쉬워집니다.&lt;/li&gt;
&lt;li data-end=&quot;639&quot; data-start=&quot;551&quot;&gt;예:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;639&quot; data-start=&quot;560&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;578&quot; data-start=&quot;560&quot;&gt;이미지/동영상 CDN 배포&lt;/li&gt;
&lt;li data-end=&quot;604&quot; data-start=&quot;581&quot;&gt;서버리스 함수와 연동한 프론트 로직&lt;/li&gt;
&lt;li data-end=&quot;639&quot; data-start=&quot;607&quot;&gt;Lazy loading, API throttling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;675&quot; data-start=&quot;646&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4️⃣ DevOps, CI/CD와 연계&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;838&quot; data-start=&quot;676&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;676&quot;&gt;프론트엔드도 요즘은 &lt;b&gt;자동 빌드/배포(CI/CD)&lt;/b&gt; 환경에서 돌아갑니다.&lt;/li&gt;
&lt;li data-end=&quot;838&quot; data-start=&quot;723&quot;&gt;클라우드 아키텍처를 이해하면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;838&quot; data-start=&quot;746&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;761&quot; data-start=&quot;746&quot;&gt;배포 파이프라인 설계&lt;/li&gt;
&lt;li data-end=&quot;793&quot; data-start=&quot;764&quot;&gt;환경별 설정 관리(dev/stage/prod)&lt;/li&gt;
&lt;li data-end=&quot;838&quot; data-start=&quot;796&quot;&gt;에러 추적 및 모니터링&lt;br /&gt;이런 작업을 더 능숙하게 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;870&quot; data-start=&quot;845&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5️⃣ 비즈니스와 팀 협업 이해&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1021&quot; data-start=&quot;871&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;972&quot; data-start=&quot;871&quot;&gt;클라우드 아키텍처를 이해하면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;972&quot; data-start=&quot;894&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;927&quot; data-start=&quot;894&quot;&gt;백엔드, DevOps, 인프라 팀과 원활한 협업 가능&lt;/li&gt;
&lt;li data-end=&quot;972&quot; data-start=&quot;930&quot;&gt;&amp;ldquo;왜 이 API가 느린지?&amp;rdquo;, &amp;ldquo;왜 배포가 오래 걸리는지&amp;rdquo; 이해 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1021&quot; data-start=&quot;973&quot;&gt;결과적으로 프론트엔드 개발자로서 &lt;b&gt;서비스 전체를 이해하는 시야&lt;/b&gt;가 생깁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1028&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1028&quot; data-ke-size=&quot;size16&quot;&gt;  프론트엔드 개발자에게 클라우드 아키텍처 지식은 단순히 서버 지식이 아니라,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1165&quot; data-start=&quot;1082&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1099&quot; data-start=&quot;1082&quot;&gt;&lt;b&gt;API 구조 이해&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1118&quot; data-start=&quot;1100&quot;&gt;&lt;b&gt;배포와 성능 최적화&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1165&quot; data-start=&quot;1119&quot;&gt;&lt;b&gt;팀 협업과 서비스 운영 능력&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;를 높여주는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;필수 역량&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;47&quot; data-start=&quot;28&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;47&quot; data-start=&quot;28&quot; data-ke-size=&quot;size23&quot;&gt;클라우드 아키텍처란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;195&quot; data-start=&quot;48&quot; data-ke-size=&quot;size16&quot;&gt;클라우드 아키텍처(Cloud Architecture)는 인터넷 위에서 서비스가 어떻게 작동할지를 설계하는 방법을 말합니다.&lt;/p&gt;
&lt;p data-end=&quot;195&quot; data-start=&quot;48&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, 누군가 웹사이트에 접속했을 때 페이지가 잘 뜨고, 버튼을 클릭하면 원하는 기능이 실행되며, 데이터가 저장되거나 불러와지도록 앱이나 서비스를 서버, 저장 공간, 네트워크 등에 배치하고 미리 계획한 &lt;b&gt;전체 구조&lt;/b&gt;를 말합니다.&lt;/p&gt;
&lt;hr data-end=&quot;200&quot; data-start=&quot;197&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;215&quot; data-start=&quot;202&quot; data-ke-size=&quot;size23&quot;&gt;핵심 개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 운영 방식은 총 2가지로 나뉩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서버리스(Serverless)&lt;/b&gt; 방식과 &lt;b&gt;서버 기반(Server-based)&lt;/b&gt; 방식 두가지가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 설계의 핵심 특징에는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분산 구조(Distributed) : 여러 서버와 서비스가 서로 통신하며 동작하여 장애가 발생해도 전체 서비스가 멈추지 않도록 설계함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장성(Scalability): 사용자가 늘어나면 자동으로 서버나 리소스를 늘림 &amp;rarr; 클라우드의 큰 장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 설계를 잘해야 사람들이 편리하게 이동하고, 필요할 때 방을 늘리거나 줄일 수 있는 것처럼, 클라우드 아키텍처도 효율적인 서비스 운영을 위해 꼭 필요합니다.&lt;/p&gt;
&lt;p data-end=&quot;826&quot; data-start=&quot;738&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;74&quot; data-start=&quot;57&quot; data-ke-size=&quot;size23&quot;&gt;클라우드 구조 핵심 요소&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;625&quot; data-start=&quot;76&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;130&quot; data-start=&quot;76&quot;&gt;&lt;b&gt;서버(Server) : &lt;/b&gt;실제 애플리케이션을 실행하고 데이터를 처리하는 공간.&lt;/li&gt;
&lt;li data-end=&quot;192&quot; data-start=&quot;132&quot;&gt;&lt;b&gt;네트워크(Network) : &lt;/b&gt;서버, 스토리지, 사용자를 연결하여 데이터와 요청을 전달.&lt;/li&gt;
&lt;li data-end=&quot;246&quot; data-start=&quot;194&quot;&gt;&lt;b&gt;스토리지(Storage) : &lt;/b&gt;데이터를 저장하고 필요할 때 불러오는 공간.&lt;/li&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;248&quot;&gt;&lt;b&gt;애플리케이션(Application) : &lt;/b&gt;사용자가 실제로 이용하는 기능과 서비스.&lt;/li&gt;
&lt;li data-end=&quot;366&quot; data-start=&quot;306&quot;&gt;&lt;b&gt;로드밸런서(Load Balancer) : &lt;/b&gt;여러 서버에 트래픽을 분산하여 과부하를 방지.&lt;/li&gt;
&lt;li data-end=&quot;432&quot; data-start=&quot;368&quot;&gt;&lt;b&gt;자동 확장(Auto Scaling) : &lt;/b&gt;사용량 변화에 따라 서버 수를 자동으로 늘리거나 줄임.&lt;/li&gt;
&lt;li data-end=&quot;480&quot; data-start=&quot;434&quot;&gt;&lt;b&gt;보안(Security) : &lt;/b&gt;데이터와 서비스 보호, 접근 통제.&lt;/li&gt;
&lt;li data-end=&quot;625&quot; data-start=&quot;482&quot;&gt;&lt;b&gt;클라우드 서비스 계층&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;625&quot; data-start=&quot;504&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;540&quot; data-start=&quot;504&quot;&gt;IaaS(인프라): 서버, 스토리지, 네트워크를 직접 구성&lt;/li&gt;
&lt;li data-end=&quot;584&quot; data-start=&quot;543&quot;&gt;PaaS(플랫폼): 애플리케이션 실행 환경 제공, 서버 관리 불필요&lt;/li&gt;
&lt;li data-end=&quot;625&quot; data-start=&quot;587&quot;&gt;SaaS(서비스): 최종 사용자에게 바로 제공되는 애플리케이션&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클라우드 아키텍처의 진화: 모놀리식에서 MSA까지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 환경에서 애플리케이션 아키텍처는 끊임없이 발전해 왔습니다. 오늘은 &lt;b&gt;전통적인 모놀리식(Monolithic) 아키텍처&lt;/b&gt;부터, &lt;b&gt;서비스 지향 아키텍처(SOA)&lt;/b&gt;, 그리고 최신 마이크로서비스 아키텍처(MSA)까지 그 흐름과 특징을 정리해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.40.07.png&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FrUm0/btsQBWr0raN/VUdCjq28VZ3ZU8QUCDjKb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FrUm0/btsQBWr0raN/VUdCjq28VZ3ZU8QUCDjKb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FrUm0/btsQBWr0raN/VUdCjq28VZ3ZU8QUCDjKb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFrUm0%2FbtsQBWr0raN%2FVUdCjq28VZ3ZU8QUCDjKb1%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;1634&quot; height=&quot;920&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.40.07.png&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.42.34.png&quot; data-origin-width=&quot;1608&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dL19xY/btsQzD8XoyA/NBtuAbzCCsyinRbPHDz6u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dL19xY/btsQzD8XoyA/NBtuAbzCCsyinRbPHDz6u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dL19xY/btsQzD8XoyA/NBtuAbzCCsyinRbPHDz6u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdL19xY%2FbtsQzD8XoyA%2FNBtuAbzCCsyinRbPHDz6u1%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;1608&quot; height=&quot;638&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.42.34.png&quot; data-origin-width=&quot;1608&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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-filename=&quot;스크린샷 2025-09-16 오후 2.18.42.png&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;1198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gf097/btsQByrlaCA/czkmaRLUXKjfR9CaEorDD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gf097/btsQByrlaCA/czkmaRLUXKjfR9CaEorDD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gf097/btsQByrlaCA/czkmaRLUXKjfR9CaEorDD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGf097%2FbtsQByrlaCA%2FczkmaRLUXKjfR9CaEorDD0%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;1630&quot; height=&quot;1198&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.18.42.png&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;1198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;284&quot; data-start=&quot;254&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;284&quot; data-start=&quot;254&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  모놀리식(Monolithic) 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.39.21.png&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdSeaD/btsQA3S0Cx8/25AW2Ql39qvEPFWQgcLiA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdSeaD/btsQA3S0Cx8/25AW2Ql39qvEPFWQgcLiA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdSeaD/btsQA3S0Cx8/25AW2Ql39qvEPFWQgcLiA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdSeaD%2FbtsQA3S0Cx8%2F25AW2Ql39qvEPFWQgcLiA1%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;1520&quot; height=&quot;882&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.39.21.png&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;285&quot; data-ke-size=&quot;size16&quot;&gt;모놀리식은 모든 기능을 하나의 애플리케이션에 통합한 구조입니다.&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;285&quot; data-ke-size=&quot;size16&quot;&gt;초기 개발이 간단하고 배포가 단일 단위라 관리가 쉽지만, 서비스가 커질수록 유지보수가 어려워집니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;479&quot; data-end=&quot;574&quot;&gt;
&lt;li data-start=&quot;518&quot; data-end=&quot;574&quot;&gt;&lt;b&gt;저장소:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;일반적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;하나의 저장소&lt;/b&gt;에서 모든 기능 관리 / 작은 프로젝트나 전통적 구조에서는 자연스럽게 하나의 저장소&lt;/li&gt;
&lt;li data-start=&quot;518&quot; data-end=&quot;574&quot;&gt;&lt;b&gt;배포:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;전체 앱 단위&lt;/li&gt;
&lt;li data-start=&quot;518&quot; data-end=&quot;574&quot;&gt;&lt;b&gt;팀 협업:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;작은 팀에 적합, 동시에 여러 기능 개발 시 충돌 가능&lt;/li&gt;
&lt;li data-start=&quot;518&quot; data-end=&quot;574&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;코드 통합, 배포 단순, 작은 변경에도 전체 배포 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757996337181&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[모놀리식 앱]
 ├── 사용자 관리
 ├── 주문 관리
 ├── 결제 관리
 └── 상품 관리
 
프로젝트 구조 (Git 저장소: 1개)
/app
  /login
  /board
  /payment
  /user
server.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;64&quot; data-start=&quot;46&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;64&quot; data-start=&quot;46&quot; data-ke-size=&quot;size16&quot;&gt;1️⃣ 단일 빌드 &amp;amp; 배포&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;190&quot; data-start=&quot;65&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;127&quot; data-start=&quot;65&quot;&gt;프론트엔드가 백엔드와 함께 한 번에 배포됨&lt;br /&gt;(보통 프론트엔드 코드와 백엔드 코드가 &lt;b&gt;같은 프로젝트/깃 저장소&lt;/b&gt; 안에 존재하는 경우가 많음.)&lt;/li&gt;
&lt;li data-end=&quot;127&quot; data-start=&quot;65&quot;&gt;개발자가 서버를 빌드하면 프론트와 백엔드가 동시에 묶여서 배포.&lt;/li&gt;
&lt;li data-end=&quot;127&quot; data-start=&quot;65&quot;&gt;예를 들어, Spring Boot 서버 안에 /static 폴더로 프론트 빌드 결과물이 들어가고, 서버를 띄우면 동시에 프론트와 백엔드가 동작하는 구조입니다.&lt;/li&gt;
&lt;li data-end=&quot;153&quot; data-start=&quot;128&quot;&gt;장점: 배포가 간단하고 버전 관리 용이&lt;/li&gt;
&lt;li data-end=&quot;190&quot; data-start=&quot;154&quot;&gt;단점: 작은 변경에도 전체 애플리케이션을 다시 배포해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;205&quot; data-start=&quot;192&quot; data-ke-size=&quot;size16&quot;&gt;2️⃣ 코드 구조&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;307&quot; data-start=&quot;206&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;232&quot; data-start=&quot;206&quot;&gt;프론트엔드와 백엔드 코드가 통합되어 있음&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;233&quot;&gt;장점: 작은 프로젝트에서는 구조가 단순하고 이해하기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;307&quot; data-start=&quot;269&quot;&gt;단점: 프로젝트가 커지면 코드 의존성이 많아 유지보수가 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;3️⃣ 성능 및 확장&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;402&quot; data-start=&quot;325&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;358&quot; data-start=&quot;325&quot;&gt;특정 페이지만 독립적으로 최적화하거나 확장하기 어려움&lt;/li&gt;
&lt;li data-end=&quot;402&quot; data-start=&quot;359&quot;&gt;프론트 성능 최적화(예: lazy loading, CDN 활용) 제한적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;416&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;4️⃣ 팀 협업&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;468&quot; data-start=&quot;417&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;442&quot; data-start=&quot;417&quot;&gt;동일 코드베이스 공유로 충돌 발생 가능&lt;/li&gt;
&lt;li data-end=&quot;468&quot; data-start=&quot;443&quot;&gt;기능 추가 시 전체 시스템 테스트 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;478&quot; data-start=&quot;470&quot; data-ke-size=&quot;size16&quot;&gt;✅ 요약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;574&quot; data-start=&quot;479&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;517&quot; data-start=&quot;479&quot;&gt;초기 개발 속도가 빠르고 SSR 같은 전통적 구조와 연동 쉬움&lt;/li&gt;
&lt;li data-end=&quot;574&quot; data-start=&quot;518&quot;&gt;코드가 커지면 모듈화 어려움, 배포 주기가 길고 SPA 등 최신 프론트와 결합 시 확장성 제한&lt;/li&gt;
&lt;li data-end=&quot;574&quot; data-start=&quot;518&quot;&gt;단일 애플리케이션이므로 한 기능 수정 시 전체를 배포해야 하는 위험도 존재합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;520&quot; data-start=&quot;495&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  서비스 지향 아키텍처(SOA)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;521&quot; data-ke-size=&quot;size16&quot;&gt;SOA는 기능 단위로 서비스를 나누고, 서비스 간 메시지나 API로 통신하는 구조입니다. 재사용성이 높고 대규모 시스템에 적합하지만, 서비스 간 통신 구조가 복잡해져 유지보수가 쉽지 않습니다. 클라우드 환경에서 SOA는 확장성과 재사용성을 위한 첫 단계로 볼 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;515&quot; data-end=&quot;673&quot;&gt;
&lt;li data-start=&quot;515&quot; data-end=&quot;557&quot;&gt;&lt;b&gt;저장소:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;저장소는 하나로 관리할 수도 있고, 서비스별로 나눌 수도 있음&lt;/li&gt;
&lt;li data-start=&quot;558&quot; data-end=&quot;589&quot;&gt;&lt;b&gt;배포:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;통합 배포 가능 (전체 서버 기준)&lt;/li&gt;
&lt;li data-start=&quot;590&quot; data-end=&quot;624&quot;&gt;&lt;b&gt;팀 협업:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서비스별 개발 가능, 병렬 작업 가능&lt;/li&gt;
&lt;li data-start=&quot;625&quot; data-end=&quot;673&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;기능 단위로 분리, 배포는 아직 전체 단위, 서비스 간 의존 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOA는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서비스 단위로 나누지만 배포는 통합될 수 있는 구조.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  중요한 건&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서비스가 논리적으로 독립적&lt;/b&gt;이라는 점이지, Git 저장소 수는 필수 조건이 아님.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757996369778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[SOA]
 ├── 사용자 서비스 &amp;harr; 주문 서비스
 ├── 결제 서비스 &amp;harr; 상품 서비스
 
프로젝트 구조
/monorepo (Git 저장소 1개 가능)
  /auth-service
  /board-service
  /payment-service
/frontend
server.js (전체 배포)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;273&quot; data-start=&quot;256&quot; data-ke-size=&quot;size16&quot;&gt;1️⃣ 서비스 단위 호출&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;384&quot; data-start=&quot;274&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;343&quot; data-start=&quot;274&quot;&gt;프론트엔드는 단일 백엔드가 아니라 여러 서비스 API 호출 (서비스 단위 &amp;ne; 서버 단위)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 서비스는 반드시 &lt;b&gt;서버가 분리&lt;/b&gt;된다는 뜻이 아니라, &lt;b&gt;API/모듈 단위로 독립적&lt;/b&gt;이라는 의미예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예: 사용자 관리, 주문 처리, 결제 기능이 각각 서비스라고 하면,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;320&quot; data-start=&quot;259&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;289&quot; data-start=&quot;259&quot;&gt;같은 서버 안에서 독립 모듈로 구현할 수도 있고&lt;/li&gt;
&lt;li data-end=&quot;320&quot; data-start=&quot;294&quot;&gt;실제로 다른 서버로 나눌 수도 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;320&quot; data-start=&quot;294&quot;&gt;장점: 필요한 기능만 호출 가능, 백엔드 변경이 프론트에 덜 영향&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** 단일 백엔드란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모놀리식 구조&lt;/b&gt;에서는 보통 &lt;b&gt;프론트엔드가 요청을 보내는 서버가 하나&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 쇼핑몰 앱이 있다고 할 때: 사용자 로그인, 상품 조회, 주문, 결제 기능이 &lt;b&gt;하나의 서버&lt;/b&gt;에서 모두 처리됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 프론트는 항상 이 서버에 요청만 하면 모든 기능을 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;278&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;단일 백엔드 = 프론트가 호출하는 서버가 한 곳뿐&lt;/b&gt;이라는 의미예요.&lt;/p&gt;
&lt;p data-end=&quot;278&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;69&quot; data-start=&quot;52&quot; data-ke-size=&quot;size16&quot;&gt;2️⃣ 독립적 개발 가능&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;141&quot; data-start=&quot;70&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;103&quot; data-start=&quot;70&quot;&gt;각 서비스가 독립적이므로 &lt;b&gt;팀이 병렬 개발 가능&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;141&quot; data-start=&quot;104&quot;&gt;&lt;b&gt;장점:&lt;/b&gt; 기능 추가/수정 시 전체 시스템 영향을 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;162&quot; data-start=&quot;143&quot; data-ke-size=&quot;size20&quot;&gt;예시: 쇼핑몰 서비스 개발&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;379&quot; data-start=&quot;163&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;285&quot; data-start=&quot;163&quot;&gt;&lt;b&gt;서비스 단위 분리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;285&quot; data-start=&quot;185&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;219&quot; data-start=&quot;185&quot;&gt;&lt;b&gt;사용자 서비스:&lt;/b&gt; 회원가입, 로그인, 프로필 관리&lt;/li&gt;
&lt;li data-end=&quot;250&quot; data-start=&quot;223&quot;&gt;&lt;b&gt;주문 서비스:&lt;/b&gt; 상품 주문, 장바구니&lt;/li&gt;
&lt;li data-end=&quot;285&quot; data-start=&quot;254&quot;&gt;&lt;b&gt;결제 서비스:&lt;/b&gt; 결제 처리, 결제 내역 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;379&quot; data-start=&quot;287&quot;&gt;&lt;b&gt;팀 구성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;379&quot; data-start=&quot;304&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;304&quot;&gt;&lt;b&gt;A팀 &amp;rarr; 사용자 서비스 개발&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;353&quot; data-start=&quot;331&quot;&gt;&lt;b&gt;B팀 &amp;rarr; 주문 서비스 개발&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;379&quot; data-start=&quot;357&quot;&gt;&lt;b&gt;C팀 &amp;rarr; 결제 서비스 개발&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;488&quot; data-start=&quot;469&quot; data-ke-size=&quot;size16&quot;&gt;3️⃣ 통신 구조 이해 필요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;315&quot; data-start=&quot;55&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;100&quot; data-start=&quot;55&quot;&gt;프론트는 서비스별 &lt;b&gt;엔드포인트, 인증/권한, 에러 처리&lt;/b&gt;를 이해해야 함&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;101&quot;&gt;&lt;b&gt;인증/권한은 모놀리식에서도 필요&lt;/b&gt;했지만,
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;268&quot; data-start=&quot;136&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;186&quot; data-start=&quot;136&quot;&gt;SOA에서는 서비스가 분리되면서 각 서비스가 독립적으로 인증/권한을 체크할 수 있음&lt;/li&gt;
&lt;li data-end=&quot;232&quot; data-start=&quot;189&quot;&gt;따라서 프론트는 &lt;b&gt;서비스별로 올바른 토큰&amp;middot;권한 정보를 전달&lt;/b&gt;해야 함&lt;/li&gt;
&lt;li data-end=&quot;268&quot; data-start=&quot;235&quot;&gt;인증/권한 처리 로직이 분산되므로 관리가 더 까다로움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;315&quot; data-start=&quot;269&quot;&gt;서비스 간 의존성은 낮지만, &lt;b&gt;네트워크 지연&amp;middot;장애 상황&lt;/b&gt;까지 고려해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;580&quot; data-start=&quot;567&quot; data-ke-size=&quot;size16&quot;&gt;4️⃣ 코드 구조&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;682&quot; data-start=&quot;581&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;635&quot; data-start=&quot;581&quot;&gt;API 호출 많아짐 &amp;rarr; API 관리 모듈, 상태 관리(store/context) 설계 필요&lt;/li&gt;
&lt;li data-end=&quot;653&quot; data-start=&quot;636&quot;&gt;장점: 코드 모듈화 가능&lt;/li&gt;
&lt;li data-end=&quot;682&quot; data-start=&quot;654&quot;&gt;단점: 서비스 수가 많아지면 관리 부담 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;706&quot; data-start=&quot;689&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;713&quot; data-start=&quot;707&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&amp;nbsp;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;792&quot; data-start=&quot;714&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;738&quot; data-start=&quot;714&quot;&gt;대규모 시스템에서도 유연한 확장 가능&lt;/li&gt;
&lt;li data-end=&quot;764&quot; data-start=&quot;739&quot;&gt;API 테스트와 프론트 개발 병행 가능&lt;/li&gt;
&lt;li data-end=&quot;792&quot; data-start=&quot;765&quot;&gt;MSA 이전, 서비스 단위 사고에 익숙해짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;800&quot; data-start=&quot;794&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&amp;nbsp;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;876&quot; data-start=&quot;801&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;832&quot; data-start=&quot;801&quot;&gt;서비스별 API 호출 증가 &amp;rarr; 네트워크 비용 상승&lt;/li&gt;
&lt;li data-end=&quot;852&quot; data-start=&quot;833&quot;&gt;서비스 상태 통합 관리 필요&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;853&quot;&gt;초기 설계가 복잡, 러닝 커브 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;767&quot; data-start=&quot;741&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 마이크로서비스 아키텍처(MSA)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.40.43.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1OCNF/btsQAPmSfoT/SbkkyuVkcpSi3GCRyM6zpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1OCNF/btsQAPmSfoT/SbkkyuVkcpSi3GCRyM6zpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1OCNF/btsQAPmSfoT/SbkkyuVkcpSi3GCRyM6zpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1OCNF%2FbtsQAPmSfoT%2FSbkkyuVkcpSi3GCRyM6zpK%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;1526&quot; height=&quot;908&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.40.43.png&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;902&quot; data-start=&quot;768&quot; data-ke-size=&quot;size16&quot;&gt;MSA는 작은 단위의 서비스로 애플리케이션을 분리하고, 각 서비스는 독립적으로 배포됩니다. 컨테이너(Docker)와 오케스트레이션(Kubernetes)와 같은 클라우드 기술과 결합하면 빠른 배포와 유연한 확장이 가능합니다.&lt;/p&gt;
&lt;p data-end=&quot;902&quot; data-start=&quot;768&quot; data-ke-size=&quot;size16&quot;&gt;MSA는 개발 효율성, 안정성, 비용 최적화를 동시에 잡을 수 있지만, 서비스 간 통신과 데이터 관리, 모니터링 체계가 필수적입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-start=&quot;877&quot; data-end=&quot;897&quot;&gt;&lt;b&gt;저장소:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서비스별 독립. 보통&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서비스별 저장소&lt;/b&gt;를 가지는 경우가 많음&lt;/li&gt;
&lt;li data-start=&quot;898&quot; data-end=&quot;922&quot;&gt;&lt;b&gt;배포:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서비스 단위 완전 독립&lt;/li&gt;
&lt;li data-start=&quot;923&quot; data-end=&quot;957&quot;&gt;&lt;b&gt;팀 협업:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;서비스 단위 담당 &amp;rarr; 팀별 배포 가능&lt;/li&gt;
&lt;li data-start=&quot;958&quot; data-end=&quot;996&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;독립적 배포, 확장성 뛰어남, 장애 영향 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.41.16.png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baAViP/btsQBvnUxYg/Rv49T9dAxITgIPc6Egqcx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baAViP/btsQBvnUxYg/Rv49T9dAxITgIPc6Egqcx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baAViP/btsQBvnUxYg/Rv49T9dAxITgIPc6Egqcx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaAViP%2FbtsQBvnUxYg%2FRv49T9dAxITgIPc6Egqcx1%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;1606&quot; height=&quot;754&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.41.16.png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;MSA는 서비스 단위가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;완전히 독립적 배포&lt;/b&gt;를 전제로 함.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나 기술적으로는 하나의 저장소(monorepo)에서도 MSA처럼 독립 서비스 개발 가능 &amp;rarr; 단지 배포와 관리가 복잡해짐&lt;/p&gt;
&lt;pre id=&quot;code_1757996405649&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[MSA]
 ├── 사용자 서비스 &amp;rarr; 독립 컨테이너
 ├── 주문 서비스 &amp;rarr; 독립 컨테이너
 ├── 결제 서비스 &amp;rarr; 독립 컨테이너
 └── 상품 서비스 &amp;rarr; 독립 컨테이너
 
 
프로젝트 구조 (Git 저장소 서비스별 독립)
auth-service/  (Git repo A)
board-service/  (Git repo B)
payment-service/  (Git repo C)
frontend/      (Git repo D)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣ &lt;b&gt;독립적 배포&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;429&quot; data-start=&quot;340&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;365&quot; data-start=&quot;340&quot;&gt;서비스별 API 호출을 통해 기능 구성&lt;/li&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;366&quot;&gt;특정 서비스 업데이트가 다른 서비스에 영향 없음&lt;/li&gt;
&lt;li data-end=&quot;429&quot; data-start=&quot;397&quot;&gt;✅ 작은 변경도 개별 배포 가능 &amp;rarr; 배포 주기 단축&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;450&quot; data-start=&quot;431&quot; data-ke-size=&quot;size16&quot;&gt;2️⃣ &lt;b&gt;API 중심 개발&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;561&quot; data-start=&quot;451&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;492&quot; data-start=&quot;451&quot;&gt;프론트는 서비스별 API 계약(API contract)에 맞춰 개발&lt;/li&gt;
&lt;li data-end=&quot;532&quot; data-start=&quot;493&quot;&gt;인증/권한 처리, 에러 핸들링, fallback 로직 고려 필요&lt;/li&gt;
&lt;li data-end=&quot;561&quot; data-start=&quot;533&quot;&gt;✅ 서비스 단위 테스트 및 유지보수 효율 &amp;uarr;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;585&quot; data-start=&quot;563&quot; data-ke-size=&quot;size16&quot;&gt;3️⃣ &lt;b&gt;성능 최적화&amp;middot;확장 용이&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;647&quot; data-start=&quot;586&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;610&quot; data-start=&quot;586&quot;&gt;필요한 서비스만 스케일 업/다운 가능&lt;/li&gt;
&lt;li data-end=&quot;647&quot; data-start=&quot;611&quot;&gt;CDN, 서버리스 함수, lazy loading 활용 쉬움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;669&quot; data-start=&quot;649&quot; data-ke-size=&quot;size16&quot;&gt;4️⃣ &lt;b&gt;팀 협업&amp;middot;개발 효율&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;745&quot; data-start=&quot;670&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;693&quot; data-start=&quot;670&quot;&gt;프론트/백엔드 팀이 독립 작업 가능&lt;/li&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;694&quot;&gt;소규모 팀 단위 담당 &amp;rarr; 개발 속도 &amp;uarr;&lt;/li&gt;
&lt;li data-end=&quot;745&quot; data-start=&quot;720&quot;&gt;장애 발생 시 특정 서비스만 대응 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;783&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&amp;nbsp;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;844&quot; data-start=&quot;784&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;784&quot;&gt;빠른 개발&amp;middot;배포&lt;/li&gt;
&lt;li data-end=&quot;819&quot; data-start=&quot;797&quot;&gt;서비스 단위 유지보수&amp;middot;테스트 용이&lt;/li&gt;
&lt;li data-end=&quot;844&quot; data-start=&quot;820&quot;&gt;클라우드 환경에서 최적화&amp;middot;확장성 확보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;854&quot; data-start=&quot;846&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&amp;nbsp;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;937&quot; data-start=&quot;855&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;885&quot; data-start=&quot;855&quot;&gt;서비스 수 증가 &amp;rarr; API 호출&amp;middot;상태 관리 복잡&lt;/li&gt;
&lt;li data-end=&quot;909&quot; data-start=&quot;886&quot;&gt;네트워크 지연&amp;middot;장애 처리 로직 필요&lt;/li&gt;
&lt;li data-end=&quot;937&quot; data-start=&quot;910&quot;&gt;초기 설계, 모니터링&amp;middot;로깅 체계 구축 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  핵심 포인트: &lt;b&gt;저장소 수는 아키텍처를 결정하는 필수 조건이 아니고, 배포 독립성과 서비스 독립성이 핵심&lt;/b&gt;이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.44.28.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;894&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSIclc/btsQAQ0I9u3/NHzwpwIpjmqE08ftUbwXBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSIclc/btsQAQ0I9u3/NHzwpwIpjmqE08ftUbwXBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSIclc/btsQAQ0I9u3/NHzwpwIpjmqE08ftUbwXBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSIclc%2FbtsQAQ0I9u3%2FNHzwpwIpjmqE08ftUbwXBk%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;1652&quot; height=&quot;894&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.44.28.png&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;894&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.44.55.png&quot; data-origin-width=&quot;1662&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cU2J99/btsQBD7oS8v/NDZs7vmXVGESwVYpXDSMwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cU2J99/btsQBD7oS8v/NDZs7vmXVGESwVYpXDSMwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cU2J99/btsQBD7oS8v/NDZs7vmXVGESwVYpXDSMwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcU2J99%2FbtsQBD7oS8v%2FNDZs7vmXVGESwVYpXDSMwK%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;1662&quot; height=&quot;612&quot; data-filename=&quot;스크린샷 2025-09-16 오후 2.44.55.png&quot; data-origin-width=&quot;1662&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 흔한 조합&lt;/p&gt;
&lt;p data-end=&quot;752&quot; data-start=&quot;691&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SPA (React/Vue) + 백엔드 MSA + 경우에 따라 Micro Frontend 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;752&quot; data-start=&quot;691&quot; data-ke-size=&quot;size16&quot;&gt;** &lt;b&gt;Micro Frontends(마이크로 프론트엔드, MFE)&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;669&quot; data-start=&quot;574&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;604&quot; data-start=&quot;574&quot;&gt;화면을 여러 팀/서비스 단위로 쪼개서 독립 배포&lt;/li&gt;
&lt;li data-end=&quot;669&quot; data-start=&quot;607&quot;&gt;예) 쿠팡 메인 페이지의 &quot;배너 영역&quot;, &quot;추천 상품&quot;, &quot;장바구니&quot;가 각각 다른 팀에서 독립 개발/배포&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1758000313658&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;A Deep Dive into Micro Frontend Architecture with React.js&quot; data-og-description=&quot;Discover the power of Micro Frontend Architecture in React.js! Learn how to build modular and scalable web applications in our latest blog.&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&quot; data-og-url=&quot;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cRdrhB/hyZIVSZkcQ/ya8IlboczUkbyXTXw5hHLK/img.png?width=1200&amp;amp;height=636&amp;amp;face=0_0_1200_636&quot;&gt;&lt;a href=&quot;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/@isuruariyarathna2k00/a-deep-dive-into-micro-frontend-architecture-with-react-js-264ca6edca6b&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cRdrhB/hyZIVSZkcQ/ya8IlboczUkbyXTXw5hHLK/img.png?width=1200&amp;amp;height=636&amp;amp;face=0_0_1200_636');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;A Deep Dive into Micro Frontend Architecture with React.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Discover the power of Micro Frontend Architecture in React.js! Learn how to build modular and scalable web applications in our latest blog.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MSA를 사용하는 기업들&lt;/h2&gt;
&lt;h4 data-end=&quot;176&quot; data-start=&quot;154&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;넷플릭스 (Netflix)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;176&quot; data-start=&quot;154&quot; data-ke-size=&quot;size16&quot;&gt;넷플릭스는 원래 모놀리식에서 시작했지만, 트래픽 급증과 기능 복잡성 증가로 인해 &lt;b&gt;마이크로서비스 아키텍처&lt;/b&gt;로 전환함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;389&quot; data-start=&quot;298&quot;&gt;각 기능(예: 계정관리, 스트리밍, 추천, 사용자 프로필 등)이 독립적 서비스로 분리됨.&amp;nbsp;&lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;471&quot; data-start=&quot;392&quot;&gt;장애 격리 (하나의 서비스 장애가 전체 서비스에 미치는 영향 줄임)&amp;nbsp;&lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;574&quot; data-start=&quot;474&quot;&gt;AWS 같은 클라우드 인프라를 활용해서 수평 확장 및 로드 밸런싱, 콘텐츠 전송망(CDN) 등을 운용함.&amp;nbsp;&lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;679&quot; data-start=&quot;577&quot;&gt;&amp;ldquo;Chaos Monkey&amp;rdquo;라는 장애 테스트 도구 등을 통해 내결함성(resilience) 확보 노하우 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://newsletter.systemdesign.one/p/netflix-microservices?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://newsletter.systemdesign.one/p/netflix-microservices?utm_source=chatgpt.com&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1758000188588&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Microservices Lessons From Netflix&quot; data-og-description=&quot;#19: Check This Out - Awesome Microservices Guide (5 minutes)&quot; data-og-host=&quot;newsletter.systemdesign.one&quot; data-og-source-url=&quot;https://newsletter.systemdesign.one/p/netflix-microservices?utm_source=chatgpt.com&quot; data-og-url=&quot;https://newsletter.systemdesign.one/p/netflix-microservices&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYlQqI/hyZITVdmzU/Bw9RslYV8jsExp78sGaeTK/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Zw1o1/hyZJqDQFOR/KeySKyxMl3ewdQvlafvjE1/img.jpg?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/ybgcu/hyZJu7i8Ke/KiJeuOH8IcFA953y8zeHl0/img.jpg?width=1456&amp;amp;height=2060&amp;amp;face=1149_737_1239_836&quot;&gt;&lt;a href=&quot;https://newsletter.systemdesign.one/p/netflix-microservices?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://newsletter.systemdesign.one/p/netflix-microservices?utm_source=chatgpt.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYlQqI/hyZITVdmzU/Bw9RslYV8jsExp78sGaeTK/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Zw1o1/hyZJqDQFOR/KeySKyxMl3ewdQvlafvjE1/img.jpg?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/ybgcu/hyZJu7i8Ke/KiJeuOH8IcFA953y8zeHl0/img.jpg?width=1456&amp;amp;height=2060&amp;amp;face=1149_737_1239_836');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Microservices Lessons From Netflix&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;#19: Check This Out - Awesome Microservices Guide (5 minutes)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;newsletter.systemdesign.one&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.techaheadcorp.com/blog/design-of-microservices-architecture-at-netflix/?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.techaheadcorp.com/blog/design-of-microservices-architecture-at-netflix/?utm_source=chatgpt.com&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;쿠팡&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;쿠팡은 2013년에 모놀리식 아키텍처로 구성된 서비스를 마이크로서비스 아키텍쳐(Microservices Architecture, MSA)로 전환하는 프로젝트를 진행하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;아래 링크는 &lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;이러한 전환을 위해 쿠팡이 취한 전략이 무엇이고, 그 과정에서 나타난 문제를 어떻게 풀어나갔는지 소개하는 페이지 입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1758000359337&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;마이크로서비스 아키텍처로의 전환&quot; data-og-description=&quot;행복을 찾기 위한 쿠팡 엔지니어링의 여정, 마이크로서비스 구현하기 &amp;mdash; Part 1&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&quot; data-og-url=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/p5Xg6/hyZJxprsbk/SRboqN1a8MqAXDHZPnLDK0/img.jpg?width=1200&amp;amp;height=798&amp;amp;face=0_0_1200_798&quot;&gt;&lt;a href=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/p5Xg6/hyZJxprsbk/SRboqN1a8MqAXDHZPnLDK0/img.jpg?width=1200&amp;amp;height=798&amp;amp;face=0_0_1200_798');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;마이크로서비스 아키텍처로의 전환&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;행복을 찾기 위한 쿠팡 엔지니어링의 여정, 마이크로서비스 구현하기 &amp;mdash; Part 1&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;토스&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스 역시 Django 기반 모놀리식 프로젝트 안에서 React를 통한 Micro Frontend를 점진적으로 도입하였다고 합니다. 오래된 코드 베이스를 대대적으로 수정하는 것보다 &amp;ldquo;필요한 부분만 조금씩 분리&amp;rdquo;하는 방식으로 접근하였다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;아래 링크는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;이러한 전환을 위해 토스가 취한 전략이 무엇이고, 그 과정을 소개하는 페이지 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;&lt;a href=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1758000488083&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Micro-frontend React, 점진적으로 도입하기&quot; data-og-description=&quot;거대한 모놀리식 Django 프로젝트에 현대적인 프론트엔드 인프라를 구축한 사례를 공유합니다. 어떻게 해야 오래된 코드 베이스를 대대적으로 수정하지 않으면서도, 최신 프론트엔드 기술들을 &quot; data-og-host=&quot;toss.im&quot; data-og-source-url=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot; data-og-url=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/76r51/hyZIW5o3vl/lRx6mPjvOKHqSHLqI3g3qk/img.png?width=1280&amp;amp;height=720&amp;amp;face=852_180_984_324,https://scrap.kakaocdn.net/dn/dqd5e6/hyZIUGzEtW/ejZUEV1vohY8wlEhkJVCbk/img.png?width=1280&amp;amp;height=720&amp;amp;face=852_180_984_324,https://scrap.kakaocdn.net/dn/0wtVf/hyZI9iSsjk/jvcWkshCKKxR3whJRtBANK/img.png?width=840&amp;amp;height=996&amp;amp;face=314_247_522_475&quot;&gt;&lt;a href=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/76r51/hyZIW5o3vl/lRx6mPjvOKHqSHLqI3g3qk/img.png?width=1280&amp;amp;height=720&amp;amp;face=852_180_984_324,https://scrap.kakaocdn.net/dn/dqd5e6/hyZIUGzEtW/ejZUEV1vohY8wlEhkJVCbk/img.png?width=1280&amp;amp;height=720&amp;amp;face=852_180_984_324,https://scrap.kakaocdn.net/dn/0wtVf/hyZI9iSsjk/jvcWkshCKKxR3whJRtBANK/img.png?width=840&amp;amp;height=996&amp;amp;face=314_247_522_475');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Micro-frontend React, 점진적으로 도입하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;거대한 모놀리식 Django 프로젝트에 현대적인 프론트엔드 인프라를 구축한 사례를 공유합니다. 어떻게 해야 오래된 코드 베이스를 대대적으로 수정하지 않으면서도, 최신 프론트엔드 기술들을&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toss.im&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1025&quot; data-start=&quot;994&quot; data-ke-size=&quot;size18&quot;&gt;  주요 인사이트 (우리 글에 넣으면 좋은 것들)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1439&quot; data-start=&quot;1027&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1155&quot; data-start=&quot;1027&quot;&gt;쿠팡은 모놀리식 &amp;rarr; MSA 전환 과정에서 한 리포지토리(monorepo 비슷한 구조)였고, 기능별 컴포넌트들을 같은 저장소 안에서 관리했었다는 점. &lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://medium.com/coupang-engineering/how-coupang-built-a-microservice-architecture-fd584fff7f2b?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Medium&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1281&quot; data-start=&quot;1156&quot;&gt;토스는 Micro Frontend를 도입하면서 &lt;b&gt;전체를 한꺼번에 갈아엎기보다는 점진적인 분리&lt;/b&gt;를 택했다는 점. 필요 기능만 골라서 현대화/분리함. &lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://toss.im/slash-21/sessions/2-5?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;토스&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1439&quot; data-start=&quot;1282&quot;&gt;조직 구조(팀/사일로)도 아키텍처 영향을 많이 준다는 사례. 기능 책임 팀 ≒ 해당 기능의 프론트 + 백이 같이 움직이면 분리/독립이 더 쉬워짐. 토스 Frontend 챕터 글에서 이런 조직 구조가 보고됨. &lt;span data-state=&quot;delayed-open&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://toss.tech/article/toss-frontend-chapter?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;토스 테크&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;139&quot; data-start=&quot;114&quot; data-ke-size=&quot;size26&quot;&gt;  프론트엔드 관점에서 본 아키텍처&lt;/h2&gt;
&lt;p data-end=&quot;281&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;아키텍처 이야기는 보통 백엔드 개발자나 인프라 팀의 영역이라고 생각하기 쉽지만, 프론트엔드 개발자에게도 큰 영향을 줍니다. 왜냐하면 &lt;b&gt;서비스를 어떻게 나누고, 어떻게 배포하고, 어떤 방식으로 확장하느냐&lt;/b&gt;에 따라 프론트 코드도 달라지기 때문이죠.&lt;/p&gt;
&lt;h3 data-end=&quot;306&quot; data-start=&quot;283&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ API 호출 방식의 변화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;607&quot; data-start=&quot;307&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;307&quot;&gt;&lt;b&gt;모놀리식&lt;/b&gt;: 하나의 백엔드 서버에서 API를 제공하므로, 프론트에서는 단일 엔드포인트만 호출하면 됐습니다.&lt;/li&gt;
&lt;li data-end=&quot;607&quot; data-start=&quot;374&quot;&gt;&lt;b&gt;SOA/ MSA&lt;/b&gt;: 서비스가 여러 개로 나뉘면서, 프론트는 다양한 엔드포인트를 호출해야 합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;607&quot; data-start=&quot;437&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;464&quot; data-start=&quot;437&quot;&gt;인증/인가 처리가 서비스별로 다를 수 있음&lt;/li&gt;
&lt;li data-end=&quot;607&quot; data-start=&quot;467&quot;&gt;서비스 간 장애 발생 시 fallback 로직 필요&lt;br /&gt;  따라서 프론트 개발자는 단순히 fetch를 넘어서 &lt;b&gt;API Gateway, BFF(Backend for Frontend)&lt;/b&gt; 같은 개념을 이해해야 효율적으로 개발할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;631&quot; data-start=&quot;609&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 배포 파이프라인의 변화&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;823&quot; data-start=&quot;632&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;683&quot; data-start=&quot;632&quot;&gt;프론트엔드도 CI/CD 환경에서 &lt;b&gt;자동 빌드 &amp;amp; 자동 배포&lt;/b&gt;가 기본이 되었습니다.&lt;/li&gt;
&lt;li data-end=&quot;823&quot; data-start=&quot;684&quot;&gt;환경(dev/stage/prod)별 설정 분리, API 주소 변경, feature flag 처리 등을 아키텍처 수준에서 고려해야 합니다.&lt;br /&gt;  클라우드 환경에 맞춘 배포 파이프라인을 이해하면, 백엔드/인프라 팀과 협업이 훨씬 수월해집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;849&quot; data-start=&quot;825&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ 성능 최적화 &amp;amp; 장애 대응&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1035&quot; data-start=&quot;850&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;905&quot; data-start=&quot;850&quot;&gt;MSA 환경에서는 네트워크 호출이 많아져서 지연(latency)이 커질 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;968&quot; data-start=&quot;906&quot;&gt;프론트 차원에서 &lt;b&gt;API 호출 최적화, 캐싱 전략, Lazy loading&lt;/b&gt; 같은 패턴이 필요합니다.&lt;/li&gt;
&lt;li data-end=&quot;1035&quot; data-start=&quot;969&quot;&gt;특정 서비스가 장애가 나더라도 전체 화면이 죽지 않도록 &lt;b&gt;fallback UI&lt;/b&gt;를 준비하는 것도 중요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1075&quot; data-start=&quot;1042&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;1075&quot; data-start=&quot;1042&quot; data-ke-size=&quot;size26&quot;&gt;  Micro Frontend 소개 (확장 개념)&lt;/h2&gt;
&lt;p data-end=&quot;1164&quot; data-start=&quot;1077&quot; data-ke-size=&quot;size16&quot;&gt;MSA가 백엔드를 쪼갠 것처럼, 프론트엔드도 커지다 보면 독립적으로 나눠야 할 필요가 생깁니다.&lt;br /&gt;이를 &lt;b&gt;Micro Frontend&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1428&quot; data-start=&quot;1166&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1246&quot; data-start=&quot;1166&quot;&gt;&lt;b&gt;필요성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1246&quot; data-start=&quot;1180&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1222&quot; data-start=&quot;1180&quot;&gt;대규모 SPA에서 빌드/배포 시간이 길어지고, 팀 간 충돌이 생길 때&lt;/li&gt;
&lt;li data-end=&quot;1246&quot; data-start=&quot;1225&quot;&gt;기능별로 독립 배포가 필요할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1352&quot; data-start=&quot;1248&quot;&gt;&lt;b&gt;장점&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1352&quot; data-start=&quot;1261&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1297&quot; data-start=&quot;1261&quot;&gt;팀 단위로 독립 배포 가능 &amp;rarr; 특정 기능만 수정/배포 가능&lt;/li&gt;
&lt;li data-end=&quot;1352&quot; data-start=&quot;1300&quot;&gt;서비스별로 기술 스택을 다르게 가져갈 수도 있음 (예: 일부 React, 일부 Vue)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1428&quot; data-start=&quot;1354&quot;&gt;&lt;b&gt;단점&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1428&quot; data-start=&quot;1367&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1367&quot;&gt;초기 설정 복잡 (라우팅, 공통 라이브러리 관리)&lt;/li&gt;
&lt;li data-end=&quot;1428&quot; data-start=&quot;1401&quot;&gt;UX 통일성을 맞추기 위한 추가 작업 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1497&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;  아직은 모든 회사가 쓰는 건 아니지만, &lt;b&gt;토스, 쿠팡 같은 대규모 서비스&lt;/b&gt;에서 점진적으로 도입하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1497&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1497&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1526&quot; data-start=&quot;1504&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;1526&quot; data-start=&quot;1504&quot; data-ke-size=&quot;size26&quot;&gt;  클라우드 네이티브와의 관계&lt;/h2&gt;
&lt;p data-end=&quot;1572&quot; data-start=&quot;1528&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;1768&quot; data-start=&quot;1574&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1621&quot; data-start=&quot;1574&quot;&gt;&lt;b&gt;Docker(컨테이너)&lt;/b&gt;: 서비스별 독립 실행 환경 제공 &amp;rarr; MSA 필수&lt;/li&gt;
&lt;li data-end=&quot;1687&quot; data-start=&quot;1622&quot;&gt;&lt;b&gt;Kubernetes(오케스트레이션)&lt;/b&gt;: 수십~수백 개의 마이크로서비스를 자동으로 배포, 확장, 복구 관리&lt;/li&gt;
&lt;li data-end=&quot;1768&quot; data-start=&quot;1688&quot;&gt;&lt;b&gt;Serverless&lt;/b&gt;: 특정 이벤트(API 요청, 스케줄링)에 맞춰 코드만 실행 &amp;rarr; 프론트에서도 Lambda 같은 서비스 자주 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1884&quot; data-start=&quot;1770&quot; data-ke-size=&quot;size16&quot;&gt;  정리하자면:&lt;br /&gt;&lt;b&gt;MSA는 클라우드 없이는 운영이 거의 불가능&lt;/b&gt;합니다.&lt;br /&gt;그리고 프론트엔드 개발자도 이런 구조를 이해해야 API 호출, 배포 전략, 장애 대응을 더 깊이 이해할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발은 이제 단순히 화면을 예쁘게 그리는 일이 아닙니다.&lt;br /&gt;서비스가 점점 커지고 복잡해질수록, &lt;b&gt;아키텍처를 이해하는 프론트엔드 개발자&lt;/b&gt;가 더 큰 경쟁력을 갖게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2127&quot; data-start=&quot;2022&quot; data-ke-size=&quot;size16&quot;&gt;저 역시 패키지 매니저 공부에서 출발했지만, 모놀리식 &amp;rarr; SOA &amp;rarr; MSA &amp;rarr; Micro Frontend, 그리고 클라우드 네이티브까지 이어지는 흐름을 배우면서 큰 깨달음을 얻었습니다.&lt;/p&gt;
&lt;p data-end=&quot;2127&quot; data-start=&quot;2022&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2243&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;내가 배우는 개념이 회사 구조랑 맞닿아 있다는 걸 알게 되는 순간, 개발자로서 한 단계 성장한다는 걸 느꼈습니다.&lt;br /&gt;이 글이 독자분들께도 그런 시야를 넓히는 데 도움이 되었으면 좋겠습니다.  &lt;/p&gt;
&lt;p data-end=&quot;2243&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2243&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2243&quot; data-start=&quot;2129&quot; data-ke-size=&quot;size16&quot;&gt;참고하시면 좋을 영상 첨부해요~&lt;br /&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8d4h7K_Fq-0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=8d4h7K_Fq-0&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=8d4h7K_Fq-0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/biPEeg/hyZJdMlBHf/DazeYbSmFbT2A4NoRzWAiK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bijBLl/hyZJjxYmUl/6HlizIkWePIW8rhqwcFRR0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[Talk&amp;amp;Talk] 누구나 쉽게 이해할수 있는 마이크로서비스 아키텍처(MSA) #1편&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/8d4h7K_Fq-0&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 로그/오늘의 개발읽기</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/93</guid>
      <comments>https://jjung2ing.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 16 Sep 2025 14:46:19 +0900</pubDate>
    </item>
    <item>
      <title>[토스 오픈소스 기여 vol.0] 오픈소스 기여 가이드</title>
      <link>https://jjung2ing.tistory.com/92</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 개발자들이 조직에서 반복적인 프로젝트를 하다 보면, 기술적으로 정체되어 있다는 느낌을 받곤 합니다.&lt;br /&gt;저 역시 최근 들어 그런 느낌을 자주 받았고, 큰 성장을 체감하지 못하고 있어 스스로 성장이 필요하다고 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;206&quot; data-ke-size=&quot;size16&quot;&gt;그러던 중 오픈소스 관련 포스팅을 작성하면서, &lt;b&gt;오픈소스가 주는 이점&lt;/b&gt;을 크게 느끼게 되었고, 자연스럽게 &lt;b&gt;오픈소스 기여&lt;/b&gt;를 해보고 싶다는 생각이 들었습니다. 하지만 처음이라 어디서부터 시작해야 할지 감이 오지 않아, 하나씩 차근차근 해보기로 마음먹었습니다.&lt;/p&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;206&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;539&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 토스의 경우 코드를 이렇게 작성하고, 이슈나 PR을 이렇게 커뮤니케이션하는구나 라는 점을 느끼며, 초기에는 &lt;b&gt;문서(docs)&lt;/b&gt; 수정부터 시작하고 점차 코드 영역으로 확장했다고 합니다. 저 역시 간단한 타입 정의나 테스트 코드부터 시작해서, 나중에는 &lt;b&gt;CI 관련 코드 등&lt;/b&gt;으로 참여 범위를 넓혀보려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;539&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;539&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 제가 이 과정을 &lt;b&gt;직접 경험하며 공유&lt;/b&gt;하려고 합니다.&lt;br /&gt;오늘은 &lt;b&gt;프로젝트를 다운받고, 코드를 어떤 식으로 작성하고 있는지&lt;/b&gt; 확인하는 것부터 시작해보겠습니다.&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;토스에는 &lt;b&gt;Slash&lt;/b&gt;라는 내부 라이브러리 컬렉션이 있습니다.&lt;br /&gt;Slash는 토스 내부에서 사용되는 &lt;b&gt;여러 TypeScript/JavaScript 유틸리티와 React 도구&lt;/b&gt;를 한데 모아놓은 컬렉션으로, &amp;ldquo;Slash libraries&amp;rdquo;라는 이름으로 문서가 정리되어 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;385&quot; data-start=&quot;232&quot; data-ke-size=&quot;size16&quot;&gt;이 라이브러리들은 미리 정의된 문제들을 해결하기 위해 만들어졌습니다.&lt;br /&gt;예를 들어, &lt;b&gt;한글 처리&lt;/b&gt;, &lt;b&gt;React Suspense 관리&lt;/b&gt;, &lt;b&gt;복잡한 사용자 흐름 관리&lt;/b&gt; 등 다양한 개발 과정에서 반복적으로 발생하는 문제들을 효율적으로 처리할 수 있도록 돕습니다.&lt;/p&gt;
&lt;p data-end=&quot;385&quot; data-start=&quot;232&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.slash.page/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.slash.page/ko/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757902901448&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Slash 라이브러리&quot; data-og-description=&quot;높은 퀄리티의 웹 서비스를 개발하기 위한 TypeScript/JavaScript 패키지 세트&quot; data-og-host=&quot;www.slash.page&quot; data-og-source-url=&quot;https://www.slash.page/ko/&quot; data-og-url=&quot;https://slash.page/ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vr0hT/hyZIOMWSgK/dXC5wf4MUkIrKlV7GRzBrk/img.png?width=1200&amp;amp;height=672&amp;amp;face=0_0_1200_672&quot;&gt;&lt;a href=&quot;https://www.slash.page/ko/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.slash.page/ko/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vr0hT/hyZIOMWSgK/dXC5wf4MUkIrKlV7GRzBrk/img.png?width=1200&amp;amp;height=672&amp;amp;face=0_0_1200_672');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Slash 라이브러리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;높은 퀄리티의 웹 서비스를 개발하기 위한 TypeScript/JavaScript 패키지 세트&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.slash.page&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;78&quot; data-start=&quot;59&quot; data-ke-size=&quot;size26&quot;&gt;토스 오픈소스 라이브러리 목록&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;523&quot; data-start=&quot;80&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;160&quot; data-start=&quot;80&quot;&gt;&lt;a href=&quot;https://github.com/toss/es-toolkit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;es-toolkit&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;토스에서 만든 유틸리티 라이브러리 모음&lt;/li&gt;
&lt;li data-end=&quot;244&quot; data-start=&quot;162&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/toss/es-hangul&quot; data-end=&quot;212&quot; data-start=&quot;166&quot;&gt;es-hangul&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;한글 관련 유틸리티 및 텍스트 처리 라이브러리&lt;/li&gt;
&lt;li data-end=&quot;340&quot; data-start=&quot;246&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/toss/suspensive&quot; data-end=&quot;298&quot; data-start=&quot;250&quot;&gt;suspensive&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;React Suspense를 활용한 비동기 상태 관리 라이브러리&lt;/li&gt;
&lt;li data-end=&quot;430&quot; data-start=&quot;342&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/toss/overlay-kit&quot; data-end=&quot;396&quot; data-start=&quot;346&quot;&gt;overlay-kit&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;모달, 팝업 등 UI 오버레이 컴포넌트 라이브러리&lt;/li&gt;
&lt;li data-end=&quot;523&quot; data-start=&quot;432&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/toss/use-funnel&quot; data-end=&quot;484&quot; data-start=&quot;436&quot;&gt;use-funnel&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;퍼널 분석 및 이벤트 추적을 위한 React 훅 라이브러리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;490&quot; data-start=&quot;474&quot; data-ke-size=&quot;size26&quot;&gt;  각 라이브러리 설명&lt;/h2&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 304px;&quot; border=&quot;1&quot; data-end=&quot;1657&quot; data-start=&quot;492&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;height: 38px; width: 13.2558%;&quot;&gt;&lt;b&gt;라이브러리&amp;nbsp;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 38px; width: 33.3721%;&quot;&gt;기능&amp;nbsp;/ 문제 해결&lt;/td&gt;
&lt;td style=&quot;height: 38px; width: 53.2558%;&quot;&gt;주요 특징 / 활용 예&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot; data-end=&quot;727&quot; data-start=&quot;547&quot;&gt;
&lt;td style=&quot;height: 38px; width: 13.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;564&quot; data-start=&quot;547&quot;&gt;&lt;b&gt;es-toolkit&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 38px; width: 33.3721%;&quot; data-col-size=&quot;md&quot; data-end=&quot;604&quot; data-start=&quot;564&quot;&gt;일반적인 자바스크립트 유틸리티 함수 모음 &lt;br /&gt;(lodash 같은 역할)&lt;/td&gt;
&lt;td style=&quot;height: 38px; width: 53.2558%;&quot; data-col-size=&quot;lg&quot; data-end=&quot;727&quot; data-start=&quot;604&quot;&gt;작고 빠름, 번들 사이즈 작고 타입 안정성 있음. &lt;br /&gt;예: debounce, sum, delay, throttle 같은 함수들이 있음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 57px;&quot; data-end=&quot;950&quot; data-start=&quot;728&quot;&gt;
&lt;td style=&quot;height: 57px; width: 13.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;744&quot; data-start=&quot;728&quot;&gt;&lt;b&gt;es-hangul&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 33.3721%;&quot; data-col-size=&quot;md&quot; data-end=&quot;790&quot; data-start=&quot;744&quot;&gt;한글 문자열 처리를 편하게&lt;br /&gt;조사 붙이기 / 초성 추출 / 분해 및 조합 등&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 53.2558%;&quot; data-col-size=&quot;lg&quot; data-end=&quot;950&quot; data-start=&quot;790&quot;&gt;예: getChoseong, josa 함수 등이 있어 &amp;ldquo;사과가/사과를 먹었습니다&amp;rdquo; 같은 표현을 자동 처리 가능. &lt;br /&gt;ECMAScript Modules 방식이며 브라우저에서도 최소 코드 다운로드 하도록 설계됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 57px;&quot; data-end=&quot;1196&quot; data-start=&quot;951&quot;&gt;
&lt;td style=&quot;height: 57px; width: 13.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;968&quot; data-start=&quot;951&quot;&gt;&lt;b&gt;suspensive&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 33.3721%;&quot; data-col-size=&quot;md&quot; data-end=&quot;1022&quot; data-start=&quot;968&quot;&gt;React의 Suspense / ErrorBoundary 등을 간편하게 사용하려는 도구 집합&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 53.2558%;&quot; data-col-size=&quot;lg&quot; data-end=&quot;1196&quot; data-start=&quot;1022&quot;&gt;SSR 환경에서 Suspense를 점진적으로 적용 가능하게 해주는 clientOnly 같은 기능도 제공됨. &lt;br /&gt;&amp;lt;Suspense&amp;gt;, &amp;lt;ErrorBoundary&amp;gt;, &amp;lt;ErrorBoundaryGroup&amp;gt; 등의 선언적 API 제공.&amp;nbsp;&lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 57px;&quot; data-end=&quot;1417&quot; data-start=&quot;1197&quot;&gt;
&lt;td style=&quot;height: 57px; width: 13.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1215&quot; data-start=&quot;1197&quot;&gt;&lt;b&gt;overlay-kit&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 33.3721%;&quot; data-col-size=&quot;md&quot; data-end=&quot;1261&quot; data-start=&quot;1215&quot;&gt;React에서 모달, 팝업, 다이얼로그 등 &lt;br /&gt;&amp;ldquo;오버레이&amp;rdquo; UI를 선언적으로 관리&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 53.2558%;&quot; data-col-size=&quot;lg&quot; data-end=&quot;1417&quot; data-start=&quot;1261&quot;&gt;상태 관리(useState 등)과 이벤트 핸들링 복잡성 줄임. &lt;br /&gt;overlay.open, overlay.openAsync 같은 API가 있음. &lt;br /&gt;오버레이 안에서 어떤 UI를 렌더링할지 쉽게 조정 가능.&amp;nbsp;&lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 57px;&quot; data-end=&quot;1657&quot; data-start=&quot;1418&quot;&gt;
&lt;td style=&quot;height: 57px; width: 13.2558%;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1435&quot; data-start=&quot;1418&quot;&gt;&lt;b&gt;use-funnel&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 33.3721%;&quot; data-col-size=&quot;md&quot; data-end=&quot;1487&quot; data-start=&quot;1435&quot;&gt;단계(step)가 있는 사용자 흐름(funnel)이나 wizard 형태의 UI 흐름 관리&lt;/td&gt;
&lt;td style=&quot;height: 57px; width: 53.2558%;&quot; data-col-size=&quot;lg&quot; data-end=&quot;1657&quot; data-start=&quot;1487&quot;&gt;예: 여러 입력 단계(이메일 &amp;rarr; 비밀번호 &amp;rarr; 정보 입력 등)를 타입 안정성 있게 관리. &lt;br /&gt;히스토리(back/forward) 지원됨. &lt;br /&gt;다양한 라우터 환경(Next.js, react-router, react navigation) 대응.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 오픈소스 기여를 시작할 때는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로젝트의 규모, 코드 난이도, 문서화 상태, 이슈 난이도&lt;/b&gt;를 보고 선택하는 게 좋을것 같아서 비교를 해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스 오픈소스 5개 라이브러리(es-toolkit, es-hangul, suspensive, overlay-kit, use-funnel)를 &lt;b&gt;내부 구조와 API 관점&lt;/b&gt;에서 비교해보면, 접근 난이도나 활용 목적을 한눈에 볼 수 있을 것같아서 GPT의 도움을 받아 비교해서 선별해보았습니다.&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-filename=&quot;스크린샷 2025-09-15 오전 11.27.30.png&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;972&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bedd2z/btsQzF4RW85/F0jpxy1QY1IFIjYl3Go5e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bedd2z/btsQzF4RW85/F0jpxy1QY1IFIjYl3Go5e1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bedd2z/btsQzF4RW85/F0jpxy1QY1IFIjYl3Go5e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbedd2z%2FbtsQzF4RW85%2FF0jpxy1QY1IFIjYl3Go5e1%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;1598&quot; height=&quot;972&quot; data-filename=&quot;스크린샷 2025-09-15 오전 11.27.30.png&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;972&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-15 오전 11.27.42.png&quot; data-origin-width=&quot;1578&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcyn3f/btsQxMxbQZj/RHd5QXfhxEEEsKadcn09V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcyn3f/btsQxMxbQZj/RHd5QXfhxEEEsKadcn09V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcyn3f/btsQxMxbQZj/RHd5QXfhxEEEsKadcn09V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdcyn3f%2FbtsQxMxbQZj%2FRHd5QXfhxEEEsKadcn09V0%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;1578&quot; height=&quot;910&quot; data-filename=&quot;스크린샷 2025-09-15 오전 11.27.42.png&quot; data-origin-width=&quot;1578&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-15 오전 11.27.54.png&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;742&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj5u5O/btsQwLewovO/TrCfzHajLucR1eURJ2TeWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj5u5O/btsQwLewovO/TrCfzHajLucR1eURJ2TeWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj5u5O/btsQwLewovO/TrCfzHajLucR1eURJ2TeWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj5u5O%2FbtsQwLewovO%2FTrCfzHajLucR1eURJ2TeWK%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;1630&quot; height=&quot;742&quot; data-filename=&quot;스크린샷 2025-09-15 오전 11.27.54.png&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;742&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;126&quot; data-start=&quot;111&quot; data-ke-size=&quot;size23&quot;&gt;  정리&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2254&quot; data-start=&quot;2047&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2119&quot; data-start=&quot;2047&quot;&gt;&lt;b&gt;초보 기여자&lt;/b&gt;: es-toolkit / es-hangul &amp;rarr; 함수 중심, 테스트/문서 개선으로 시작하기 좋음&lt;/li&gt;
&lt;li data-end=&quot;2185&quot; data-start=&quot;2120&quot;&gt;&lt;b&gt;중급 개발자&lt;/b&gt;: overlay-kit, use-funnel &amp;rarr; Hook/컴포넌트 구조 이해 필요&lt;/li&gt;
&lt;li data-end=&quot;2254&quot; data-start=&quot;2186&quot;&gt;&lt;b&gt;상급 개발자&lt;/b&gt;: suspensive &amp;rarr; React Suspense + SSR, 에러 경계 관리 이해 필요&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  라이브러리의 내부 구조와 대표 API&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣ es-toolkit (범용 JS 유틸)&lt;/p&gt;
&lt;pre id=&quot;code_1757903356562&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;es-toolkit/
├─ src/
│   ├─ debounce.ts       # 함수 지연 호출
│   ├─ throttle.ts       # 함수 제한 호출
│   ├─ sum.ts            # 배열 합계
│   └─ delay.ts          # Promise 지연
└─ tests/
    ├─ debounce.spec.ts
    ├─ throttle.spec.ts
    └─ sum.spec.ts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;412&quot; data-start=&quot;354&quot;&gt;대표 API: debounce(), throttle(), sum(), delay()&lt;/li&gt;
&lt;li data-end=&quot;456&quot; data-start=&quot;413&quot;&gt;특징: 순수 JS 함수, 타입스크립트 지원, 테스트(Vitest) 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;es-toolkit은 단순한 JS 함수들의 모음이에요. src 폴더 안에는 debounce, throttle, sum, delay 같은 개별 함수 파일이 있고, 각각에 대응하는 테스트 파일이 tests 폴더에 있어요.&lt;br /&gt;대표 API는 debounce()나 throttle() 같은 함수로, 브라우저나 Node 환경에서 그대로 쓸 수 있습니다. 타입스크립트를 지원하고 Vitest로 테스트를 돌릴 수 있어 초보자가 기여하기 가장 쉬운 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2️⃣ es-hangul (한글 처리)&lt;/p&gt;
&lt;pre id=&quot;code_1757903379018&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;es-hangul/
├─ src/
│   ├─ josa.ts           # 조사 붙이기
│   ├─ getChoseong.ts    # 초성 추출
│   ├─ hangulCompose.ts  # 글자 조합
│   └─ hangulDecompose.ts# 글자 분해
└─ tests/
    ├─ josa.spec.ts
    ├─ getChoseong.spec.ts
    └─ hangulCompose.spec.ts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;787&quot; data-start=&quot;736&quot;&gt;대표 API: josa('사과', '을'), getChoseong('가나다')&lt;/li&gt;
&lt;li data-end=&quot;821&quot; data-start=&quot;788&quot;&gt;특징: 작은 범위, 직관적, 타입 안전, Vitest&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;es-hangul은 한글 문자열 처리에 특화된 유틸 모음이에요. src 안에는 josa.ts(조사 붙이기), getChoseong.ts(초성 추출), hangulCompose.ts(글자 조합), hangulDecompose.ts(글자 분해) 같은 파일들이 있어요. 테스트도 Vitest로 작성되어 있습니다.&lt;br /&gt;대표 API는 josa('사과', '을')나 getChoseong('가나다')이고, 한글 처리 도메인이 직관적이라 입문용으로 적합합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3️⃣ suspensive (React Suspense &amp;amp; ErrorBoundary)&lt;/p&gt;
&lt;pre id=&quot;code_1757903399040&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;suspensive/
├─ src/
│   ├─ components/
│   │   ├─ Suspense.tsx
│   │   └─ ErrorBoundary.tsx
│   ├─ hooks/
│   │   └─ clientOnly.ts
└─ tests/
    ├─ Suspense.spec.tsx
    └─ ErrorBoundary.spec.tsx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1144&quot; data-start=&quot;1085&quot;&gt;대표 API: &amp;lt;Suspense&amp;gt;, &amp;lt;ErrorBoundary&amp;gt;, clientOnly()&lt;/li&gt;
&lt;li data-end=&quot;1177&quot; data-start=&quot;1145&quot;&gt;특징: React 전용, SSR 대응, 중급 난이도&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;suspensive는 React 환경에서 Suspense와 ErrorBoundary를 관리하기 위한 라이브러리입니다. src/components에는 와 컴포넌트가 있고, src/hooks에는 clientOnly 같은 Hook이 있습니다.&lt;br /&gt;대표 API는 와 를 JSX에서 직접 쓰거나, clientOnly()로 SSR 환경에서 특정 컴포넌트를 클라이언트 전용으로 렌더링하는 방식입니다. React와 SSR 지식이 필요해 난이도가 중급 수준이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4️⃣ overlay-kit (모달/팝업 관리)&lt;/p&gt;
&lt;pre id=&quot;code_1757903419731&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;overlay-kit/
├─ src/
│   ├─ overlay.tsx       # 오버레이 컨트롤
│   ├─ hooks/
│   │   └─ useOverlay.ts
└─ tests/
    ├─ overlay.spec.tsx
    └─ useOverlay.spec.ts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1436&quot; data-start=&quot;1380&quot;&gt;대표 API: overlay.open(&amp;lt;Modal /&amp;gt;), overlay.close()&lt;/li&gt;
&lt;li data-end=&quot;1479&quot; data-start=&quot;1437&quot;&gt;특징: Hook + API 조합, React UI 관리, 중급 난이도&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;overlay-kit은 React에서 모달, 팝업, 다이얼로그 등 오버레이 UI를 선언적으로 관리할 수 있게 도와주는 라이브러리입니다. src/overlay.tsx가 핵심이고, src/hooks/useOverlay.ts로 상태를 제어할 수 있습니다.&lt;br /&gt;대표 API는 overlay.open()와 overlay.close()로, 오버레이를 열고 닫는 동작을 간단히 제어할 수 있습니다. React Hook과 컴포넌트 구조를 이해해야 해서 난이도는 중급이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1515&quot; data-start=&quot;1486&quot; data-ke-size=&quot;size16&quot;&gt;5️⃣ use-funnel (단계별 UI 흐름)&lt;/p&gt;
&lt;pre id=&quot;code_1757903447765&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;use-funnel/
├─ src/
│   └─ hooks/
│       └─ useFunnel.ts   # step 관리, next/back
└─ tests/
    └─ useFunnel.spec.ts&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1736&quot; data-start=&quot;1642&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1699&quot; data-start=&quot;1642&quot;&gt;대표 API: const { step, next, back } = useFunnel(...)&lt;/li&gt;
&lt;li data-end=&quot;1736&quot; data-start=&quot;1700&quot;&gt;특징: Wizard/Flow 관리, 타입 안전, 중급~상급&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;use-funnel은 단계별 UI 흐름이나 Wizard를 타입 안전하게 관리하는 Hook입니다. src/hooks/useFunnel.ts 안에서 step, next, back 등을 관리하며, 히스토리(back/forward)도 지원합니다.&lt;br /&gt;대표 API는 const { step, next, back } = useFunnel(...)이고, 복잡한 단계형 UI를 만들 때 유용합니다. 타입 안정성을 이해해야 해서 난이도는 중급~상급이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리를 해보자면,&lt;/p&gt;
&lt;h3 data-end=&quot;126&quot; data-start=&quot;111&quot; data-ke-size=&quot;size23&quot;&gt;  난이도별 접근성&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;829&quot; data-start=&quot;127&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;280&quot; data-start=&quot;127&quot;&gt;&lt;b&gt;es-hangul&lt;/b&gt; (가장 쉬움 ✅)
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;280&quot; data-start=&quot;159&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;190&quot; data-start=&quot;159&quot;&gt;한글 관련 문자열 처리라 문제 도메인이 직관적임.&lt;/li&gt;
&lt;li data-end=&quot;228&quot; data-start=&quot;194&quot;&gt;비교적 작은 범위(문자열 유틸 함수)라 이해하기 쉬움.&lt;/li&gt;
&lt;li data-end=&quot;280&quot; data-start=&quot;232&quot;&gt;&amp;ldquo;오타 수정&amp;rdquo;, &amp;ldquo;문서 보강&amp;rdquo;, &amp;ldquo;테스트 케이스 추가&amp;rdquo; 같은 기여 포인트 많음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;282&quot;&gt;&lt;b&gt;es-toolkit&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;400&quot; data-start=&quot;305&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;325&quot; data-start=&quot;305&quot;&gt;lodash 같은 유틸 모음.&lt;/li&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;329&quot;&gt;코드가 단순한 함수 단위로 나뉘어 있어서 특정 함수 하나만 분석해도 됨.&lt;/li&gt;
&lt;li data-end=&quot;400&quot; data-start=&quot;377&quot;&gt;작은 개선(PR) 시도하기 좋아요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;402&quot;&gt;&lt;b&gt;overlay-kit&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;555&quot; data-start=&quot;426&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;458&quot; data-start=&quot;426&quot;&gt;React에서 모달/팝업 UI를 다루는 라이브러리.&lt;/li&gt;
&lt;li data-end=&quot;513&quot; data-start=&quot;462&quot;&gt;컴포넌트/Hook 기반이라, 프론트엔드 개발자로서 실사용 경험을 살려 기여하기 좋음.&lt;/li&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;517&quot;&gt;다만 내부 구조(상태관리/Portal 등) 이해가 조금 필요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;557&quot;&gt;&lt;b&gt;use-funnel&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;688&quot; data-start=&quot;580&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;605&quot; data-start=&quot;580&quot;&gt;&quot;단계별 UI 흐름&quot; 관리 라이브러리.&lt;/li&gt;
&lt;li data-end=&quot;659&quot; data-start=&quot;609&quot;&gt;타입 안정성이 핵심이라 TypeScript 타입 설계 경험 있으면 기여하기 괜찮음.&lt;/li&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;663&quot;&gt;초반에는 난이도가 조금 높을 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;829&quot; data-start=&quot;690&quot;&gt;&lt;b&gt;suspensive&lt;/b&gt; (가장 어려움 ⚠️)
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;829&quot; data-start=&quot;725&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;768&quot; data-start=&quot;725&quot;&gt;React Suspense/ErrorBoundary 다루는 고급 패턴.&lt;/li&gt;
&lt;li data-end=&quot;801&quot; data-start=&quot;772&quot;&gt;React 동작 원리에 대한 깊은 이해 필요.&lt;/li&gt;
&lt;li data-end=&quot;829&quot; data-start=&quot;805&quot;&gt;초보자 입장에서는 난이도가 꽤 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 어떤 부분 먼저해야할지 감이 오지않아서 기여 포인트도 정해달라고 해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;109&quot; data-start=&quot;91&quot; data-ke-size=&quot;size18&quot;&gt;  es-toolkit&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;332&quot; data-start=&quot;110&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;259&quot; data-start=&quot;110&quot;&gt;&lt;b&gt;기여 포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;259&quot; data-start=&quot;127&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;187&quot; data-start=&quot;127&quot;&gt;테스트 케이스 추가: debounce, throttle, sum 같은 함수의 경계값 테스트&lt;/li&gt;
&lt;li data-end=&quot;224&quot; data-start=&quot;190&quot;&gt;문서 개선: 각 함수의 예제 코드 추가, 사용법 명확화&lt;/li&gt;
&lt;li data-end=&quot;259&quot; data-start=&quot;227&quot;&gt;버그 수정: 작은 함수 동작 오류, 타입 정의 오류&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;275&quot; data-start=&quot;260&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;: 낮음&lt;/li&gt;
&lt;li data-end=&quot;332&quot; data-start=&quot;276&quot;&gt;&lt;b&gt;추천 이유&lt;/b&gt;: 순수 JS 함수라 코드 이해가 쉽고, 테스트/문서 기여가 곧바로 의미 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;339&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;339&quot; data-ke-size=&quot;size18&quot;&gt;  es-hangul&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;546&quot; data-start=&quot;357&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;472&quot; data-start=&quot;357&quot;&gt;&lt;b&gt;기여 포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;472&quot; data-start=&quot;374&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;414&quot; data-start=&quot;374&quot;&gt;테스트 케이스 확장: 조사 처리, 초성 추출 등 예외 케이스 추가&lt;/li&gt;
&lt;li data-end=&quot;454&quot; data-start=&quot;417&quot;&gt;문서 보강: 함수 사용 예제, 한국어 맞춤법 관련 설명 추가&lt;/li&gt;
&lt;li data-end=&quot;472&quot; data-start=&quot;457&quot;&gt;작은 버그/오타 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;488&quot; data-start=&quot;473&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;: 낮음&lt;/li&gt;
&lt;li data-end=&quot;546&quot; data-start=&quot;489&quot;&gt;&lt;b&gt;추천 이유&lt;/b&gt;: 한글 처리라는 도메인이 직관적이고, 초보자도 테스트/문서 개선으로 기여 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;572&quot; data-start=&quot;553&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;572&quot; data-start=&quot;553&quot; data-ke-size=&quot;size18&quot;&gt;  overlay-kit&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;817&quot; data-start=&quot;573&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;738&quot; data-start=&quot;573&quot;&gt;&lt;b&gt;기여 포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;738&quot; data-start=&quot;590&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;648&quot; data-start=&quot;590&quot;&gt;테스트 케이스 추가: overlay.open() / overlay.close() 동작 검증&lt;/li&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;651&quot;&gt;문서 개선: 오버레이 사용 예제, Hook 사용법 추가&lt;/li&gt;
&lt;li data-end=&quot;738&quot; data-start=&quot;688&quot;&gt;UI 컴포넌트 개선: 기본 Modal 컴포넌트 스타일 수정이나 Props 설명 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;754&quot; data-start=&quot;739&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;: 중급&lt;/li&gt;
&lt;li data-end=&quot;817&quot; data-start=&quot;755&quot;&gt;&lt;b&gt;추천 이유&lt;/b&gt;: React Hook과 UI 관리 경험을 살릴 수 있음, 테스트/문서 기여로 시작 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;842&quot; data-start=&quot;824&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;842&quot; data-start=&quot;824&quot; data-ke-size=&quot;size18&quot;&gt;  use-funnel&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1058&quot; data-start=&quot;843&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;984&quot; data-start=&quot;843&quot;&gt;&lt;b&gt;기여 포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;984&quot; data-start=&quot;860&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;905&quot; data-start=&quot;860&quot;&gt;테스트 케이스 추가: step 이동, back/forward, 예외 케이스&lt;/li&gt;
&lt;li data-end=&quot;941&quot; data-start=&quot;908&quot;&gt;문서 개선: 단계별 UI 구성 예제, 타입 설명 추가&lt;/li&gt;
&lt;li data-end=&quot;984&quot; data-start=&quot;944&quot;&gt;예제 시나리오 추가: Wizard나 회원가입 같은 흐름 샘플 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1003&quot; data-start=&quot;985&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;: 중급~상급&lt;/li&gt;
&lt;li data-end=&quot;1058&quot; data-start=&quot;1004&quot;&gt;&lt;b&gt;추천 이유&lt;/b&gt;: 단계별 UI 흐름 이해가 필요하지만, 테스트/문서로 접근하면 시작 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1083&quot; data-start=&quot;1065&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1083&quot; data-start=&quot;1065&quot; data-ke-size=&quot;size18&quot;&gt;  suspensive&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1313&quot; data-start=&quot;1084&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1234&quot; data-start=&quot;1084&quot;&gt;&lt;b&gt;기여 포인트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1234&quot; data-start=&quot;1101&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1165&quot; data-start=&quot;1101&quot;&gt;문서 개선: &amp;lt;Suspense&amp;gt; / &amp;lt;ErrorBoundary&amp;gt; 사용법, SSR 관련 주의 사항 추가&lt;/li&gt;
&lt;li data-end=&quot;1213&quot; data-start=&quot;1168&quot;&gt;테스트 케이스 확장: Suspense fallback, 에러 처리 시나리오&lt;/li&gt;
&lt;li data-end=&quot;1234&quot; data-start=&quot;1216&quot;&gt;작은 버그/타입 오류 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1250&quot; data-start=&quot;1235&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;: 상급&lt;/li&gt;
&lt;li data-end=&quot;1313&quot; data-start=&quot;1251&quot;&gt;&lt;b&gt;추천 이유&lt;/b&gt;: React Suspense와 SSR 이해가 필요하지만, 문서/테스트 기여로 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1342&quot; data-start=&quot;1320&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1342&quot; data-start=&quot;1320&quot; data-ke-size=&quot;size23&quot;&gt;  추천 순서 (첫 PR 기준)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1562&quot; data-start=&quot;1343&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1378&quot; data-start=&quot;1343&quot;&gt;&lt;b&gt;es-hangul&lt;/b&gt; &amp;rarr; 직관적, 테스트/문서 개선&lt;/li&gt;
&lt;li data-end=&quot;1417&quot; data-start=&quot;1379&quot;&gt;&lt;b&gt;es-toolkit&lt;/b&gt; &amp;rarr; 함수 단위, 테스트/문서 개선&lt;/li&gt;
&lt;li data-end=&quot;1466&quot; data-start=&quot;1418&quot;&gt;&lt;b&gt;overlay-kit&lt;/b&gt; &amp;rarr; React Hook 이해 후 테스트/문서 기여&lt;/li&gt;
&lt;li data-end=&quot;1510&quot; data-start=&quot;1467&quot;&gt;&lt;b&gt;use-funnel&lt;/b&gt; &amp;rarr; 단계형 UI 이해 후 테스트/예제 작성&lt;/li&gt;
&lt;li data-end=&quot;1562&quot; data-start=&quot;1511&quot;&gt;&lt;b&gt;suspensive&lt;/b&gt; &amp;rarr; SSR + Suspense 이해 후 문서/테스트 기여&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 토스 오픈소스 라이브러리들의 구조와 난이도, 그리고 초보자가 접근하기 좋은 기여 포인트를 정리해보았습니다.&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;✨&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;✨&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 &lt;b&gt;es-hangul&lt;/b&gt;을 실제로 다운로드하고, 코드를 분석하며 작은 PR을 만들어보는 과정부터 시작할 예정이에요.&lt;br /&gt;테스트를 작성하고 문서를 개선하는 실습 과정을 함께 공유할 테니, 오픈소스 기여에 관심 있는 분들은 같이 따라오시면 좋습니다.&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;  참고 자료로, 최근 &lt;b&gt;토스 개발자 컨퍼런스&lt;/b&gt; 공식 홈페이지를 소개합니다.&lt;br /&gt;해당 사이트에는 컨퍼런스 영상이 순차적으로 올라오고 있어, 토스 개발 문화와 기술 스택을 직접 확인할 수 있습니다.&lt;br /&gt;오픈소스 기여와 관련된 내부 사례나 코드 리뷰 문화도 영상에서 접할 수 있으니, 관심 있는 분들은 참고하시면 좋습니다.&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;153&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://toss.im/slash-24&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toss.im/slash-24&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757904210611&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;토스 개발자 컨퍼런스 SLASH24&quot; data-og-description=&quot;참가 신청 8.23-9.2 / 본 행사 9.12 COEX&quot; data-og-host=&quot;toss.im&quot; data-og-source-url=&quot;https://toss.im/slash-24&quot; data-og-url=&quot;https://toss.im/slash-24&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pBPgE/hyZJv53NV9/T48kSUHkxhWnWh1S2rKTTK/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bj045E/hyZIT8y3JQ/LpN7TcDuDK8eCyeCctf3g1/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/kf2wI/hyZJmac0Bi/xepFDyJrkEoEeijll6t9n1/img.png?width=1437&amp;amp;height=324&amp;amp;face=0_0_1437_324&quot;&gt;&lt;a href=&quot;https://toss.im/slash-24&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toss.im/slash-24&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pBPgE/hyZJv53NV9/T48kSUHkxhWnWh1S2rKTTK/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bj045E/hyZIT8y3JQ/LpN7TcDuDK8eCyeCctf3g1/img.jpg?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/kf2wI/hyZJmac0Bi/xepFDyJrkEoEeijll6t9n1/img.png?width=1437&amp;amp;height=324&amp;amp;face=0_0_1437_324');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;토스 개발자 컨퍼런스 SLASH24&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;참가 신청 8.23-9.2 / 본 행사 9.12 COEX&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toss.im&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 로그/사이드작업실</category>
      <category>오픈소스</category>
      <category>토스오픈소스</category>
      <category>토스채용</category>
      <category>토스프론트엔드</category>
      <category>프론트성장</category>
      <category>프론트엔드</category>
      <category>프론트엔드개발</category>
      <category>프론트엔드개발자</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/92</guid>
      <comments>https://jjung2ing.tistory.com/92#entry92comment</comments>
      <pubDate>Mon, 15 Sep 2025 11:44:25 +0900</pubDate>
    </item>
    <item>
      <title>[React 공식문서 Vol.1] 리액트 설치 및 환경 구축 완벽 가이드</title>
      <link>https://jjung2ing.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 공식문서 짚어보기 1일차 시작하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 해 볼 부분은 설치하기 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;&amp;darr;&amp;darr;&amp;nbsp; &amp;nbsp; &amp;nbsp;아래 공식문서 링크 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.react.dev/learn/installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.react.dev/learn/installation&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757807093908&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;설치하기 &amp;ndash; React&quot; data-og-description=&quot;The library for web and native user interfaces&quot; data-og-host=&quot;ko.react.dev&quot; data-og-source-url=&quot;https://ko.react.dev/learn/installation&quot; data-og-url=&quot;https://ko.react.dev/learn/installation&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/JoiZO/hyZI6TlOyW/26WBYH3HHWj4Nadb8QP90k/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/b0fbUE/hyZIT8ofCi/LB1CHkXfv5Kdd1fOmTg7e1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://ko.react.dev/learn/installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.react.dev/learn/installation&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/JoiZO/hyZI6TlOyW/26WBYH3HHWj4Nadb8QP90k/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/b0fbUE/hyZIT8ofCi/LB1CHkXfv5Kdd1fOmTg7e1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;설치하기 &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The library for web and native user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #f6f7f9; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 장에서는&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #ebecf0; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a style=&quot;color: #58c4dc;&quot; href=&quot;https://ko.react.dev/learn/start-a-new-react-project&quot;&gt;새로운 React 프로젝트를 시작하는 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;color: #58c4dc;&quot; href=&quot;https://ko.react.dev/learn/add-react-to-an-existing-project&quot;&gt;기존 프로젝트에 React를 추가하는 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;color: #58c4dc;&quot; href=&quot;https://ko.react.dev/learn/editor-setup&quot;&gt;에디터를 설정하는 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;color: #58c4dc;&quot; href=&quot;https://ko.react.dev/learn/react-developer-tools&quot;&gt;React 개발자 도구를 설치하는 방법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 공식문서에 따르면 React를 실행해 볼 수 있는 방법은 크게 두 가지예요.&lt;br /&gt;바로 &quot;샌드박스&quot;와 &quot;로컬개발환경구성&quot;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;208&quot; data-start=&quot;189&quot; data-ke-size=&quot;size23&quot;&gt; ️ 샌드박스에서 실행하기&lt;/h3&gt;
&lt;p data-end=&quot;386&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 별도의 설치 없이도 온라인 코드 에디터에서 바로 실행해 볼 수 있습니다.&lt;br /&gt;예를 들&lt;span style=&quot;background-color: #ffffff;&quot;&gt;어 &lt;a style=&quot;background-color: #ffffff; color: #58c4dc; text-align: start;&quot; href=&quot;https://codesandbox.io/s/new&quot;&gt;CodeSandbox&lt;/a&gt;&lt;span style=&quot;color: #f6f7f9; text-align: start;&quot;&gt;, &lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #58c4dc; text-align: start;&quot; href=&quot;https://stackblitz.com/fork/react&quot;&gt;StackBlitz&lt;/a&gt;&lt;span style=&quot;color: #f6f7f9; text-align: start;&quot;&gt;, &lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #58c4dc; text-align: start;&quot; href=&quot;https://codepen.io/pen?template=QWYVwWN&quot;&gt;CodePen&lt;/a&gt;&amp;nbsp;&lt;/span&gt;같은 툴들이 React를 지원하기 때문에,&lt;br /&gt;처음 설치 과정이 번거롭게 느껴진다면 브라우저에서 바로 코드를 작성하고 실행해볼 수 있어요.&lt;/p&gt;
&lt;p data-end=&quot;386&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;413&quot; data-start=&quot;393&quot; data-ke-size=&quot;size23&quot;&gt;  로컬 개발 환경 구성하기&lt;/h3&gt;
&lt;p data-end=&quot;532&quot; data-start=&quot;414&quot; data-ke-size=&quot;size16&quot;&gt;하지만 결국에는 내 PC에 직접 개발 환경을 세팅하는 방법이 가장 좋아요.&lt;br /&gt;이 방식은 실제 프로젝트를 만들 때도 그대로 사용할 수 있기 때문에, React를 본격적으로 배우려면 꼭 거쳐야 하는 과정입니다.&lt;/p&gt;
&lt;p data-end=&quot;564&quot; data-start=&quot;534&quot; data-ke-size=&quot;size16&quot;&gt;로컬 환경을 꾸미려면 보통 다음 과정이 필요합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;689&quot; data-start=&quot;565&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;584&quot; data-start=&quot;565&quot;&gt;&lt;b&gt;Node.js 설치&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;646&quot; data-start=&quot;585&quot;&gt;&lt;b&gt;프로젝트 생성 도구 사용 (예: Create React App, Vite, Next.js 등)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;689&quot; data-start=&quot;647&quot;&gt;&lt;b&gt;코드 에디터 준비 (Visual Studio Code 추천)&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;173&quot; data-start=&quot;153&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ Node.js 설치하기&lt;/h3&gt;
&lt;p data-end=&quot;332&quot; data-start=&quot;174&quot; data-ke-size=&quot;size16&quot;&gt;React는 자바스크립트 기반 라이브러리이기 때문에 &lt;b&gt;Node.js&lt;/b&gt;가 꼭 필요합니다.&lt;br /&gt;&lt;a data-end=&quot;264&quot; data-start=&quot;227&quot;&gt;Node.js 공식 사이트&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;에 들어가면 &lt;b&gt;LTS(Long Term Support)&lt;/b&gt; 버전과 &lt;b&gt;Current&lt;/b&gt; 버전 두 가지가 보일 거예요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;483&quot; data-start=&quot;334&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;423&quot; data-start=&quot;334&quot;&gt;&lt;b&gt;LTS(Long Term Support)&lt;/b&gt; : 장기 지원 버전으로, 안정성과 호환성이 보장됩니다. 기업이나 프로젝트에서 실무에 가장 많이 사용해요.&lt;/li&gt;
&lt;li data-end=&quot;483&quot; data-start=&quot;424&quot;&gt;&lt;b&gt;Current&lt;/b&gt; : 최신 기능이 포함된 버전이지만, 안정성보다는 새 기능 테스트에 가깝습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;541&quot; data-start=&quot;485&quot; data-ke-size=&quot;size16&quot;&gt;  React를 배우고 실제 프로젝트를 진행하려면 &lt;b&gt;LTS 버전&lt;/b&gt;을 설치하는 게 안전합니다.&lt;/p&gt;
&lt;p data-end=&quot;582&quot; data-start=&quot;543&quot; data-ke-size=&quot;size16&quot;&gt;설치가 잘 되었는지 확인하려면 터미널에서 다음 명령어를 입력합니다:&lt;/p&gt;
&lt;pre id=&quot;code_1757808022116&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;node -v
npm -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;663&quot; data-start=&quot;574&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;504&quot; data-start=&quot;487&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 프로젝트 생성하기&lt;/h3&gt;
&lt;p data-end=&quot;545&quot; data-start=&quot;505&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서 React 프로젝트를 시작하는 방법은 여러 가지가 있습니다.&lt;/p&gt;
&lt;h4 data-end=&quot;577&quot; data-start=&quot;547&quot; data-ke-size=&quot;size20&quot;&gt;  Create React App (CRA)&lt;/h4&gt;
&lt;p data-end=&quot;613&quot; data-start=&quot;578&quot; data-ke-size=&quot;size16&quot;&gt;가장 전통적인 방식으로, 초보자도 쉽게 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757808079267&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx create-react-app my-app
cd my-app
npm start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm install 따로 안 해줘도 되나?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 &lt;b&gt;npx create-react-app my-app&lt;/b&gt; 명령어 안에는 이미 설치 과정이 포함되어 있어서 따로 설치할 필요가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 사용되는 npx는 npm 패키지를 로컬에 설치하지 않아도 바로 실행할 수 있게 해주는 도구예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;하지만, 공식문서에도 있다시피 CRA는 더 이상 사용되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-14 오전 9.03.16.png&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccfALu/btsQzd1E5hQ/D4yaDS9X8YcruKgLtLFyp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccfALu/btsQzd1E5hQ/D4yaDS9X8YcruKgLtLFyp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccfALu/btsQzd1E5hQ/D4yaDS9X8YcruKgLtLFyp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccfALu%2FbtsQzd1E5hQ%2FD4yaDS9X8YcruKgLtLFyp0%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;1362&quot; height=&quot;682&quot; data-filename=&quot;스크린샷 2025-09-14 오전 9.03.16.png&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;222&quot; data-start=&quot;186&quot; data-ke-size=&quot;size26&quot;&gt; ️ Create React App(CRA)의 등장과 퇴장&lt;/h2&gt;
&lt;p data-end=&quot;246&quot; data-start=&quot;224&quot; data-ke-size=&quot;size16&quot;&gt;  CRA의 탄생 (2016년)&lt;/p&gt;
&lt;p data-end=&quot;350&quot; data-start=&quot;247&quot; data-ke-size=&quot;size16&quot;&gt;2016년, React 팀은 &lt;b&gt;Create React App(CRA)을&lt;/b&gt; 처음 공개했습니다.&lt;br /&gt;그 당시에는 React 앱을 새로 만들기 위한 &lt;b&gt;표준적인 방법이 없었어요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;402&quot; data-start=&quot;352&quot; data-ke-size=&quot;size16&quot;&gt;React를 시작하려면 직접 다음과 같은 도구들을 하나하나 설치하고 연결해야 했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;451&quot; data-start=&quot;403&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;403&quot;&gt;JSX 컴파일러&lt;/li&gt;
&lt;li data-end=&quot;430&quot; data-start=&quot;416&quot;&gt;Linting 도구&lt;/li&gt;
&lt;li data-end=&quot;451&quot; data-start=&quot;431&quot;&gt;Hot Reloading 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;453&quot; data-ke-size=&quot;size16&quot;&gt;이 과정은 굉장히 까다롭고 복잡했습니다.&lt;br /&gt;그래서 커뮤니티에서는 자주 사용하는 설정을 묶어 &lt;b&gt;보일러플레이트(boilerplate)를&lt;/b&gt; 만들었지만,&lt;br /&gt;업데이트가 어렵고 설정이 조각나 있어서 React 팀이 새로운 기능을 배포하기 힘들었죠.&lt;/p&gt;
&lt;p data-end=&quot;734&quot; data-start=&quot;594&quot; data-ke-size=&quot;size16&quot;&gt;CRA는 이런 문제를 해결했습니다.&lt;br /&gt;여러 도구를 하나의 권장 설정으로 통합해 주었고,&lt;br /&gt;React 팀이 &lt;b&gt;Fast Refresh 지원, Hooks Lint 규칙&lt;/b&gt; 같은 새로운 기능을&lt;br /&gt;쉽게 많은 사용자에게 배포할 수 있도록 도와주었습니다.&lt;/p&gt;
&lt;hr data-end=&quot;739&quot; data-start=&quot;736&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;762&quot; data-start=&quot;741&quot; data-ke-size=&quot;size23&quot;&gt;  CRA의 한계와 지원 종료&lt;/h3&gt;
&lt;p data-end=&quot;838&quot; data-start=&quot;763&quot; data-ke-size=&quot;size16&quot;&gt;CRA는 초보자가 React를 &lt;b&gt;쉽게 시작할 수 있도록&lt;/b&gt; 큰 역할을 했습니다.&lt;br /&gt;하지만 시간이 지나면서 한계가 뚜렷해졌습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;942&quot; data-start=&quot;840&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;840&quot;&gt;빌드 속도가 느려 대규모 앱에는 비효율적&lt;/li&gt;
&lt;li data-end=&quot;914&quot; data-start=&quot;867&quot;&gt;최신 개발 트렌드(예: 서버 사이드 렌더링, 코드 스플리팅 등) 반영이 어려움&lt;/li&gt;
&lt;li data-end=&quot;942&quot; data-start=&quot;915&quot;&gt;유지보수 담당자가 사라지면서 업데이트 정체&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1046&quot; data-start=&quot;944&quot; data-ke-size=&quot;size16&quot;&gt;React 팀은 CRA를 프레임워크로 발전시켜 문제를 해결할 수도 있었지만,&lt;br /&gt;이미 &lt;b&gt;Next.js, Remix, Vite&lt;/b&gt; 같은 강력한 대안들이 자리를 잡은 상황이었습니다.&lt;/p&gt;
&lt;p data-end=&quot;1138&quot; data-start=&quot;1048&quot; data-ke-size=&quot;size16&quot;&gt;결국 React 팀은 &lt;b&gt;CRA의 지원 종료&lt;/b&gt;를 결정했습니다.&lt;br /&gt;이제 새로운 앱을 설치할 때 CRA를 사용하면 &lt;b&gt;지원 종료 경고 메시지&lt;/b&gt;가 표시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요새 대부분 마이그레이션을 하는 추세예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;147&quot; data-start=&quot;113&quot; data-ke-size=&quot;size26&quot;&gt;  CRA를 꼭 알아야 마이그레이션 할 수 있을까?&lt;/h2&gt;
&lt;p data-end=&quot;176&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;1. CRA를 몰라도 마이그레이션 가능 ✅&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;320&quot; data-start=&quot;177&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;235&quot; data-start=&quot;177&quot;&gt;CRA 프로젝트는 기본적으로 &lt;b&gt;Webpack + Babel 기반&lt;/b&gt;의 설정을 감춰둔 구조입니다.&lt;/li&gt;
&lt;li data-end=&quot;287&quot; data-start=&quot;236&quot;&gt;실제 마이그레이션은 대부분 &lt;b&gt;의존성 패키지 교체 + 빌드 도구 전환&lt;/b&gt; 작업이에요.&lt;/li&gt;
&lt;li data-end=&quot;320&quot; data-start=&quot;288&quot;&gt;그래서 CRA 내부 설정을 다 알 필요는 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;즉, &amp;ldquo;CRA가 내부적으로 어떻게 동작하는지&amp;rdquo;까지 알 필요는 없어요.&lt;/p&gt;
&lt;hr data-end=&quot;367&quot; data-start=&quot;364&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;399&quot; data-start=&quot;369&quot; data-ke-size=&quot;size16&quot;&gt;2. 하지만 CRA 구조를 조금 알면 이득 ⬆️&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;664&quot; data-start=&quot;400&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;477&quot; data-start=&quot;400&quot;&gt;CRA는 src/, public/ 폴더 구조와 index.js 진입 파일 등 &lt;b&gt;표준 프로젝트 구조&lt;/b&gt;를 가지고 있어요.&lt;/li&gt;
&lt;li data-end=&quot;533&quot; data-start=&quot;478&quot;&gt;이 구조를 이해하면 Vite나 Next.js로 옮길 때 &lt;b&gt;파일 매핑&lt;/b&gt;이 훨씬 수월합니다.&lt;/li&gt;
&lt;li data-end=&quot;664&quot; data-start=&quot;534&quot;&gt;예를 들어:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;664&quot; data-start=&quot;547&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;596&quot; data-start=&quot;547&quot;&gt;CRA의 public/index.html &amp;rarr; Vite의 index.html&lt;/li&gt;
&lt;li data-end=&quot;664&quot; data-start=&quot;599&quot;&gt;CRA의 index.js &amp;rarr; Vite/Next.js의 진입점(main.jsx or _app.tsx)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;669&quot; data-start=&quot;666&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;690&quot; data-start=&quot;671&quot; data-ke-size=&quot;size16&quot;&gt;3. 마이그레이션 접근 방식&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;940&quot; data-start=&quot;691&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;810&quot; data-start=&quot;691&quot;&gt;&lt;b&gt;CRA &amp;rarr; Vite&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;810&quot; data-start=&quot;712&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;732&quot; data-start=&quot;712&quot;&gt;폴더 구조 비슷, 비교적 단순&lt;/li&gt;
&lt;li data-end=&quot;770&quot; data-start=&quot;735&quot;&gt;react-scripts 제거 후 Vite 설정 추가&lt;/li&gt;
&lt;li data-end=&quot;810&quot; data-start=&quot;773&quot;&gt;babel 대신 Vite의 esbuild/rollup을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;940&quot; data-start=&quot;811&quot;&gt;&lt;b&gt;CRA &amp;rarr; Next.js&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;940&quot; data-start=&quot;835&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;882&quot; data-start=&quot;835&quot;&gt;라우팅, 서버 기능이 다르므로 단순 교체보다는 &lt;b&gt;프로젝트 구조 개편&lt;/b&gt; 필요&lt;/li&gt;
&lt;li data-end=&quot;940&quot; data-start=&quot;885&quot;&gt;하지만 CRA 내부를 몰라도 Next.js 공식 문서의 &amp;ldquo;마이그레이션 가이드&amp;rdquo;만 따르면 충분&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;196&quot; data-start=&quot;176&quot; data-ke-size=&quot;size26&quot;&gt;  CRA에서 마이그레이션 하기&lt;/h2&gt;
&lt;p data-end=&quot;280&quot; data-start=&quot;198&quot; data-ke-size=&quot;size16&quot;&gt;CRA의 지원이 종료되면서, 이제는 새로운 프로젝트를 시작하거나 기존 앱을 이어가려면 &lt;b&gt;프레임워크&lt;/b&gt; 또는 &lt;b&gt;빌드 도구&lt;/b&gt;로 옮겨야 합니다.&lt;/p&gt;
&lt;hr data-end=&quot;285&quot; data-start=&quot;282&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;317&quot; data-start=&quot;287&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ 프레임워크로 마이그레이션 하기 (추천 ⭐)&lt;/h3&gt;
&lt;p data-end=&quot;400&quot; data-start=&quot;318&quot; data-ke-size=&quot;size16&quot;&gt;React 팀은 새로운 앱을 만들 때 &lt;b&gt;프레임워크 기반으로 시작&lt;/b&gt;하는 걸 권장합니다.&lt;br /&gt;추천되는 모든 프레임워크는 다음 특징을 지원합니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;477&quot; data-start=&quot;402&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;424&quot; data-start=&quot;402&quot;&gt;클라이언트 사이드 렌더링(CSR)&lt;/li&gt;
&lt;li data-end=&quot;442&quot; data-start=&quot;425&quot;&gt;단일 페이지 앱(SPA)&lt;/li&gt;
&lt;li data-end=&quot;477&quot; data-start=&quot;443&quot;&gt;CDN 또는 정적 호스팅 서비스에 서버 없이 배포 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;545&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;CRA로 하던 방식은 그대로 유지하면서도&lt;/b&gt; 프레임워크가 제공하는 강력한 기능들을 더 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;566&quot; data-start=&quot;547&quot; data-ke-size=&quot;size16&quot;&gt;  공식 마이그레이션 가이드:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;835&quot; data-start=&quot;567&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;677&quot; data-start=&quot;567&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/app/guides/migrating/from-create-react-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;675&quot; data-start=&quot;569&quot;&gt;Next.js의 CRA 마이그레이션 가이드&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;758&quot; data-start=&quot;678&quot;&gt;&lt;a href=&quot;https://reactrouter.com/upgrading/component-routes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;756&quot; data-start=&quot;680&quot;&gt;React Router의 프레임워크 도입 가이드&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;835&quot; data-start=&quot;759&quot;&gt;&lt;a href=&quot;https://docs.expo.dev/router/migrate/from-expo-webpack/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;833&quot; data-start=&quot;761&quot;&gt;Expo: 웹팩에서 Expo Router로 마이그레이션&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;840&quot; data-start=&quot;837&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;883&quot; data-start=&quot;842&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 빌드 도구로 마이그레이션하기 (커스텀 세팅이 필요할 때)&lt;/h3&gt;
&lt;p data-end=&quot;991&quot; data-start=&quot;884&quot; data-ke-size=&quot;size16&quot;&gt;만약 앱이 특수한 제약 조건을 가지고 있거나, 직접 프레임워크를 만들고 싶은 경우, 혹은 React가 처음부터 어떻게 동작하는지 배우고 싶다면 &lt;b&gt;빌드 도구를 직접 선택&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1006&quot; data-start=&quot;993&quot; data-ke-size=&quot;size16&quot;&gt;대표적인 빌드 도구:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1109&quot; data-start=&quot;1007&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1035&quot; data-start=&quot;1007&quot;&gt;&lt;b&gt;Vite&lt;/b&gt; &amp;rarr; 빠른 빌드, 간단한 설정&lt;/li&gt;
&lt;li data-end=&quot;1074&quot; data-start=&quot;1036&quot;&gt;&lt;b&gt;Parcel&lt;/b&gt; &amp;rarr; 제로 설정(Zero-config) 철학&lt;/li&gt;
&lt;li data-end=&quot;1109&quot; data-start=&quot;1075&quot;&gt;&lt;b&gt;RSBuild&lt;/b&gt; &amp;rarr; 최신 Rust 기반 빌드 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1130&quot; data-start=&quot;1111&quot; data-ke-size=&quot;size16&quot;&gt;  공식 마이그레이션 가이드:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1302&quot; data-start=&quot;1131&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1198&quot; data-start=&quot;1131&quot;&gt;&lt;a href=&quot;https://www.robinwieruch.de/vite-create-react-app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;1196&quot; data-start=&quot;1133&quot;&gt;Vite의 CRA 마이그레이션 가이드&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;1250&quot; data-start=&quot;1199&quot;&gt;&lt;a href=&quot;https://parceljs.org/migration/cra/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;1248&quot; data-start=&quot;1201&quot;&gt;Parcel의 CRA 마이그레이션 가이드&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;1302&quot; data-start=&quot;1251&quot;&gt;&lt;a href=&quot;https://rsbuild.rs/guide/migration/cra&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-end=&quot;1300&quot; data-start=&quot;1253&quot;&gt;RSBuild의 CRA 마이그레이션 가이드&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1384&quot; data-start=&quot;1304&quot; data-ke-size=&quot;size16&quot;&gt;또한 React 팀은 &lt;b&gt;Vite, Parcel, RSBuild로&lt;/b&gt; 앱을 새로 시작하는 데 도움을 주는 문서를 별도로 추가해 두었습니다.&lt;/p&gt;
&lt;p data-end=&quot;1384&quot; data-start=&quot;1304&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;686&quot; data-start=&quot;675&quot; data-ke-size=&quot;size20&quot;&gt;⚡ Vite&lt;/h4&gt;
&lt;p data-end=&quot;737&quot; data-start=&quot;687&quot; data-ke-size=&quot;size16&quot;&gt;요즘은 &lt;b&gt;빠른 빌드 속도&lt;/b&gt;와 &lt;b&gt;가벼운 설정&lt;/b&gt; 때문에 Vite를 많이 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757808106492&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm create vite@latest my-app
cd my-app
npm install
npm run dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;99&quot; data-start=&quot;71&quot; data-ke-size=&quot;size23&quot;&gt;1. Vite 설치 및 프로젝트 생성 방법&lt;/h3&gt;
&lt;h4 data-end=&quot;118&quot; data-start=&quot;101&quot; data-ke-size=&quot;size20&quot;&gt;방법 1: npx 사용&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;npx create-vite@latest my-app &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;280&quot; data-start=&quot;161&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;193&quot; data-start=&quot;161&quot;&gt;CRA처럼 &lt;b&gt;패키지를 임시로 다운로드&lt;/b&gt;해서 실행&lt;/li&gt;
&lt;li data-end=&quot;229&quot; data-start=&quot;194&quot;&gt;프로젝트 폴더(my-app) 생성 후 기본 세팅 완료&lt;/li&gt;
&lt;li data-end=&quot;280&quot; data-start=&quot;230&quot;&gt;이후 cd my-app &amp;rarr; npm install &amp;rarr; npm run dev&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;312&quot; data-start=&quot;282&quot; data-ke-size=&quot;size20&quot;&gt;방법 2: npm init 사용 (최신 권장)&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;npm create vite@latest my-app &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;454&quot; data-start=&quot;355&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;374&quot; data-start=&quot;355&quot;&gt;사실상 npx와 동일한 기능&lt;/li&gt;
&lt;li data-end=&quot;403&quot; data-start=&quot;375&quot;&gt;최신 Vite 문서에서는 이 방법을 더 권장&lt;/li&gt;
&lt;li data-end=&quot;454&quot; data-start=&quot;404&quot;&gt;이유: npm create &amp;lt;패키지&amp;gt;가 npx보다 명확하게 최신 버전을 설치해 줌&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;459&quot; data-start=&quot;456&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;474&quot; data-start=&quot;461&quot; data-ke-size=&quot;size23&quot;&gt;2. 실행 과정&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;602&quot; data-start=&quot;475&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;520&quot; data-start=&quot;475&quot;&gt;프로젝트 생성: npm create vite@latest my-app&lt;/li&gt;
&lt;li data-end=&quot;546&quot; data-start=&quot;521&quot;&gt;디렉터리 이동: cd my-app&lt;/li&gt;
&lt;li data-end=&quot;573&quot; data-start=&quot;547&quot;&gt;의존성 설치: npm install&lt;/li&gt;
&lt;li data-end=&quot;602&quot; data-start=&quot;574&quot;&gt;개발 서버 실행: npm run dev&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-end=&quot;733&quot; data-start=&quot;604&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;733&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;CRA와 달리 Vite는 &lt;b&gt;프로젝트 생성 후 의존성을 별도로 설치&lt;/b&gt;해야 합니다.&lt;br /&gt;CRA는 npx create-react-app 명령어 안에서 자동으로 설치까지 해주지만, Vite는 한 단계가 추가되는 구조예요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;830&quot; data-start=&quot;815&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;830&quot; data-start=&quot;815&quot; data-ke-size=&quot;size20&quot;&gt;  Next.js&lt;/h4&gt;
&lt;p data-end=&quot;883&quot; data-start=&quot;831&quot; data-ke-size=&quot;size16&quot;&gt;서버 사이드 렌더링과 라우팅까지 제공하는 프레임워크를 쓰고 싶다면 Next.js가 좋아요.&lt;/p&gt;
&lt;pre id=&quot;code_1757808121028&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx create-next-app@latest my-app
cd my-app
npm run dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;975&quot; data-start=&quot;958&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ 코드 에디터 준비&lt;/h3&gt;
&lt;p data-end=&quot;1137&quot; data-start=&quot;976&quot; data-ke-size=&quot;size16&quot;&gt;개발을 편하게 하려면 &lt;b&gt;Visual Studio Code(VS Code)&lt;/b&gt; 같은 코드 에디터를 설치하는 게 좋아요.&lt;br /&gt;여기에 React 관련 확장 프로그램(예: ES7+ React/Redux/React-Native snippets, Prettier 등)을 추가하면 더 편리합니다.&lt;/p&gt;
&lt;p data-end=&quot;1137&quot; data-start=&quot;976&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1137&quot; data-start=&quot;976&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;1137&quot; data-start=&quot;976&quot; data-ke-size=&quot;size23&quot;&gt; ️ Custom Toolchain&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 알기 쉽게 간단히 요약하고 아래에 자세히 한번 알아볼게요.&lt;/p&gt;
&lt;h2 data-end=&quot;97&quot; data-start=&quot;69&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ React 개발 환경의 역할별 도구 구조&lt;/h2&gt;
&lt;p data-end=&quot;172&quot; data-start=&quot;99&quot; data-ke-size=&quot;size16&quot;&gt;React 앱을 개발할 때, 여러 도구가 각자 역할을 나눠 수행합니다.&lt;br /&gt;한눈에 이해하기 쉽게 기호와 단계로 정리해 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757810696018&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  패키지 매니저
└─ npm / yarn / pnpm
   &amp;rarr; 프로젝트 생성, 라이브러리 설치/관리

  컴파일러(Transpiler)
└─ Babel / TypeScript / esbuild
   &amp;rarr; JSX, 최신 JS, TS를 브라우저가 이해할 수 있는 JS로 변환

  번들러(Bundler)
└─ Webpack / esbuild / Rollup / Parcel
   &amp;rarr; 여러 파일(JS, CSS, 이미지)을 하나 또는 몇 개로 묶고 최적화

  개발 서버(Dev Server)
└─ CRA: react-scripts start
└─ Vite: vite dev server
└─ Next.js: next dev
   &amp;rarr; 코드 변경 시 자동 반영, Hot Reload 지원

  Lint &amp;amp; Formatter
└─ ESLint / Prettier
   &amp;rarr; 코드 스타일 검증, 문법 오류 확인

  테스트 도구
└─ Jest / Vitest
   &amp;rarr; 단위 테스트, 통합 테스트 수행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;172&quot; data-start=&quot;99&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-start=&quot;102&quot; data-end=&quot;118&quot; data-ke-size=&quot;size20&quot;&gt;  패키지 매니저란?&lt;/h4&gt;
&lt;p data-start=&quot;119&quot; data-end=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;Node.js를 설치하면 함께&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;npm(Node Package Manager)이라는&lt;/b&gt; 패키지 매니저가 따라옵니다.&lt;br /&gt;패키지 매니저는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;리액트 같은 라이브러리를 설치하고 관리해 주는&lt;/b&gt; 도구예요.&lt;/p&gt;
&lt;p data-start=&quot;119&quot; data-end=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-start=&quot;235&quot; data-end=&quot;258&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로는 다음 세 가지가 있습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;260&quot; data-end=&quot;572&quot;&gt;
&lt;li data-start=&quot;260&quot; data-end=&quot;349&quot;&gt;&lt;b&gt;npm&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;274&quot; data-end=&quot;349&quot;&gt;
&lt;li data-start=&quot;274&quot; data-end=&quot;296&quot;&gt;Node.js 기본 패키지 매니저&lt;/li&gt;
&lt;li data-start=&quot;299&quot; data-end=&quot;333&quot;&gt;따로 설치할 필요 없음 (Node 설치 시 자동 포함)&lt;/li&gt;
&lt;li data-start=&quot;336&quot; data-end=&quot;349&quot;&gt;가장 널리 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-start=&quot;351&quot; data-end=&quot;461&quot;&gt;&lt;b&gt;yarn&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;366&quot; data-end=&quot;461&quot;&gt;
&lt;li data-start=&quot;366&quot; data-end=&quot;399&quot;&gt;Meta(구 Facebook)에서 만든 패키지 매니저&lt;/li&gt;
&lt;li data-start=&quot;402&quot; data-end=&quot;436&quot;&gt;npm보다 속도가 빠르고, 설치 과정에서 안정성을 강조&lt;/li&gt;
&lt;li data-start=&quot;439&quot; data-end=&quot;461&quot;&gt;팀 단위 프로젝트에서 종종 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-start=&quot;463&quot; data-end=&quot;572&quot;&gt;&lt;b&gt;pnpm&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;478&quot; data-end=&quot;572&quot;&gt;
&lt;li data-start=&quot;478&quot; data-end=&quot;509&quot;&gt;디스크 공간을 효율적으로 쓰는 최신 패키지 매니저&lt;/li&gt;
&lt;li data-start=&quot;512&quot; data-end=&quot;540&quot;&gt;동일한 패키지를 여러 프로젝트에서 공유 가능&lt;/li&gt;
&lt;li data-start=&quot;543&quot; data-end=&quot;572&quot;&gt;속도도 빠르고 최근에 점점 인기가 올라가는 중&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-start=&quot;574&quot; data-end=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;  처음 시작하는 단계라면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;npm 그대로 사용&lt;/b&gt;해도 충분합니다.&lt;br /&gt;필요에 따라 yarn이나 pnpm을 선택할 수도 있다는 정도만 알고 계시면 돼요.&lt;/p&gt;
&lt;p data-start=&quot;574&quot; data-end=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-start=&quot;574&quot; data-end=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;그럼 패키지 매니저 선택 시점은 언제일까요?&lt;/p&gt;
&lt;p data-end=&quot;86&quot; data-start=&quot;67&quot; data-ke-size=&quot;size16&quot;&gt;  패키지 매니저 선택 시점&lt;/p&gt;
&lt;p data-end=&quot;139&quot; data-start=&quot;88&quot; data-ke-size=&quot;size16&quot;&gt;보통 React 프로젝트를 시작할 때 &lt;b&gt;패키지 매니저는 프로젝트 생성 직전에 선택&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-end=&quot;164&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;164&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;1️⃣ 프로젝트 생성 도구 실행 전&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;394&quot; data-start=&quot;165&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;238&quot; data-start=&quot;165&quot;&gt;CRA, Vite, Next.js 등 프로젝트 생성 명령어를 실행하기 전에&lt;br /&gt;자신이 사용할 패키지 매니저를 결정합니다.&lt;/li&gt;
&lt;li data-end=&quot;394&quot; data-start=&quot;239&quot;&gt;예시:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;394&quot; data-start=&quot;249&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;293&quot; data-start=&quot;249&quot;&gt;npm &amp;rarr; CRA: npx create-react-app my-app&lt;/li&gt;
&lt;li data-end=&quot;342&quot; data-start=&quot;296&quot;&gt;yarn &amp;rarr; CRA: yarn create react-app my-app&lt;/li&gt;
&lt;li data-end=&quot;394&quot; data-start=&quot;345&quot;&gt;pnpm &amp;rarr; Vite: pnpm create vite@latest my-app&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;472&quot; data-start=&quot;396&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;472&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;패키지 매니저에 따라 생성 후 설치 명령어(npm install / yarn / pnpm install)가 달라집니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;2️⃣ 프로젝트 생성 후&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;749&quot; data-start=&quot;497&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;541&quot; data-start=&quot;497&quot;&gt;프로젝트 생성 과정에서 패키지 매니저가 설치와 의존성 관리를 담당합니다.&lt;/li&gt;
&lt;li data-end=&quot;663&quot; data-start=&quot;542&quot;&gt;이후 모든 &lt;b&gt;패키지 추가, 삭제, 실행 명령&lt;/b&gt;은 선택한 패키지 매니저로 실행합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;663&quot; data-start=&quot;597&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;663&quot; data-start=&quot;597&quot;&gt;예: npm install axios vs yarn add axios vs pnpm add axios&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;749&quot; data-start=&quot;664&quot;&gt;이미 프로젝트를 시작한 뒤 다른 매니저로 바꾸는 것도 가능하지만,&lt;br /&gt;의존성 관리 방식이 달라 &lt;b&gt;충돌이 생길 수 있어 추천하지 않습니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;769&quot; data-start=&quot;756&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;769&quot; data-start=&quot;756&quot; data-ke-size=&quot;size16&quot;&gt;3️⃣ 선택 기준&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;887&quot; data-start=&quot;770&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;801&quot; data-start=&quot;770&quot;&gt;&lt;b&gt;팀에서 표준화된 매니저가 있다면 그걸 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;829&quot; data-start=&quot;802&quot;&gt;&lt;b&gt;초보자 / 단순 프로젝트&lt;/b&gt; &amp;rarr; npm&lt;/li&gt;
&lt;li data-end=&quot;862&quot; data-start=&quot;830&quot;&gt;&lt;b&gt;속도와 캐싱 효율&lt;/b&gt; &amp;rarr; yarn 또는 pnpm&lt;/li&gt;
&lt;li data-end=&quot;887&quot; data-start=&quot;863&quot;&gt;&lt;b&gt;디스크 공간 효율&lt;/b&gt; &amp;rarr; pnpm&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-start=&quot;574&quot; data-end=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;75&quot; data-start=&quot;54&quot; data-ke-size=&quot;size26&quot;&gt; ️ React에서 컴파일러란?&lt;/h2&gt;
&lt;p data-end=&quot;214&quot; data-start=&quot;77&quot; data-ke-size=&quot;size16&quot;&gt;React 자체는 브라우저에서 바로 실행 가능한 자바스크립트 라이브러리입니다.&lt;br /&gt;그런데 우리가 작성하는 코드에는 &lt;b&gt;최신 자바스크립트 문법, JSX, TypeScript&lt;/b&gt; 등이 포함되어 있어서&lt;br /&gt;브라우저가 이해하지 못하는 경우가 많아요.&lt;/p&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;이때 등장하는 것이 컴파일러(Transpiler)입니다.&lt;/p&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;컴파일러는 다음 작업을 수행합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;571&quot; data-start=&quot;292&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;410&quot; data-start=&quot;292&quot;&gt;&lt;b&gt;JSX &amp;rarr; JavaScript 변환&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1757809680152&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const element = &amp;lt;h1&amp;gt;Hello, React!&amp;lt;/h1&amp;gt;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;410&quot; data-start=&quot;292&quot;&gt;&amp;rarr; 브라우저가 이해할 수 있는 JS 코드로 변환&lt;/li&gt;
&lt;li data-end=&quot;502&quot; data-start=&quot;412&quot;&gt;&lt;b&gt;최신 JS 문법 변환&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;502&quot; data-start=&quot;436&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;502&quot; data-start=&quot;436&quot;&gt;ES6+ 문법 (예: import, const, arrow function) &amp;rarr; 호환 가능한 코드로 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;571&quot; data-start=&quot;504&quot;&gt;&lt;b&gt;TypeScript &amp;rarr; JavaScript 변환&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;571&quot; data-start=&quot;543&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;571&quot; data-start=&quot;543&quot;&gt;타입 정보를 제거하고 순수 JS 코드로 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;593&quot; data-start=&quot;578&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-end=&quot;593&quot; data-start=&quot;578&quot; data-ke-size=&quot;size16&quot;&gt;대표 컴파일러&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;728&quot; data-start=&quot;594&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;631&quot; data-start=&quot;594&quot;&gt;&lt;b&gt;Babel&lt;/b&gt;: CRA, Vite 등에서 기본적으로 사용&lt;/li&gt;
&lt;li data-end=&quot;686&quot; data-start=&quot;632&quot;&gt;&lt;b&gt;TypeScript Compiler(tsc)&lt;/b&gt;: TypeScript 프로젝트에서 사용&lt;/li&gt;
&lt;li data-end=&quot;728&quot; data-start=&quot;687&quot;&gt;&lt;b&gt;esbuild&lt;/b&gt;: Vite 등 최신 빌드 도구에서 빠른 변환용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 식으로 동작하냐면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자&amp;nbsp;코드(JSX,&amp;nbsp;TS)&amp;nbsp;&amp;rarr;&amp;nbsp;컴파일러(Babel/esbuild/tsc)&amp;nbsp;&amp;rarr;&amp;nbsp;브라우저가&amp;nbsp;이해&amp;nbsp;가능한&amp;nbsp;JS&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;822&quot;&gt;즉, &lt;b&gt;컴파일러는 브라우저가 이해하지 못하는 코드를 변환해 주는&lt;/b&gt; 역할&lt;/li&gt;
&lt;li data-end=&quot;928&quot; data-start=&quot;867&quot;&gt;React 개발 환경에서는 거의 항상 &lt;b&gt;자동으로 설정되어 있어서 개발자가 따로 설치할 필요는 없음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;110&quot; data-start=&quot;73&quot; data-ke-size=&quot;size26&quot;&gt; ️ CRA vs Vite vs Next.js 컴파일러 비교&lt;/h2&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;React 프로젝트를 만들 때 &lt;b&gt;어떤 컴파일러가 쓰이는지&lt;/b&gt;에 따라 빌드 속도와 개발 경험이 달라집니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 99.5349%; height: 381px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-start=&quot;175&quot; data-end=&quot;733&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;프로젝트 도구&lt;/b&gt;&lt;/td&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-start=&quot;258&quot; data-end=&quot;414&quot;&gt;
&lt;td data-start=&quot;258&quot; data-end=&quot;287&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;CRA (Create React App)&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;287&quot; data-end=&quot;295&quot; data-col-size=&quot;sm&quot;&gt;Babel&lt;/td&gt;
&lt;td data-start=&quot;295&quot; data-end=&quot;375&quot; data-col-size=&quot;md&quot;&gt;- JSX, 최신 JS 문법을 브라우저 호환 코드로 변환&lt;br /&gt;- 프로젝트 생성 시 자동 설정&lt;br /&gt;- 개발 서버 Hot Reload 지원&lt;/td&gt;
&lt;td data-start=&quot;375&quot; data-end=&quot;414&quot; data-col-size=&quot;md&quot;&gt;- 빌드 속도가 비교적 느림&lt;br /&gt;- 설정 커스터마이징이 제한적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;415&quot; data-end=&quot;577&quot;&gt;
&lt;td data-start=&quot;415&quot; data-end=&quot;426&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;Vite&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;426&quot; data-end=&quot;444&quot; data-col-size=&quot;sm&quot;&gt;esbuild + Babel&lt;/td&gt;
&lt;td data-start=&quot;444&quot; data-end=&quot;523&quot; data-col-size=&quot;md&quot;&gt;- esbuild가 빠른 변환 제공 &amp;rarr; 개발 서버 매우 빠름&lt;br /&gt;- 일부 고급 변환은 Babel 사용&lt;br /&gt;- TypeScript 지원&lt;/td&gt;
&lt;td data-start=&quot;523&quot; data-end=&quot;577&quot; data-col-size=&quot;md&quot;&gt;- CRA보다 초기 설정 자유도가 높음&lt;br /&gt;- 일부 Babel 플러그인 호환성 확인 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;578&quot; data-end=&quot;733&quot;&gt;
&lt;td data-start=&quot;578&quot; data-end=&quot;592&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;Next.js&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;592&quot; data-end=&quot;606&quot; data-col-size=&quot;sm&quot;&gt;Babel + SWC&lt;/td&gt;
&lt;td data-start=&quot;606&quot; data-end=&quot;681&quot; data-col-size=&quot;md&quot;&gt;- SWC(Speedy Web Compiler)로 빠른 빌드&lt;br /&gt;- SSR, SSG 지원&lt;br /&gt;- JSX, TS 변환 모두 처리&lt;/td&gt;
&lt;td data-start=&quot;681&quot; data-end=&quot;733&quot; data-col-size=&quot;md&quot;&gt;- SWC는 일부 고급 Babel 플러그인 미지원&lt;br /&gt;- 서버 렌더링 관련 설정 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;121&quot; data-start=&quot;93&quot; data-ke-size=&quot;size20&quot;&gt; ️ 기본 컴파일러와 커스터마이징 가능 여부&lt;/h4&gt;
&lt;h4 data-end=&quot;153&quot; data-start=&quot;123&quot; data-ke-size=&quot;size20&quot;&gt;1. CRA (Create React App)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;441&quot; data-start=&quot;154&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;176&quot; data-start=&quot;154&quot;&gt;&lt;b&gt;기본 컴파일러&lt;/b&gt;: Babel&lt;/li&gt;
&lt;li data-end=&quot;401&quot; data-start=&quot;177&quot;&gt;&lt;b&gt;변경 가능 여부&lt;/b&gt;: 제한적
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;401&quot; data-start=&quot;201&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;248&quot; data-start=&quot;201&quot;&gt;CRA는 &lt;b&gt;설정이 숨겨져 있음&lt;/b&gt;(react-scripts 내부에 설정)&lt;/li&gt;
&lt;li data-end=&quot;342&quot; data-start=&quot;251&quot;&gt;직접 Babel을 교체하거나 Webpack 설정을 바꾸려면 &lt;b&gt;eject&lt;/b&gt; 해야 함&lt;/li&gt;
&lt;li&gt;eject 후에는 모든 설정이 프로젝트 안으로 풀리지만, 되돌릴 수 없음 &amp;rarr; 관리 부담 &amp;uarr;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757809998583&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm run eject&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;441&quot; data-start=&quot;402&quot;&gt;대부분은 CRA 기본 Babel 설정 그대로 사용하는 것이 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;460&quot; data-start=&quot;448&quot; data-ke-size=&quot;size20&quot;&gt;2. Vite&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;641&quot; data-start=&quot;461&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;493&quot; data-start=&quot;461&quot;&gt;&lt;b&gt;기본 컴파일러&lt;/b&gt;: esbuild + Babel&lt;/li&gt;
&lt;li data-end=&quot;641&quot; data-start=&quot;494&quot;&gt;&lt;b&gt;변경 가능 여부&lt;/b&gt;: 자유로움
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;641&quot; data-start=&quot;519&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;564&quot; data-start=&quot;519&quot;&gt;Vite는 설정 파일(vite.config.js)을 직접 수정 가능&lt;/li&gt;
&lt;li data-end=&quot;611&quot; data-start=&quot;567&quot;&gt;필요하면 esbuild 대신 Babel로 전환하거나 플러그인을 추가 가능&lt;/li&gt;
&lt;li data-end=&quot;641&quot; data-start=&quot;614&quot;&gt;설정 자유도가 높아서 커스텀 툴체인에 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;663&quot; data-start=&quot;648&quot; data-ke-size=&quot;size20&quot;&gt;3. Next.js&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;838&quot; data-start=&quot;664&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;692&quot; data-start=&quot;664&quot;&gt;&lt;b&gt;기본 컴파일러&lt;/b&gt;: Babel + SWC&lt;/li&gt;
&lt;li data-end=&quot;838&quot; data-start=&quot;693&quot;&gt;&lt;b&gt;변경 가능 여부&lt;/b&gt;: 부분적으로 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;838&quot; data-start=&quot;722&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;758&quot; data-start=&quot;722&quot;&gt;Next.js는 SWC를 기본으로 사용하여 빠른 빌드 제공&lt;/li&gt;
&lt;li data-end=&quot;809&quot; data-start=&quot;761&quot;&gt;SWC 대신 Babel로 강제 전환 가능 (next.config.js 설정)&lt;/li&gt;
&lt;li data-end=&quot;838&quot; data-start=&quot;812&quot;&gt;하지만 SWC 최적화 일부를 포기해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Vite가 가장 유연하게 컴파일러를 변경할 수 있고&lt;/b&gt;, CRA는 거의 못 바꾸는 수준, Next.js는 부분적 조정만 가능하다고 이해하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;87&quot; data-start=&quot;66&quot; data-ke-size=&quot;size26&quot;&gt; ️ 번들러(Bundler)란?&lt;/h2&gt;
&lt;p data-end=&quot;234&quot; data-start=&quot;89&quot; data-ke-size=&quot;size16&quot;&gt;React 프로젝트에서는 &lt;b&gt;많은 파일과 라이브러리&lt;/b&gt;를 사용하게 됩니다.&lt;br /&gt;브라우저는 import 같은 모듈 문법을 일부만 지원하고, 여러 개의 파일을 한 번에 로드하는 데 한계가 있어요.&lt;br /&gt;이때 등장하는 것이 번들러(Bundler)입니다.&lt;/p&gt;
&lt;p data-end=&quot;250&quot; data-start=&quot;236&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;250&quot; data-start=&quot;236&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;365&quot; data-start=&quot;251&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;299&quot; data-start=&quot;251&quot;&gt;여러 개의 JS, CSS, 이미지 파일을 &lt;b&gt;하나 또는 몇 개의 파일로 묶음&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;300&quot;&gt;브라우저가 효율적으로 읽을 수 있는 형태로 변환&lt;/li&gt;
&lt;li data-end=&quot;365&quot; data-start=&quot;331&quot;&gt;필요시 &lt;b&gt;최적화, 코드 스플리팅, 압축&lt;/b&gt;까지 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;386&quot; data-start=&quot;372&quot; data-ke-size=&quot;size23&quot;&gt;대표 번들러&lt;/h3&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-start=&quot;387&quot; data-end=&quot;701&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;번들러&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특징&lt;/td&gt;
&lt;td&gt;사용 예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;438&quot; data-end=&quot;503&quot;&gt;
&lt;td data-start=&quot;438&quot; data-end=&quot;452&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;Webpack&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;452&quot; data-end=&quot;486&quot; data-col-size=&quot;sm&quot;&gt;가장 널리 쓰이는 번들러, 플러그인과 설정 자유도가 높음&lt;/td&gt;
&lt;td data-start=&quot;486&quot; data-end=&quot;503&quot; data-col-size=&quot;sm&quot;&gt;CRA, 커스텀 프로젝트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;504&quot; data-end=&quot;568&quot;&gt;
&lt;td data-start=&quot;504&quot; data-end=&quot;518&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;esbuild&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;518&quot; data-end=&quot;554&quot; data-col-size=&quot;sm&quot;&gt;매우 빠른 빌드, TypeScript 지원, 최신 도구 중심&lt;/td&gt;
&lt;td data-start=&quot;554&quot; data-end=&quot;568&quot; data-col-size=&quot;sm&quot;&gt;Vite 개발 서버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;569&quot; data-end=&quot;644&quot;&gt;
&lt;td data-start=&quot;569&quot; data-end=&quot;582&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;Rollup&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;582&quot; data-end=&quot;623&quot; data-col-size=&quot;sm&quot;&gt;라이브러리 배포에 최적화, 트리 쉐이킹(Tree Shaking) 강력&lt;/td&gt;
&lt;td data-start=&quot;623&quot; data-end=&quot;644&quot; data-col-size=&quot;sm&quot;&gt;라이브러리 제작, Vite 빌드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-start=&quot;645&quot; data-end=&quot;701&quot;&gt;
&lt;td data-start=&quot;645&quot; data-end=&quot;658&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;Parcel&lt;/b&gt;&lt;/td&gt;
&lt;td data-start=&quot;658&quot; data-end=&quot;685&quot; data-col-size=&quot;sm&quot;&gt;설정 거의 필요 없음, Zero-config&lt;/td&gt;
&lt;td data-start=&quot;685&quot; data-end=&quot;701&quot; data-col-size=&quot;sm&quot;&gt;개인 프로젝트, 학습용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;React 프로젝트에서 번들러 위치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자&amp;nbsp;코드&amp;nbsp;+&amp;nbsp;라이브러리&amp;nbsp;&amp;rarr;&amp;nbsp;번들러(webpack/esbuild/rollup)&amp;nbsp;&amp;rarr;&amp;nbsp;브라우저가&amp;nbsp;읽는&amp;nbsp;단일/최적화된&amp;nbsp;파일&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;905&quot; data-start=&quot;812&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;828&quot; data-start=&quot;812&quot;&gt;CRA: Webpack&lt;/li&gt;
&lt;li data-end=&quot;870&quot; data-start=&quot;829&quot;&gt;Vite: 개발 서버 &amp;rarr; esbuild, 빌드 시 Rollup 사용&lt;/li&gt;
&lt;li data-end=&quot;905&quot; data-start=&quot;871&quot;&gt;Next.js: Webpack 기본, 빌드 최적화 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;937&quot; data-start=&quot;912&quot; data-ke-size=&quot;size16&quot;&gt;번들러를 직접 바꿀 수 있을까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1063&quot; data-start=&quot;938&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;984&quot; data-start=&quot;938&quot;&gt;&lt;b&gt;CRA&lt;/b&gt;: Webpack 설정 숨겨져 있어 어렵다(eject 필요)&lt;/li&gt;
&lt;li data-end=&quot;1022&quot; data-start=&quot;985&quot;&gt;&lt;b&gt;Vite&lt;/b&gt;: 설정 파일에서 쉽게 교체/커스터마이징 가능&lt;/li&gt;
&lt;li data-end=&quot;1063&quot; data-start=&quot;1023&quot;&gt;&lt;b&gt;Next.js&lt;/b&gt;: Webpack 교체 가능, 일부 제한 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;번들러는 여러 파일을 하나로 묶어 브라우저가 실행 가능하게 해주는 도구&lt;br /&gt;React 프로젝트에서는 필수적인 역할&lt;br /&gt;도구마다 기본 번들러가 다르고, 변경 가능 여부도 차이가 있음&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;94&quot; data-start=&quot;70&quot; data-ke-size=&quot;size26&quot;&gt; ️ 미니파이어(Minifier)란?&lt;/h2&gt;
&lt;p data-end=&quot;200&quot; data-start=&quot;96&quot; data-ke-size=&quot;size16&quot;&gt;미니파이어는 &lt;b&gt;코드 파일의 크기를 줄여주는 도구&lt;/b&gt;입니다.&lt;br /&gt;React 앱처럼 여러 JS, CSS 파일을 브라우저에서 로드할 때, 파일 크기가 크면 페이지 로딩 속도가 느려집니다.&lt;/p&gt;
&lt;p data-end=&quot;257&quot; data-start=&quot;202&quot; data-ke-size=&quot;size16&quot;&gt;미니파이어는 이를 해결하기 위해 &lt;b&gt;불필요한 공백, 줄 바꿈, 주석, 변수 이름을 축약&lt;/b&gt;합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757810901682&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 원본
function sayHello(name) {
    console.log(&quot;Hello, &quot; + name + &quot;!&quot;);
}
sayHello(&quot;React&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;darr;&amp;darr;&amp;darr; 미니파이&amp;nbsp;후&lt;/p&gt;
&lt;pre id=&quot;code_1757810964967&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 미니파이 후
function a(b){console.log(&quot;Hello, &quot;+b+&quot;!&quot;)}a(&quot;React&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;643&quot; data-start=&quot;574&quot;&gt;&lt;b&gt;번들링 과정에서 자동 적용&lt;/b&gt;: Webpack, Vite, Rollup 등 대부분 번들러가 미니파이어 기능을 포함&lt;/li&gt;
&lt;li data-end=&quot;690&quot; data-start=&quot;644&quot;&gt;&lt;b&gt;프로덕션 빌드 시 필수&lt;/b&gt;: 개발 서버에서는 가독성을 위해 적용하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;895&quot; data-start=&quot;862&quot;&gt;&lt;b&gt;목적&lt;/b&gt;: 코드 용량 줄여 페이지 로딩 속도 개선&lt;/li&gt;
&lt;li data-end=&quot;927&quot; data-start=&quot;896&quot;&gt;&lt;b&gt;언제 쓰는가&lt;/b&gt;: 프로덕션 빌드 시 자동 적용&lt;/li&gt;
&lt;li data-end=&quot;956&quot; data-start=&quot;928&quot;&gt;&lt;b&gt;개발자가 직접 건드릴 필요 거의 없음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;102&quot; data-start=&quot;74&quot; data-ke-size=&quot;size26&quot;&gt; ️ 테스트 러너(Test Runner)란?&lt;/h2&gt;
&lt;p data-end=&quot;204&quot; data-start=&quot;104&quot; data-ke-size=&quot;size16&quot;&gt;테스트 러너는 &lt;b&gt;작성한 테스트 코드를 실행하고 결과를 확인&lt;/b&gt;하는 도구입니다.&lt;br /&gt;React 앱에서는 UI, 기능, 상태 관리 등이 의도대로 동작하는지 검증할 때 사용합니다.&lt;/p&gt;
&lt;p data-end=&quot;221&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;221&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;역할&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;308&quot; data-start=&quot;222&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;235&quot; data-start=&quot;222&quot;&gt;테스트 파일 실행&lt;/li&gt;
&lt;li data-end=&quot;251&quot; data-start=&quot;236&quot;&gt;성공/실패 여부 출력&lt;/li&gt;
&lt;li data-end=&quot;293&quot; data-start=&quot;252&quot;&gt;테스트 환경 설정 (예: DOM 시뮬레이션, Mock 데이터 제공)&lt;/li&gt;
&lt;li data-end=&quot;308&quot; data-start=&quot;294&quot;&gt;테스트 보고서 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;310&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;코드를 실제로 실행해서 기능이 올바른지 확인&lt;/b&gt;해주는 역할입니다.&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;718&quot; data-start=&quot;378&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;테스트 러너&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특징&lt;/td&gt;
&lt;td&gt;React 환경 사용 예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;541&quot; data-start=&quot;454&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;465&quot; data-start=&quot;454&quot;&gt;&lt;b&gt;Jest&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;499&quot; data-start=&quot;465&quot;&gt;Facebook에서 만든 JavaScript 테스트 러너&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;541&quot; data-start=&quot;499&quot;&gt;CRA, Vite, Next.js 기본 지원, 단위/통합 테스트 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;606&quot; data-start=&quot;542&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;555&quot; data-start=&quot;542&quot;&gt;&lt;b&gt;Vitest&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;574&quot; data-start=&quot;555&quot;&gt;Vite 친화적, 빠른 테스트&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;606&quot; data-start=&quot;574&quot;&gt;Vite 프로젝트 추천, Jest 호환 API 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;660&quot; data-start=&quot;607&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;619&quot; data-start=&quot;607&quot;&gt;&lt;b&gt;Mocha&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;636&quot; data-start=&quot;619&quot;&gt;유연한 구조, 커스텀 가능&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;660&quot; data-start=&quot;636&quot;&gt;구버전 또는 커스텀 프로젝트에서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;718&quot; data-start=&quot;661&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;675&quot; data-start=&quot;661&quot;&gt;&lt;b&gt;Jasmine&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;701&quot; data-start=&quot;675&quot;&gt;BDD 스타일, 비교적 오래된 JS 테스트&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;718&quot; data-start=&quot;701&quot;&gt;과거 프로젝트 유지보수용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-end=&quot;353&quot; data-start=&quot;310&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;748&quot; data-start=&quot;725&quot; data-ke-size=&quot;size23&quot;&gt;React에서 사용하는 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;904&quot; data-start=&quot;749&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;788&quot; data-start=&quot;749&quot;&gt;&lt;b&gt;단위(Unit) 테스트&lt;/b&gt;: 함수, 컴포넌트 개별 기능 검증&lt;/li&gt;
&lt;li data-end=&quot;842&quot; data-start=&quot;789&quot;&gt;&lt;b&gt;통합(Integration) 테스트&lt;/b&gt;: 여러 컴포넌트를 함께 사용했을 때 동작 검증&lt;/li&gt;
&lt;li data-end=&quot;904&quot; data-start=&quot;843&quot;&gt;&lt;b&gt;UI 테스트&lt;/b&gt;: React Testing Library와 결합해 실제 DOM 렌더링 결과 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757811199948&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { render, screen } from '@testing-library/react';
import App from './App';

test('renders hello message', () =&amp;gt; {
  render(&amp;lt;App /&amp;gt;);
  const heading = screen.getByText(/hello react/i);
  expect(heading).toBeInTheDocument();
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 React 공식 문서의 &lt;b&gt;설치 및 개발 환경 구성&lt;/b&gt; 부분을 중심으로 살펴봤습니다.&lt;br /&gt;CRA, Vite, Next.js 등 다양한 프로젝트 생성 도구가 있고, 각 도구마다 기본 &lt;b&gt;컴파일러와 번들러&lt;/b&gt;가 있다는 점을 배웠습니다.&lt;br /&gt;npx create-react-app 명령어가 &lt;b&gt;프로젝트 생성과 의존성 설치를 한 번에 처리&lt;/b&gt;해준다는 것도 확인했죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Vite는 최신 도구답게 &lt;b&gt;빠른 빌드와 자유로운 설정&lt;/b&gt;이 장점이며, Next.js는 서버 사이드 렌더링까지 지원합니다.&lt;br /&gt;React 환경에서는 &lt;b&gt;패키지 매니저, 컴파일러, 번들러, 미니파이어, 개발 서버, 테스트 러너&lt;/b&gt;가 각자 역할을 나눠 프로젝트를 효율적으로 관리합니다.&lt;br /&gt;특히 Jest와 같은 테스트 러너를 통해 단위 테스트와 통합 테스트를 쉽게 실행할 수 있다는 것도 실습해봤습니다.&lt;br /&gt;CRA와 Vite, Next.js의 도구별 특징과 커스터마이징 가능 여부를 비교하면서, 자신에게 맞는 개발 환경을 선택하는 기준도 알 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 과정에서 각 도구가 제공하는 편의성과, 직접 설정할 수 있는 Custom Toolchain의 장단점도 이해할 수 있었죠.&lt;br /&gt;앞으로는 오늘 배운 내용을 바탕으로 &lt;b&gt;실제 프로젝트를 만들고 실행해보며&lt;/b&gt;, 각 도구가 어떻게 동작하는지 경험해보는 것이 중요합니다.&lt;br /&gt;React 개발 환경을 제대로 이해하면, 새로운 프로젝트를 시작할 때 어떤 도구를 선택하고, 효율적으로 구성할지 자신 있게 결정할 수 있습니다.&lt;/p&gt;</description>
      <category>개발 로그/React</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/91</guid>
      <comments>https://jjung2ing.tistory.com/91#entry91comment</comments>
      <pubDate>Sun, 14 Sep 2025 09:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[React 공식문서 vol.0] 공식문서로 리액트 기본 다지기</title>
      <link>https://jjung2ing.tistory.com/90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리액트를 공부하려고 마음먹었다면, 아마 가장 먼저 고민하게 되는 질문이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;뭐부터 공부해야 하지?&quot; 혹은 &quot;책을 볼까, 영상 강의를 볼까?&quot;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;368&quot; data-start=&quot;240&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 말해서, 저는 &lt;b&gt;리액트를 제대로 공부하고 싶다면 공식문서보다 좋은 자료는 없다고 생각합니다.&lt;/b&gt;&lt;br /&gt;왜냐하면 공식문서 안에는 &lt;b&gt;리액트 기초부터 고급 문법까지, 핵심 개념과 실습 예제&lt;/b&gt;가 모두 담겨 있기 때문입니다.&lt;/p&gt;
&lt;p data-end=&quot;548&quot; data-start=&quot;370&quot; data-ke-size=&quot;size16&quot;&gt;게다가 이 문서는 &lt;b&gt;리액트를 직접 개발한 사람들이 작성한 공식문서&lt;/b&gt;입니다.&lt;br /&gt;즉, 누구보다 정확하고 믿을 수 있는 정보가 담겨 있으며, 최신 버전 React에 맞춰 항상 업데이트됩니다.&lt;br /&gt;책이나 영상 강의는 출간 시점 이후 최신 내용이 반영되지 않을 수 있지만, 공식문서는 실시간으로 최신 정보가 반영됩니다.&lt;/p&gt;
&lt;p data-end=&quot;748&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;748&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;748&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;저 역시 이미 4년 넘게 리액트를 사용했지만, 이번에 새롭게 버전업한 React가 어떤 &lt;b&gt;새로운 기능과 개선 사항&lt;/b&gt;을 담고 있는지,&lt;br /&gt;그리고 제가 알고 있는 지식이 여전히 정확한지 &lt;b&gt;짚어보는 시간&lt;/b&gt;을 갖고 싶었습니다.&lt;/p&gt;
&lt;p data-end=&quot;748&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;748&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이런 이유로 이번 시리즈에서는 &lt;b&gt;공식문서를 한 챕터씩 정주행하며, 리액트 기본을 다시 다지는 과정&lt;/b&gt;을 기록하려고 합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;764&quot; data-start=&quot;750&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;764&quot; data-start=&quot;750&quot; data-ke-size=&quot;size26&quot;&gt;공식문서를 읽는 목적&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;921&quot; data-start=&quot;766&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 목표는 단순히 읽는 것이 아니라 &lt;b&gt;이해하고, 직접 코드를 작성하며 내 것으로 만드는 것&lt;/b&gt;입니다.&lt;br /&gt;JSX 문법, 컴포넌트 구조 같은 기본 개념부터 시작해, Hooks, Context API, Suspense 등 &lt;b&gt;고급 주제까지 차근차근 학습&lt;/b&gt;할 예정입니다.&lt;/p&gt;
&lt;p data-end=&quot;1067&quot; data-start=&quot;923&quot; data-ke-size=&quot;size16&quot;&gt;작은 컴포넌트를 직접 만들어보며 실습하면, 단순히 읽는 것보다 &lt;b&gt;기억에 오래 남고 이해가 깊어집니다.&lt;/b&gt;&lt;br /&gt;공식문서의 예제 코드는 실제로 동작하도록 작성되어 있어, 복사해서 내 프로젝트에 적용하거나 조금 변형해 &lt;b&gt;나만의 코드&lt;/b&gt;로 만들 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1192&quot; data-start=&quot;1069&quot; data-ke-size=&quot;size16&quot;&gt;또한 공식문서를 정주행하면 &lt;b&gt;리액트의 철학과 설계 의도&lt;/b&gt;를 자연스럽게 이해하게 됩니다.&lt;br /&gt;그냥 사용법만 아는 개발자와, &lt;b&gt;왜 이런 방식으로 만들어졌는지 이해하는 개발자&lt;/b&gt;는 문제를 해결할 때 큰 차이가 납니다.&lt;/p&gt;
&lt;p data-end=&quot;1192&quot; data-start=&quot;1069&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;72&quot; data-start=&quot;60&quot; data-ke-size=&quot;size26&quot;&gt;시리즈 진행 방식&lt;/h2&gt;
&lt;p data-end=&quot;146&quot; data-start=&quot;74&quot; data-ke-size=&quot;size16&quot;&gt;이 시리즈에서는 매 포스트마다 &lt;b&gt;한 챕터씩 정리&lt;/b&gt;하면서, 제가 직접 코드를 작성해보고 느낀 점도 함께 기록하려고 해요.&lt;/p&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;148&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;148&quot; data-ke-size=&quot;size16&quot;&gt;그래서 혼자 공부하는 분이나, 이제 막 리액트를 배우기 시작한 분도 같이 따라올 수 있도록 &lt;b&gt;쉽게 따라갈 수 있는 구성&lt;/b&gt;으로 만들었습니다.&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;중요한 건 &lt;b&gt;속도가 아니라 이해의 깊이&lt;/b&gt;예요.&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;하루에 조금씩 읽고, 코드를 작성하고, 다시 돌아보는 과정을 반복하다 보면 리액트의 기초부터 고급 개념까지 자연스럽게 내 것이 된답니다.&lt;/p&gt;
&lt;p data-end=&quot;455&quot; data-start=&quot;345&quot; data-ke-size=&quot;size16&quot;&gt;시리즈가 끝나갈 즈음에는, 공식문서를 읽는 게 얼마나 큰 힘이 되는지 직접 느낄 수 있을 거예요.&lt;/p&gt;
&lt;p data-end=&quot;455&quot; data-start=&quot;345&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;455&quot; data-start=&quot;345&quot; data-ke-size=&quot;size16&quot;&gt;그리고 혼자서도 충분히 리액트 프로젝트를 설계하고 구현할 &lt;b&gt;자신감&lt;/b&gt;이 생기실 거예요.&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;리액트 공식문서를 검색하면 두개가 있는데 필요하신 버전에 맞게 공부하시면 될 것같습니다.&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;현재 리액트는 v19 까지 나왔습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-13 오후 4.34.58.png&quot; data-origin-width=&quot;1842&quot; data-origin-height=&quot;1288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Up8B/btsQwBJ09rj/91Rrpl1Z5UePcVCOAr8b1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Up8B/btsQwBJ09rj/91Rrpl1Z5UePcVCOAr8b1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Up8B/btsQwBJ09rj/91Rrpl1Z5UePcVCOAr8b1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Up8B%2FbtsQwBJ09rj%2F91Rrpl1Z5UePcVCOAr8b1k%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;1842&quot; height=&quot;1288&quot; data-filename=&quot;스크린샷 2025-09-13 오후 4.34.58.png&quot; data-origin-width=&quot;1842&quot; data-origin-height=&quot;1288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;구 React 공식문서&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/getting-started.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.legacy.reactjs.org/docs/getting-started.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757748833973&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;시작하기 &amp;ndash; React&quot; data-og-description=&quot;A JavaScript library for building user interfaces&quot; data-og-host=&quot;ko.legacy.reactjs.org&quot; data-og-source-url=&quot;https://ko.legacy.reactjs.org/docs/getting-started.html&quot; data-og-url=&quot;https://ko.legacy.reactjs.org/docs/getting-started.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/heF4Z/hyZI3Wv50P/e8rAhqrcwkt8ypXXcVTLOk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/getting-started.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.legacy.reactjs.org/docs/getting-started.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/heF4Z/hyZI3Wv50P/e8rAhqrcwkt8ypXXcVTLOk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;시작하기 &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A JavaScript library for building user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.legacy.reactjs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신 React 공식문서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://react.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://react.dev/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757748852198&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;React&quot; data-og-description=&quot;React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizati&quot; data-og-host=&quot;react.dev&quot; data-og-source-url=&quot;https://react.dev/&quot; data-og-url=&quot;https://react.dev/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cJaEEg/hyZIZAGZzk/thOOdwP61vPmsQsiOxoWx0/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/rkpaD/hyZIVkJNkl/Zoot8SlKquJCAA1jP9FdW1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://react.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://react.dev/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cJaEEg/hyZIZAGZzk/thOOdwP61vPmsQsiOxoWx0/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/rkpaD/hyZIVkJNkl/Zoot8SlKquJCAA1jP9FdW1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizati&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;155&quot; data-start=&quot;131&quot; data-ke-size=&quot;size26&quot;&gt;리액트 버전별 비교: 주요 변화와 특징&lt;/h2&gt;
&lt;h3 data-end=&quot;175&quot; data-start=&quot;157&quot; data-ke-size=&quot;size23&quot;&gt;1. React 15 이전&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;269&quot; data-start=&quot;176&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;227&quot; data-start=&quot;176&quot;&gt;&lt;b&gt;주요 특징:&lt;/b&gt; 클래스 컴포넌트 중심, JSX 문법 기본, 가상 DOM 개념 도입&lt;/li&gt;
&lt;li data-end=&quot;269&quot; data-start=&quot;228&quot;&gt;&lt;b&gt;주의점:&lt;/b&gt; 함수형 컴포넌트는 단순한 렌더링용, 상태 관리 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;286&quot; data-start=&quot;271&quot; data-ke-size=&quot;size23&quot;&gt;2. React 16&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;432&quot; data-start=&quot;287&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;287&quot;&gt;&lt;b&gt;주요 특징:&lt;/b&gt; Fiber 아키텍처 도입 &amp;rarr; 렌더링 성능 개선&lt;/li&gt;
&lt;li data-end=&quot;382&quot; data-start=&quot;328&quot;&gt;&lt;b&gt;주요 추가 기능:&lt;/b&gt; Error Boundaries, Fragments, Portals&lt;/li&gt;
&lt;li data-end=&quot;432&quot; data-start=&quot;383&quot;&gt;&lt;b&gt;Hooks 전 단계:&lt;/b&gt; 상태와 사이드 이펙트는 여전히 클래스 컴포넌트에 의존&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;451&quot; data-start=&quot;434&quot; data-ke-size=&quot;size23&quot;&gt;3. React 16.8&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;561&quot; data-start=&quot;452&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;511&quot; data-start=&quot;452&quot;&gt;&lt;b&gt;주요 특징:&lt;/b&gt; &lt;b&gt;Hooks 도입&lt;/b&gt; &amp;rarr; 함수형 컴포넌트에서도 상태 관리와 생명주기 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;561&quot; data-start=&quot;512&quot;&gt;&lt;b&gt;주요 Hooks:&lt;/b&gt; useState, useEffect, useContext&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;578&quot; data-start=&quot;563&quot; data-ke-size=&quot;size23&quot;&gt;4. React 17&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;663&quot; data-start=&quot;579&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;618&quot; data-start=&quot;579&quot;&gt;&lt;b&gt;주요 특징:&lt;/b&gt; 주로 내부적인 변화, 점진적 업그레이드 용이&lt;/li&gt;
&lt;li data-end=&quot;663&quot; data-start=&quot;619&quot;&gt;&lt;b&gt;주의점:&lt;/b&gt; 새로운 기능 추가보다는 호환성과 마이그레이션 편의성 강화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;680&quot; data-start=&quot;665&quot; data-ke-size=&quot;size23&quot;&gt;5. React 18&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;799&quot; data-start=&quot;681&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;751&quot; data-start=&quot;681&quot;&gt;&lt;b&gt;주요 특징:&lt;/b&gt; Concurrent Mode 도입, 자동 배치(Batched Updates), Suspense 개선&lt;/li&gt;
&lt;li data-end=&quot;799&quot; data-start=&quot;752&quot;&gt;&lt;b&gt;주의점:&lt;/b&gt; 기존 프로젝트 업그레이드 시 일부 렌더링 방식 차이 확인 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;155&quot; data-start=&quot;131&quot; data-ke-size=&quot;size26&quot;&gt;함수형 컴포넌트 vs 클래스형 컴포넌트&lt;/h2&gt;
&lt;p data-end=&quot;254&quot; data-start=&quot;157&quot; data-ke-size=&quot;size16&quot;&gt;리액트 컴포넌트에는 &lt;b&gt;함수형 컴포넌트&lt;/b&gt;와 &lt;b&gt;클래스형 컴포넌트&lt;/b&gt; 두 가지가 있어요.&lt;br /&gt;최근에는 함수형 컴포넌트가 주류지만, 차이를 이해하면 둘 다 활용할 수 있습니다.&lt;/p&gt;
&lt;div&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%;&quot; border=&quot;1&quot; data-end=&quot;714&quot; data-start=&quot;256&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;714&quot; data-start=&quot;329&quot;&gt;
&lt;tr data-end=&quot;412&quot; data-start=&quot;329&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;334&quot; data-start=&quot;329&quot;&gt;문법&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;378&quot; data-start=&quot;334&quot;&gt;class 키워드 사용, extends React.Component&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;412&quot; data-start=&quot;378&quot;&gt;일반 함수 형태, function 혹은 화살표 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;498&quot; data-start=&quot;413&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;421&quot; data-start=&quot;413&quot;&gt;상태 관리&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;455&quot; data-start=&quot;421&quot;&gt;this.state, this.setState()&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;498&quot; data-start=&quot;455&quot;&gt;&lt;b&gt;Hooks&lt;/b&gt; 사용 (useState, useReducer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;582&quot; data-start=&quot;499&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;506&quot; data-start=&quot;499&quot;&gt;생명주기&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;552&quot; data-start=&quot;506&quot;&gt;componentDidMount, componentDidUpdate 등&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;582&quot; data-start=&quot;552&quot;&gt;&lt;b&gt;Hooks&lt;/b&gt; 사용 (useEffect)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;653&quot; data-start=&quot;583&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;588&quot; data-start=&quot;583&quot;&gt;장점&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;616&quot; data-start=&quot;588&quot;&gt;과거 프로젝트와 호환성, 명시적 생명주기 관리&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;653&quot; data-start=&quot;616&quot;&gt;간결하고 직관적, 코드량 적음, 최신 React 패턴과 호환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;714&quot; data-start=&quot;654&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;659&quot; data-start=&quot;654&quot;&gt;단점&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;677&quot; data-start=&quot;659&quot;&gt;코드가 길고 복잡해지기 쉬움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;714&quot; data-start=&quot;677&quot;&gt;Hooks 개념 학습 필요, 클래스형 경험 없으면 초기 혼란&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;726&quot; data-start=&quot;716&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;726&quot; data-start=&quot;716&quot; data-ke-size=&quot;size23&quot;&gt;핵심 포인트&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;884&quot; data-start=&quot;727&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;765&quot; data-start=&quot;727&quot;&gt;함수형 컴포넌트는 &lt;b&gt;최근 리액트에서 권장되는 방식&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li data-end=&quot;825&quot; data-start=&quot;766&quot;&gt;클래스형 컴포넌트는 &lt;b&gt;레거시 코드 유지&lt;/b&gt;나 일부 라이브러리 호환에서 여전히 필요할 때가 있어요.&lt;/li&gt;
&lt;li data-end=&quot;884&quot; data-start=&quot;826&quot;&gt;Hooks를 활용하면 함수형에서도 &lt;b&gt;상태 관리와 생명주기 기능&lt;/b&gt;을 완전히 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트를 공부하다 보면 한 번쯤은 &lt;b&gt;클래스형 컴포넌트 vs 함수형 컴포넌트&lt;/b&gt;를 비교하게 됩니다.&lt;br /&gt;클래스형은 과거 프로젝트에서 많이 쓰였고, 생명주기 메서드가 명시적으로 드러난다는 장점이 있어요.&lt;br /&gt;하지만 요즘 리액트의 흐름은 명확히 &lt;b&gt;함수형 컴포넌트 + Hooks&lt;/b&gt; 쪽으로 가고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;401&quot; data-start=&quot;284&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;523&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번 시리즈에서는 함수형 컴포넌트를 중심으로 공부를 이어가려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;물론 필요하다면 클래스형도 함께 다루겠지만,&lt;br /&gt;중요한 건 최신 리액트가 어디에 초점을 맞추고 있는지를 따라가는 거라고 생각해요.&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;668&quot; data-start=&quot;525&quot; data-ke-size=&quot;size16&quot;&gt;이제 본격적으로 문서를 정주행하면서,&lt;br /&gt;리액트의 기초부터 고급 주제까지 차근차근 살펴보고 직접 코드를 작성해보겠습니다.&lt;br /&gt;끝까지 따라오신다면, 단순히 &quot;리액트를 쓸 줄 아는 사람&quot;이 아니라&lt;br /&gt;&quot;리액트를 이해하는 개발자&quot;가 될 수 있을 거예요.  &lt;/p&gt;</description>
      <category>개발 로그/React</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/90</guid>
      <comments>https://jjung2ing.tistory.com/90#entry90comment</comments>
      <pubDate>Sun, 14 Sep 2025 08:31:43 +0900</pubDate>
    </item>
    <item>
      <title>[React] SPA와 리액트: 현대 웹 개발의 핵심 기술 이해하기</title>
      <link>https://jjung2ing.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 오늘은 리액트(React)에 대해 이야기해보려고 해요.&lt;br /&gt;프론트엔드 채용 시, 거의 모든 회사가 요구하는 자격 조건이라고 해도 과언이 아니죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;306&quot; data-start=&quot;192&quot; data-ke-size=&quot;size16&quot;&gt;그런데 리액트가 왜 갑자기 등장했는지, 또 왜 이렇게 인기가 많아졌는지는 잘 모르는 분들도 많더라고요.&lt;br /&gt;사실 리액트의 등장은 그냥 우연이 아니라, 웹 개발 환경과 트렌드 변화와 깊은 관련이 있어요.&lt;/p&gt;
&lt;p data-end=&quot;306&quot; data-start=&quot;192&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;조금만 거슬러 올라가 보면, 예전 웹은 대부분 &lt;b&gt;정적인 페이지&lt;/b&gt; 중심이었어요.&lt;br /&gt;사용자가 버튼을 누르면 페이지가 새로고침되고, 서버에서 HTML을 다시 받아오는 방식이었죠.&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 예시를 들어 볼까요?&lt;/p&gt;
&lt;h3 data-end=&quot;95&quot; data-start=&quot;79&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ 쇼핑몰 장바구니&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;299&quot; data-start=&quot;96&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;214&quot; data-start=&quot;96&quot;&gt;&lt;b&gt;정적 페이지&lt;/b&gt;: 상품을 장바구니에 담으면 페이지가 새로고침됨.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;214&quot; data-start=&quot;140&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;171&quot; data-start=&quot;140&quot;&gt;화면 전체가 깜빡이면서 장바구니 리스트가 나타남.&lt;/li&gt;
&lt;li data-end=&quot;214&quot; data-start=&quot;174&quot;&gt;장바구니 안에서 선택한 수량 같은 상태도 다시 초기화될 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;299&quot; data-start=&quot;215&quot;&gt;&lt;b&gt;SPA&lt;/b&gt;: 수량 버튼 클릭 &amp;rarr; 서버에 필요한 데이터만 요청 &amp;rarr; 화면 일부만 업데이트.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;299&quot; data-start=&quot;272&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;299&quot; data-start=&quot;272&quot;&gt;깜빡임 없이 장바구니 수량이 바로 반영됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;304&quot; data-start=&quot;301&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;323&quot; data-start=&quot;306&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 댓글 작성/좋아요&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;504&quot; data-start=&quot;324&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;324&quot;&gt;&lt;b&gt;정적 페이지&lt;/b&gt;: 댓글을 작성하거나 좋아요를 누르면 페이지 전체가 새로고침됨.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;415&quot; data-start=&quot;376&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;415&quot; data-start=&quot;376&quot;&gt;기존 댓글도 깜빡이며, 스크롤 위치가 맨 위로 이동할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;504&quot; data-start=&quot;416&quot;&gt;&lt;b&gt;SPA&lt;/b&gt;: 댓글 입력 &amp;rarr; 서버로 데이터 전송 &amp;rarr; 화면 일부만 업데이트.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;504&quot; data-start=&quot;465&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;504&quot; data-start=&quot;465&quot;&gt;기존 댓글은 그대로, 스크롤도 유지, 좋아요 숫자만 바로 바뀜.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;509&quot; data-start=&quot;506&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;527&quot; data-start=&quot;511&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ 지도/위치 검색&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;664&quot; data-start=&quot;528&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;613&quot; data-start=&quot;528&quot;&gt;&lt;b&gt;정적 페이지&lt;/b&gt;: 지도에서 다른 지역을 검색하면 페이지 전체가 새로고침됨.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;613&quot; data-start=&quot;578&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;613&quot; data-start=&quot;578&quot;&gt;지도 화면이 잠깐 사라지고 다시 나타남 &amp;rarr; 깜빡임 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;664&quot; data-start=&quot;614&quot;&gt;&lt;b&gt;SPA&lt;/b&gt;: 검색 결과만 받아서 지도만 갱신 &amp;rarr; 깜빡임 없음, 지도 위치 유지.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;이런 예시가 도움이 되셨나요? 조금 더 이해가 쉬워졌길 바라요  &lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 큰 불편함이 없었지만, 웹 서비스가 점점 복잡해지면서 문제가 나타났어요.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;특히 사용자 경험이 중요한 서비스에서는 &lt;b&gt;페이지 깜빡임&lt;/b&gt;과 &lt;b&gt;느린 로딩&lt;/b&gt;이 큰 걸림돌이었죠.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그래서 등장한 것이 바로 SPA(Single Page Application)예요.&lt;br /&gt;SPA는 한 페이지 안에서 필요한 부분만 갱신해서 보여주는 방식이에요.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;SPA는 많은 웹 페이지를 로딩하더라도, 필요한 데이터만 빠르게 업데이트할 수 있어요.&lt;br /&gt;덕분에 페이지 로딩 속도가 빨라지고, 트래픽도 줄일 수 있죠.&lt;br /&gt;화면 전환이 부드럽고, 업데이트가 끝날 때까지 기다리는 시간도 짧아져서 사용자가 몰입감 있게 웹을 사용할 수 있어요.  &lt;br /&gt;덕분에 페이지 전체를 새로 불러오지 않아도 되고, 사용자 입장에서는 앱처럼 부드럽게 느껴지죠.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;899&quot; data-start=&quot;883&quot; data-ke-size=&quot;size23&quot;&gt;SPA의 주요 장점&lt;/h3&gt;
&lt;p data-end=&quot;1080&quot; data-start=&quot;901&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1️⃣ 빠른 로딩 속도와 반응성&lt;/b&gt;&lt;br /&gt;SPA는 페이지 전환 시 서버에서 전체 HTML을 내려받지 않고, 필요한 데이터만 업데이트해요.&lt;br /&gt;최초 한 번만 전체 웹 애플리케이션 파일을 다운로드하면 이후에는 필요한 데이터만 받아 화면을 바꿀 수 있죠.&lt;br /&gt;덕분에 로딩 속도가 빨라지고, 서버 트래픽도 줄일 수 있어요.&lt;/p&gt;
&lt;p data-end=&quot;1080&quot; data-start=&quot;901&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1082&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2️⃣ 향상된 사용자 경험&lt;/b&gt;&lt;br /&gt;빠른 화면 전환과 부드러운 렌더링 덕분에, 사용자는 SPA를 &lt;b&gt;엑셀이나 워드 같은 네이티브 앱&lt;/b&gt;처럼 느낄 수 있어요.&lt;br /&gt;페이지가 느리면 사용자가 쉽게 이탈하지만, SPA는 체류 시간을 늘리고 만족도를 높일 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1082&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1409&quot; data-start=&quot;1232&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3️⃣ 웹/모바일 공통 아키텍처 활용&lt;/b&gt;&lt;br /&gt;전통적인 웹 개발 방식에서는 모바일 앱용 API 서버를 별도로 구성해야 했지만,&lt;br /&gt;SPA는 &lt;b&gt;UI와 서버 데이터를 분리&lt;/b&gt;하고 비동기 방식으로 데이터를 가져오기 때문에&lt;br /&gt;웹 앱뿐 아니라 모바일 앱에서도 &lt;b&gt;같은 백엔드를 활용&lt;/b&gt;할 수 있어 개발 효율이 높아요.&lt;/p&gt;
&lt;p data-end=&quot;1409&quot; data-start=&quot;1232&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1587&quot; data-start=&quot;1411&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4️⃣ 복잡한 대규모 애플리케이션 대응&lt;/b&gt;&lt;br /&gt;사용자와의 상호작용이 많고 동적 요소가 많은 앱도 SPA라면&lt;br /&gt;필요한 부분만 업데이트하기 때문에 &lt;b&gt;트래픽 부담을 줄이고 반응성을 유지&lt;/b&gt;할 수 있어요.&lt;br /&gt;React, Vue, Angular 같은 프레임워크가 SPA 원칙을 도입하는 이유도 바로 여기에 있죠.&lt;/p&gt;
&lt;p data-end=&quot;1587&quot; data-start=&quot;1411&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;하지만 SPA 개발도 쉽지만은 않았어요.&lt;br /&gt;자바스크립트 코드가 점점 복잡해지고, 상태 관리가 어려워지면서 개발자들이 머리를 싸매야 했거든요.&lt;/p&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;667&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;930&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 &lt;b&gt;컴포넌트 단위로 UI를 쪼개 관리&lt;/b&gt;할 수 있게 해주고,&lt;/p&gt;
&lt;p data-end=&quot;930&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;상태(state)가 바뀌면 알아서 화면을 효율적으로 업데이트해주는 가상 DOM(Virtual DOM)을 도입했어요.&lt;/p&gt;
&lt;p data-end=&quot;930&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;덕분에 복잡한 SPA도 훨씬 깔끔하고, 유지보수가 쉬워졌죠.&lt;/p&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;즉, 리액트는 단순히 &amp;ldquo;유행하는 라이브러리&amp;rdquo;가 아니라,&lt;br /&gt;SPA 시대의 필연적인 해결책이자, 개발자들의 고민을 덜어주는 도구였던 거예요.&lt;/p&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;오늘 글에서는 리액트가 왜 만들어졌는지, 어떤 문제를 해결하려고 했는지, 그리고 SPA와 어떤 관계가 있는지를 친근하게 풀어보려고 해요.&lt;br /&gt;코드를 바로 다루기 전, 이렇게 배경부터 이해하면 훨씬 재밌게 따라올 수 있답니다.&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;88&quot; data-start=&quot;64&quot; data-ke-size=&quot;size23&quot;&gt;리액트가 왜 만들어졌는가?&lt;/h3&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;89&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 &lt;b&gt;SPA 개발의 복잡함을 해결&lt;/b&gt;하기 위해 만들어졌어요.&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;89&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;페이스북은 이런 문제를 해결하기 위해 &lt;b&gt;UI를 컴포넌트 단위로 쪼개고&lt;/b&gt;,&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;상태 변화에 따라 필요한 부분만 효율적으로 업데이트하는 가상 DOM(Virtual DOM)을 도입한 리액트를 만들었습니다.&lt;br /&gt;즉, &quot;복잡한 SPA를 쉽게 만들고, 유지보수도 편하게 하자!&quot;가 핵심 목표였어요.&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;여기서 궁금한점! &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SPA 개발의 복잡함&amp;nbsp;&lt;/b&gt;이 뭐예요? 뭐가 복잡하다는 걸까요?&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;여기서 말하는 &lt;b&gt;SPA 개발의 복잡함&lt;/b&gt;은 단순히 코드가 많아진다는 뜻이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;377&quot; data-start=&quot;209&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;166&quot; data-start=&quot;143&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;166&quot; data-start=&quot;143&quot; data-ke-size=&quot;size16&quot;&gt;1. 상태(state) 관리 문제&lt;/p&gt;
&lt;p data-end=&quot;213&quot; data-start=&quot;167&quot; data-ke-size=&quot;size16&quot;&gt;SPA에서는 한 페이지 안에서 여러 UI가 동적으로 바뀌잖아요.&lt;br /&gt;예를 들어:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;273&quot; data-start=&quot;214&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;230&quot; data-start=&quot;214&quot;&gt;장바구니 목록 업데이트&lt;/li&gt;
&lt;li data-end=&quot;251&quot; data-start=&quot;231&quot;&gt;댓글 작성 후 바로 화면 갱신&lt;/li&gt;
&lt;li data-end=&quot;273&quot; data-start=&quot;252&quot;&gt;좋아요 버튼 클릭 시 숫자 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;275&quot; data-ke-size=&quot;size16&quot;&gt;이럴 때 &lt;b&gt;어떤 데이터가 어디에서 바뀌었는지, 그리고 화면에 어떻게 반영할지&lt;/b&gt;를 직접 다 관리해야 했어요.&lt;br /&gt;페이지가 커질수록 &amp;ldquo;어떤 상태가 어디에 영향을 주는지&amp;rdquo;가 복잡해지고, 버그가 생기기 쉽죠.&lt;/p&gt;
&lt;p data-end=&quot;417&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;417&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;2. DOM 업데이트 문제&lt;/p&gt;
&lt;p data-end=&quot;499&quot; data-start=&quot;418&quot; data-ke-size=&quot;size16&quot;&gt;SPA 이전에는 페이지 전체를 새로 그리면 됐어요.&lt;br /&gt;하지만 SPA에서는 &lt;b&gt;부분만 업데이트&lt;/b&gt;해야 하니까, DOM을 직접 조작해야 했어요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;552&quot; data-start=&quot;500&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;514&quot; data-start=&quot;500&quot;&gt;어떤 요소를 바꿀지&lt;/li&gt;
&lt;li data-end=&quot;535&quot; data-start=&quot;515&quot;&gt;이벤트 핸들러가 꼬이지 않도록&lt;/li&gt;
&lt;li data-end=&quot;552&quot; data-start=&quot;536&quot;&gt;데이터와 UI를 동기화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;599&quot; data-start=&quot;554&quot; data-ke-size=&quot;size16&quot;&gt;이게 많아지면 &lt;b&gt;코드가 점점 지저분하고 관리하기 어려워지는 구조&lt;/b&gt;가 돼요.&lt;/p&gt;
&lt;p data-end=&quot;628&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;628&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;3. 이벤트와 비동기 처리 문제&lt;/p&gt;
&lt;p data-end=&quot;678&quot; data-start=&quot;629&quot; data-ke-size=&quot;size16&quot;&gt;SPA는 사용자 이벤트가 많고, 서버 데이터도 **비동기(Async)**로 받아와요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;736&quot; data-start=&quot;679&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;706&quot; data-start=&quot;679&quot;&gt;서버에서 데이터를 받아와 화면에 바로 반영&lt;/li&gt;
&lt;li data-end=&quot;736&quot; data-start=&quot;707&quot;&gt;동시에 여러 이벤트가 발생하면 상태 충돌 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;790&quot; data-start=&quot;738&quot; data-ke-size=&quot;size16&quot;&gt;이런 비동기 로직과 이벤트 로직을 직접 관리하다 보면 코드가 복잡해지고, 디버깅도 어렵죠.&lt;/p&gt;
&lt;p data-end=&quot;908&quot; data-start=&quot;797&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;908&quot; data-start=&quot;797&quot; data-ke-size=&quot;size16&quot;&gt;  쉽게 요약하면, SPA는 &amp;ldquo;화면 전체를 새로 그리지 않고 부분 업데이트&amp;rdquo;를 하기 때문에&lt;br /&gt;&lt;b&gt;상태 관리 + DOM 업데이트 + 비동기 처리&lt;/b&gt;가 복잡하게 얽히면서 코드가 복잡해지는 거예요.&lt;/p&gt;
&lt;h3 data-end=&quot;403&quot; data-start=&quot;384&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;403&quot; data-start=&quot;384&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 누가 만들었는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;565&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 페이스북(Facebook)에서 개발되었고, 2013년에 오픈소스로 공개되었습니다.&lt;br /&gt;초기에는 페이스북 내부 뉴스피드에서 UI 문제를 해결하기 위해 시작됐고,&lt;br /&gt;지금은 페이스북뿐만 아니라 &lt;b&gt;인스타그램, 넷플릭스, 에어비앤비 등 다양한 기업&lt;/b&gt;에서도 사용되고 있어요.&lt;/p&gt;
&lt;p data-end=&quot;565&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;565&quot; data-start=&quot;404&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;570&quot; data-start=&quot;567&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;597&quot; data-start=&quot;572&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;597&quot; data-start=&quot;572&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ 리액트는 어떻게 사용하는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;629&quot; data-start=&quot;598&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 &lt;b&gt;컴포넌트 기반&lt;/b&gt;으로 UI를 구성합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;780&quot; data-start=&quot;630&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;693&quot; data-start=&quot;630&quot;&gt;화면을 작은 단위(컴포넌트)로 나누고, 각 컴포넌트가 자신만의 상태(state)와 속성(props)을 가짐&lt;/li&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;694&quot;&gt;상태가 바뀌면 리액트가 알아서 화면을 효율적으로 업데이트&lt;/li&gt;
&lt;li data-end=&quot;780&quot; data-start=&quot;730&quot;&gt;JSX라는 &lt;b&gt;자바스크립트 안에서 HTML처럼 쓸 수 있는 문법&lt;/b&gt;으로 UI를 작성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;904&quot; data-start=&quot;782&quot; data-ke-size=&quot;size16&quot;&gt;즉, &quot;UI를 작은 블록처럼 나누고, 상태가 바뀌면 필요한 블록만 자동으로 업데이트&quot;하는 방식이에요.&lt;br /&gt;리액트는 &lt;b&gt;웹뿐만 아니라 모바일 앱 개발(React Native)에도 사용&lt;/b&gt;될 수 있어 확장성이 뛰어나죠.&lt;/p&gt;
&lt;p data-end=&quot;904&quot; data-start=&quot;782&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-filename=&quot;스크린샷 2025-09-13 오후 5.15.39.png&quot; data-origin-width=&quot;2240&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFBkVJ/btsQxb4QENB/G9Rq3rV5UdQ7O3bflN3ffK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFBkVJ/btsQxb4QENB/G9Rq3rV5UdQ7O3bflN3ffK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFBkVJ/btsQxb4QENB/G9Rq3rV5UdQ7O3bflN3ffK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFBkVJ%2FbtsQxb4QENB%2FG9Rq3rV5UdQ7O3bflN3ffK%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;2240&quot; height=&quot;1254&quot; data-filename=&quot;스크린샷 2025-09-13 오후 5.15.39.png&quot; data-origin-width=&quot;2240&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;1. 리액트 설치&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;보통은 간편하기 때문에 CRA 방식으로 프로젝트를 시작하시곤 해요. 저희 회사역시도 CRA로 만든 프로젝트들이 많습니다.&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;(하지만 최근 리액트에서는 해당 방식을 사용하지 말라고 해요. CRA 방법도 설명해드리지만 권장하진 않습니다.)&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;우선 CRA 방식 설명해드릴께요. 왜 리액트 공식 페이지에서 다른 방법을 권장하는지는 이 설명 밑에서 자세히 다룰께요.&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;167&quot; data-start=&quot;91&quot; data-ke-size=&quot;size16&quot;&gt;리액트 프로젝트를 만들려면 Node.js가 필요해요.&lt;br /&gt;설치 후 터미널에서 이렇게 입력하면 간단하게 새 프로젝트를 만들 수 있어요.&lt;/p&gt;
&lt;pre id=&quot;code_1757750665339&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx create-react-app my-app
cd my-app
npm start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&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;314&quot; data-start=&quot;230&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;271&quot; data-start=&quot;230&quot;&gt;create-react-app : 리액트 프로젝트를 빠르게 생성&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;272&quot;&gt;npm start : 개발 서버를 실행해서 브라우저에서 바로 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;374&quot; data-start=&quot;316&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;318&quot; data-ke-size=&quot;size16&quot;&gt;이제 브라우저에서 http://localhost:3000을 열면 기본 페이지가 나타나요.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;npx create-react-app my-app&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&quot; data-ke-size=&quot;size16&quot;&gt;해당 명령어를 CRA(Create React App) 방식이라고 말해요.&lt;/p&gt;
&lt;p data-end=&quot;1142&quot; data-start=&quot;1013&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;419&quot; data-start=&quot;88&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;259&quot; data-start=&quot;88&quot;&gt;&lt;b&gt;CRA란?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;259&quot; data-start=&quot;104&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;162&quot; data-start=&quot;104&quot;&gt;페이스북이 만든 공식 툴로, 리액트 프로젝트를 &lt;b&gt;빠르게 생성하고 개발 환경을 세팅&lt;/b&gt;해주는 도구&lt;/li&gt;
&lt;li data-end=&quot;222&quot; data-start=&quot;165&quot;&gt;번들러(Webpack), Babel, ESLint 같은 복잡한 설정을 &lt;b&gt;자동으로 구성&lt;/b&gt;해 줌&lt;/li&gt;
&lt;li data-end=&quot;259&quot; data-start=&quot;225&quot;&gt;덕분에 바로 코드를 작성하고 개발 서버를 띄울 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;419&quot; data-start=&quot;261&quot;&gt;&lt;b&gt;명령어 설명&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;419&quot; data-start=&quot;278&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;341&quot; data-start=&quot;278&quot;&gt;npx create-react-app my-app &amp;rarr; my-app이라는 폴더에 새 리액트 프로젝트 생성&lt;/li&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;344&quot;&gt;cd my-app &amp;rarr; 프로젝트 폴더로 이동&lt;/li&gt;
&lt;li data-end=&quot;419&quot; data-start=&quot;376&quot;&gt;npm start &amp;rarr; 개발 서버 실행, 브라우저에서 결과 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간편하다는 장점으로 리액트 초창기에는 많은 사람들이 CRA 방식을 선호했답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 최근에는,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 공식 문서에서는 &lt;b&gt;새로운 프로젝트에 create-react-app(CRA)을 사용하지 말고&lt;/b&gt;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 &lt;b&gt;Next.js&lt;/b&gt;, &lt;b&gt;Vite&lt;/b&gt;, &lt;b&gt;Parcel&lt;/b&gt;, &lt;b&gt;Remix&lt;/b&gt;와 같은 최신 프레임워크나 빌드 도구를 사용하라고 권장하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;173&quot; data-start=&quot;158&quot; data-ke-size=&quot;size23&quot;&gt;  공식 권장 사항&lt;/h3&gt;
&lt;p data-end=&quot;396&quot; data-start=&quot;175&quot; data-ke-size=&quot;size16&quot;&gt;2025년 2월 14일, 리액트 팀은 CRA를 공식적으로 사용 중단(deprecate)한다고 발표했습니다.&lt;/p&gt;
&lt;p data-end=&quot;396&quot; data-start=&quot;175&quot; data-ke-size=&quot;size16&quot;&gt;이후 새로 생성한 프로젝트에서는 CRA를 사용할 때마다 경고 메시지가 표시됩니다.&lt;/p&gt;
&lt;p data-end=&quot;396&quot; data-start=&quot;175&quot; data-ke-size=&quot;size16&quot;&gt;CRA는 더 이상 활성 유지보수가 이루어지지 않으며, 최신 리액트 버전(React 19)과의 호환성 문제로 인해 권장되지 않습니다 &lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://react.dev/blog/2025/02/14/sunsetting-create-react-app?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;react.dev&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h3 data-end=&quot;417&quot; data-start=&quot;398&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;417&quot; data-start=&quot;398&quot; data-ke-size=&quot;size23&quot;&gt;✅ 왜 CRA를 지양하나요?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;691&quot; data-start=&quot;419&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;419&quot;&gt;&lt;b&gt;성능 문제&lt;/b&gt;: CRA는 Webpack을 기반으로 하여 개발 서버 시작 속도와 핫 리로드(HMR)가 느립니다.&lt;/li&gt;
&lt;li data-end=&quot;563&quot; data-start=&quot;485&quot;&gt;&lt;b&gt;최신 기능 부족&lt;/b&gt;: 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 코드 분할 등의 기능이 기본적으로 지원되지 않습니다.&lt;/li&gt;
&lt;li data-end=&quot;691&quot; data-start=&quot;564&quot;&gt;&lt;b&gt;유지보수 부족&lt;/b&gt;: CRA는 2021년부터 활발한 유지보수가 이루어지지 않고 있으며, 리액트 19와의 호환성 문제로 인해 더 이상 권장되지 않습니다 &lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://socket.dev/blog/create-react-app-officially-deprecated?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Socket&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;713&quot; data-start=&quot;693&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;713&quot; data-start=&quot;693&quot; data-ke-size=&quot;size23&quot;&gt;  대안으로 권장되는 도구들&lt;/h3&gt;
&lt;p data-end=&quot;744&quot; data-start=&quot;715&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;744&quot; data-start=&quot;715&quot; data-ke-size=&quot;size16&quot;&gt;리액트 팀은 다음과 같은 도구들을 권장하고 있습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1000&quot; data-start=&quot;746&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;830&quot; data-start=&quot;746&quot;&gt;&lt;b&gt;Next.js&lt;/b&gt;: 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), API 라우팅 등 다양한 기능을 제공하는 풀스택 프레임워크입니다.&lt;/li&gt;
&lt;li data-end=&quot;896&quot; data-start=&quot;831&quot;&gt;&lt;b&gt;Vite&lt;/b&gt;: ESBuild를 기반으로 한 빠른 개발 서버와 빌드 도구로, 설정이 간단하고 성능이 뛰어납니다.&lt;/li&gt;
&lt;li data-end=&quot;937&quot; data-start=&quot;897&quot;&gt;&lt;b&gt;Parcel&lt;/b&gt;: 제로 설정으로 빠른 빌드를 지원하는 도구입니다.&lt;/li&gt;
&lt;li data-end=&quot;1000&quot; data-start=&quot;938&quot;&gt;&lt;b&gt;Remix&lt;/b&gt;: 웹 표준을 기반으로 한 최신 프레임워크로, 데이터 패칭과 렌더링 최적화에 중점을 둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1002&quot; data-ke-size=&quot;size16&quot;&gt;이러한 도구들은 최신 리액트 기능을 지원하며, 성능과 개발 경험을 향상시킬 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1072&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;1072&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size23&quot;&gt; ️ CRA를 대체하려면?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1224&quot; data-start=&quot;1074&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1138&quot; data-start=&quot;1074&quot;&gt;&lt;b&gt;새로운 프로젝트 시작 시&lt;/b&gt;: CRA 대신 위에서 언급한 도구들 중 하나를 선택하여 시작하는 것이 좋습니다.&lt;/li&gt;
&lt;li data-end=&quot;1224&quot; data-start=&quot;1139&quot;&gt;&lt;b&gt;기존 CRA 프로젝트를 마이그레이션할 때&lt;/b&gt;: 리액트 팀은 Vite, Next.js, Remix 등으로의 마이그레이션 가이드를 제공하고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1351&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;리액트 공식 문서에서는 이러한 대체 도구들에 대한 자세한 정보를 제공하고 있으며, 프로젝트의 요구사항에 맞는 도구를 선택할 수 있도록 안내하고 있습니다 &lt;span data-state=&quot;closed&quot;&gt;&lt;span data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a href=&quot;https://react.dev/learn/installation?utm_source=chatgpt.com&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;react.dev&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-end=&quot;1351&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1351&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1351&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;118&quot; data-start=&quot;106&quot; data-ke-size=&quot;size26&quot;&gt;리액트 핵심 문법&lt;/h2&gt;
&lt;p data-end=&quot;238&quot; data-start=&quot;120&quot; data-ke-size=&quot;size16&quot;&gt;리액트에서 가장 기본이 되는 개념은 &lt;b&gt;State와 Props&lt;/b&gt;입니다.&lt;br /&gt;이 두 가지를 이해하면, 컴포넌트 단위로 UI를 만들고 데이터가 바뀔 때 화면이 어떻게 업데이트되는지 쉽게 이해할 수 있어요.  &lt;/p&gt;
&lt;p data-end=&quot;100&quot; data-start=&quot;79&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;100&quot; data-start=&quot;79&quot; data-ke-size=&quot;size23&quot;&gt;State&amp;nbsp; =&amp;nbsp; 컴포넌트의 메모리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;217&quot; data-start=&quot;102&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;134&quot; data-start=&quot;102&quot;&gt;&lt;b&gt;컴포넌트가 가지고 있는 값들을 저장&lt;/b&gt;하는 공간&lt;/li&gt;
&lt;li data-end=&quot;165&quot; data-start=&quot;135&quot;&gt;값이 바뀌면 리액트가 알아서 &lt;b&gt;UI를 갱신&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;217&quot; data-start=&quot;166&quot;&gt;페이지 전체를 새로고침하지 않고도 &lt;b&gt;상태 변화에 따라 화면을 업데이트&lt;/b&gt;할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757751549387&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from &quot;react&quot;;

function Counter() {
  const [count, setCount] = useState(0); // 여기서 count가 메모리 역할

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;현재 숫자: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;증가&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;508&quot; data-start=&quot;421&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;518&quot; data-start=&quot;486&quot;&gt;count는 &lt;b&gt;컴포넌트가 기억하고 있는 값&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;550&quot; data-start=&quot;519&quot;&gt;버튼 클릭 시 setCount로 값을 바꾸면,&lt;/li&gt;
&lt;li data-end=&quot;582&quot; data-start=&quot;551&quot;&gt;리액트가 &lt;b&gt;변경된 값으로 화면을 다시 그려줌&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;508&quot; data-start=&quot;421&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;508&quot; data-start=&quot;421&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;100&quot; data-start=&quot;76&quot; data-ke-size=&quot;size23&quot;&gt;Props = 부모가 내려주는 값 (부모 = 상위컴포넌트)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;226&quot; data-start=&quot;102&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;135&quot; data-start=&quot;102&quot;&gt;&lt;b&gt;Props는 컴포넌트가 부모로부터 받는 데이터&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;182&quot; data-start=&quot;136&quot;&gt;읽기 전용(Read-only)이어서, 자식 컴포넌트에서는 직접 바꿀 수 없음&lt;/li&gt;
&lt;li data-end=&quot;226&quot; data-start=&quot;183&quot;&gt;화면에 데이터를 전달하거나, 컴포넌트 재사용 시 설정값을 넣을 때 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757751623679&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Greeting({ name }) {
  return &amp;lt;h1&amp;gt;안녕하세요, {name}님!  &amp;lt;/h1&amp;gt;;
}

function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Greeting name=&quot;콘솔로그&quot; /&amp;gt;
      &amp;lt;Greeting name=&quot;프론트엔드 개발자&quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;520&quot; data-start=&quot;432&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;495&quot; data-start=&quot;432&quot;&gt;부모(App)에서 name=&quot;콘솔로그&quot;과 name=&quot;프론트엔드 개발자&quot;를 자식(Greeting)에 전달&lt;/li&gt;
&lt;li data-end=&quot;520&quot; data-start=&quot;496&quot;&gt;자식은 받은 값을 그대로 화면에 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;548&quot; data-start=&quot;527&quot; data-ke-size=&quot;size23&quot;&gt;State와 Props 차이&lt;/h3&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;863&quot; data-start=&quot;550&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구분&lt;/td&gt;
&lt;td&gt;State&lt;/td&gt;
&lt;td&gt;Props&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;749&quot; data-start=&quot;697&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;708&quot; data-start=&quot;697&quot;&gt;정의&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;729&quot; data-start=&quot;708&quot;&gt;컴포넌트 내부에서 관리하는 데이터&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;749&quot; data-start=&quot;729&quot;&gt;부모가 자식에게 전달하는 값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;810&quot; data-start=&quot;750&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;759&quot; data-start=&quot;750&quot;&gt;변경 가능&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;787&quot; data-start=&quot;759&quot;&gt;가능 (setState 사용)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;810&quot; data-start=&quot;787&quot;&gt;불가능 (읽기 전용)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;863&quot; data-start=&quot;811&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;822&quot; data-start=&quot;811&quot;&gt;역할&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;844&quot; data-start=&quot;822&quot;&gt;UI가 동적으로 바뀔 때 사용&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;863&quot; data-start=&quot;844&quot;&gt;컴포넌트 설정/데이터 전달용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;865&quot; data-ke-size=&quot;size16&quot;&gt;  쉽게 비유하면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;981&quot; data-start=&quot;880&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;923&quot; data-start=&quot;880&quot;&gt;&lt;b&gt;State&lt;/b&gt; &amp;rarr; &amp;ldquo;컴포넌트 안에서 마음대로 바꿀 수 있는 메모리&amp;rdquo;&lt;/li&gt;
&lt;li data-end=&quot;981&quot; data-start=&quot;924&quot;&gt;&lt;b&gt;Props&lt;/b&gt; &amp;rarr; &amp;ldquo;부모가 준 선물 상자, 열어서 볼 수는 있지만 마음대로 바꿀 수는 없음&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;App&lt;br /&gt;&amp;nbsp;├─&amp;nbsp;Counter(state:&amp;nbsp;count=0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;--&amp;nbsp;state는&amp;nbsp;Counter에서&amp;nbsp;관리&lt;br /&gt;&amp;nbsp;└─&amp;nbsp;Greeting(state:&amp;nbsp;name=&quot;콘솔로그&quot;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;--&amp;nbsp;Greeting&amp;nbsp;자체&amp;nbsp;state&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└─&amp;nbsp;Profile(props:&amp;nbsp;name=&quot;콘솔로그&quot;,&amp;nbsp;state:&amp;nbsp;age=25)&amp;nbsp;&amp;nbsp;&amp;lt;--&amp;nbsp;Profile에서&amp;nbsp;age&amp;nbsp;state&amp;nbsp;관리,&amp;nbsp;부모(Greeting)의&amp;nbsp;name을&amp;nbsp;props로&amp;nbsp;사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;465&quot; data-start=&quot;327&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;359&quot; data-start=&quot;327&quot;&gt;Counter &amp;rarr; 자체 count 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;392&quot; data-start=&quot;360&quot;&gt;Greeting &amp;rarr; 자체 name 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;465&quot; data-start=&quot;393&quot;&gt;Profile &amp;rarr; 부모(Greeting)로부터 받은 name을 &lt;b&gt;props&lt;/b&gt;로 사용, 자체 age 상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;558&quot; data-start=&quot;467&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;558&quot; data-start=&quot;467&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;558&quot; data-start=&quot;467&quot; data-ke-size=&quot;size23&quot;&gt;리액트의 조건부로 렌더링&lt;/h3&gt;
&lt;p data-end=&quot;558&quot; data-start=&quot;467&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 앞서 설명했듯 &lt;b&gt;SPA 기반&lt;/b&gt;이기 때문에, &lt;b&gt;조건부 렌더링&lt;/b&gt;을 활용해 효율적이고 부드러운 화면 업데이트를 제공합니다.&lt;/p&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;163&quot; data-ke-size=&quot;size16&quot;&gt;왜 리액트는 조건부로 렌더링할까요? 그 이유는 아래와 같습니다.&lt;/p&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;163&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;202&quot; data-start=&quot;187&quot; data-ke-size=&quot;size20&quot;&gt;1️⃣ 성능 최적화&lt;/h4&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;203&quot; data-ke-size=&quot;size16&quot;&gt;웹 앱에서 모든 상태 변화마다 전체 화면을 다시 그리면 느려집니다.&lt;br /&gt;특히 SPA에서는 한 페이지 안에 여러 컴포넌트가 동시에 존재하기 때문에, 불필요하게 렌더링하면 &lt;b&gt;속도 저하&lt;/b&gt;와 &lt;b&gt;브라우저 과부하&lt;/b&gt;가 생길 수 있습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;406&quot; data-start=&quot;336&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;406&quot; data-start=&quot;338&quot; data-ke-size=&quot;size16&quot;&gt;예: 100개의 리스트 아이템이 있을 때,&lt;br /&gt;하나의 아이템만 바뀌었는데 100개를 다 다시 그리면 비효율적입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-end=&quot;434&quot; data-start=&quot;413&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;434&quot; data-start=&quot;413&quot; data-ke-size=&quot;size20&quot;&gt;2️⃣ 필요한 부분만 업데이트&lt;/h4&gt;
&lt;p data-end=&quot;555&quot; data-start=&quot;435&quot; data-ke-size=&quot;size16&quot;&gt;리액트는 &lt;b&gt;Virtual DOM&lt;/b&gt;을 사용하여 실제 DOM과 비교(Diff)한 후,&lt;br /&gt;변경된 부분만 실제 DOM에 반영합니다.&lt;br /&gt;즉, 조건부 렌더링으로 &lt;b&gt;UI의 필요한 부분만 업데이트&lt;/b&gt;되어 효율적입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;584&quot; data-start=&quot;562&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;584&quot; data-start=&quot;562&quot; data-ke-size=&quot;size20&quot;&gt;3️⃣ 상태와 데이터 기반 UI&lt;/h4&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;585&quot; data-ke-size=&quot;size16&quot;&gt;리액트의 핵심 철학은 &lt;b&gt;데이터가 UI를 결정한다(Data-driven UI)&lt;/b&gt; 입니다.&lt;br /&gt;State, Props, Context 등의 값이 바뀔 때만 렌더링되므로,&lt;br /&gt;&lt;b&gt;화면과 데이터의 일관성을 유지&lt;/b&gt;할 수 있습니다.&lt;br /&gt;불필요한 렌더링을 줄이고, 사용자가 보는 화면과 실제 데이터가 항상 일치하게 됩니다.&lt;/p&gt;
&lt;h4 data-end=&quot;788&quot; data-start=&quot;770&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;788&quot; data-start=&quot;770&quot; data-ke-size=&quot;size20&quot;&gt;4️⃣ 사용자 경험 향상&lt;/h4&gt;
&lt;p data-end=&quot;904&quot; data-start=&quot;789&quot; data-ke-size=&quot;size16&quot;&gt;필요한 부분만 빠르게 업데이트하므로, &lt;b&gt;화면 전환이 부드럽고 자연스러움&lt;/b&gt;&lt;br /&gt;전체 페이지를 다시 불러오지 않아 &lt;b&gt;몰입감 있는 UI 경험&lt;/b&gt;을 제공하며,&lt;br /&gt;SPA 환경에서는 특히 중요한 요소입니다.&lt;/p&gt;
&lt;p data-end=&quot;904&quot; data-start=&quot;789&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;134&quot; data-start=&quot;111&quot; data-ke-size=&quot;size26&quot;&gt;라이프사이클과 훅(Hooks)&lt;/h2&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;136&quot; data-ke-size=&quot;size16&quot;&gt;리액트 컴포넌트는 생성되고, 업데이트되고, 삭제되는 생명주기(Lifecycle)를 가지고 있어요.&lt;br /&gt;클래스형 컴포넌트에서는 componentDidMount, componentDidUpdate, componentWillUnmount 같은 메서드를 사용했지만,&lt;br /&gt;함수형 컴포넌트에서는 &lt;b&gt;Hooks&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;337&quot; data-start=&quot;326&quot; data-ke-size=&quot;size23&quot;&gt;주요 훅 예시&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;499&quot; data-start=&quot;338&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;386&quot; data-start=&quot;338&quot;&gt;useEffect: 컴포넌트가 &lt;b&gt;생성, 업데이트, 삭제&lt;/b&gt;될 때 동작 정의&lt;/li&gt;
&lt;li data-end=&quot;442&quot; data-start=&quot;387&quot;&gt;useMemo: 계산량이 많은 값이나 함수를 &lt;b&gt;메모이제이션&lt;/b&gt;하여 불필요한 재계산 방지&lt;/li&gt;
&lt;li data-end=&quot;499&quot; data-start=&quot;443&quot;&gt;useCallback: 함수 자체를 메모이제이션해서 &lt;b&gt;자식 컴포넌트 불필요한 렌더링 방지&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;** &lt;/b&gt;리액트에서 생명주기가 필요한 이유&lt;/p&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;93&quot; data-ke-size=&quot;size16&quot;&gt;리액트 컴포넌트는 단순히 &lt;b&gt;한 번 그려지는 UI&lt;/b&gt;가 아니라, &lt;b&gt;동적으로 변화하는 화면&lt;/b&gt;을 만들기 위해 존재합니다.&lt;br /&gt;따라서 컴포넌트가 생성되고, 업데이트되고, 사라지는 과정마다 &lt;b&gt;특정 작업을 처리할 필요&lt;/b&gt;가 있어요.&lt;/p&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;93&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;222&quot; data-start=&quot;93&quot; data-ke-size=&quot;size16&quot;&gt;  요약하면, 생명주기가 필요한 이유는:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;960&quot; data-start=&quot;851&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;889&quot; data-start=&quot;851&quot;&gt;&lt;b&gt;초기화 작업&lt;/b&gt;: 컴포넌트가 생성될 때 필요한 작업 수행&lt;/li&gt;
&lt;li data-end=&quot;927&quot; data-start=&quot;890&quot;&gt;&lt;b&gt;업데이트 작업&lt;/b&gt;: 상태/데이터 변경에 따라 작업 수행&lt;/li&gt;
&lt;li data-end=&quot;960&quot; data-start=&quot;928&quot;&gt;&lt;b&gt;정리 작업&lt;/b&gt;: 컴포넌트 제거 시 리소스 정리&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1087&quot; data-start=&quot;962&quot; data-ke-size=&quot;size16&quot;&gt;즉, 생명주기는 &lt;b&gt;컴포넌트의 &amp;ldquo;생성과 관리, 종료&amp;rdquo;를 체계적으로 다루기 위해 필요&lt;/b&gt;합니다.&lt;br /&gt;SPA 환경에서 수많은 컴포넌트가 동시에 존재할 때, &lt;b&gt;리소스 누수 없이 효율적으로 동작&lt;/b&gt;하게 만드는 핵심 개념이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1115&quot; data-start=&quot;1098&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;1115&quot; data-start=&quot;1098&quot; data-ke-size=&quot;size26&quot;&gt;조건부 렌더링 확장&lt;/h2&gt;
&lt;p data-end=&quot;1193&quot; data-start=&quot;1117&quot; data-ke-size=&quot;size16&quot;&gt;리액트에서 조건부 렌더링은 UI를 &lt;b&gt;필요한 상황에서만 보여주는 기능&lt;/b&gt;이에요.&lt;br /&gt;기본적인 삼항연산자 외에도 여러 방법이 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757752355355&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const isLoggedIn = true;

return (
  &amp;lt;div&amp;gt;
    {/* 삼항연산자 */}
    {isLoggedIn ? &amp;lt;p&amp;gt;환영합니다!&amp;lt;/p&amp;gt; : &amp;lt;p&amp;gt;로그인이 필요합니다.&amp;lt;/p&amp;gt;}

    {/* &amp;amp;&amp;amp; 연산자 */}
    {isLoggedIn &amp;amp;&amp;amp; &amp;lt;button&amp;gt;로그아웃&amp;lt;/button&amp;gt;}

    {/* switch 사용 */}
    {(() =&amp;gt; {
      switch(status) {
        case &quot;loading&quot;: return &amp;lt;p&amp;gt;로딩 중...&amp;lt;/p&amp;gt;;
        case &quot;error&quot;: return &amp;lt;p&amp;gt;에러 발생!&amp;lt;/p&amp;gt;;
        default: return &amp;lt;p&amp;gt;데이터 준비 완료&amp;lt;/p&amp;gt;;
      }
    })()}
  &amp;lt;/div&amp;gt;
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  포인트:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1685&quot; data-start=&quot;1624&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1663&quot; data-start=&quot;1624&quot;&gt;조건부 렌더링으로 &lt;b&gt;불필요한 요소 생성 방지&lt;/b&gt; &amp;rarr; 성능 개선&lt;/li&gt;
&lt;li data-end=&quot;1685&quot; data-start=&quot;1664&quot;&gt;UI 흐름을 깔끔하게 유지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1711&quot; data-start=&quot;1692&quot; data-ke-size=&quot;size26&quot;&gt;컴포넌트 구조와 재사용&lt;/h2&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;리액트의 핵심 장점 중 하나는 &lt;b&gt;컴포넌트를 재사용 가능하게 구조화&lt;/b&gt;할 수 있다는 점이에요.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 리액트가 등장한 배경과 SPA, 그리고 리액트의 핵심 문법과 렌더링 원리에 대해 이야기해봤어요.&lt;br /&gt;리액트는 단순히 인기 있는 라이브러리가 아니라, &lt;b&gt;복잡한 SPA 개발을 효율적으로 만들어주는 도구&lt;/b&gt;예요.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;State와 Props를 통해 컴포넌트 단위로 데이터를 관리하고, 조건부 렌더링으로 필요한 부분만 업데이트할 수 있죠.&lt;br /&gt;Hooks를 활용하면 함수형 컴포넌트에서도 생명주기 관리와 성능 최적화가 가능해요.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;컴포넌트를 구조화하고 재사용하며, React.memo 같은 최적화를 적용하면 &lt;b&gt;유지보수성과 성능&lt;/b&gt;까지 잡을 수 있습니다.&lt;br /&gt;Virtual DOM 덕분에 화면 갱신이 효율적이고, 사용자 경험도 부드럽고 자연스럽게 만들어줍니다.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;리액트를 이해하면 단순히 코드를 작성하는 수준을 넘어, &lt;b&gt;데이터와 UI를 어떻게 설계할지&lt;/b&gt; 감이 생깁니다.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;처음에는 어렵게 느껴질 수 있지만, 차근차근 State, Props, 렌더링 원리부터 익히면 금방 익숙해져요.&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;리액트의 세계에 발을 들이면, 웹 개발이 훨씬 더 즐겁고 직관적으로 느껴질 거예요!  &lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1767&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽어보면 좋을 만한 참고 사이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SPA 관련 정리 글 : &lt;a href=&quot;https://www.elancer.co.kr/blog/detail/214&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.elancer.co.kr/blog/detail/214&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757750190353&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SPA란? 웹 개발 트렌드 SPA의  특징부터 구현 방법까지 모두 알려드립니다! I 이랜서 블로그&quot; data-og-description=&quot;웹 페이지 로딩 속도를 향상시키고 트래픽을 줄여 부드러운 페이지 전환과 함께 업데이트가 될 때까지 기다리는 시간을 단축시켜 사용자로 하여금 높은 몰입도와 생동감을 선사하는 웹 페이지 &quot; data-og-host=&quot;www.elancer.co.kr&quot; data-og-source-url=&quot;https://www.elancer.co.kr/blog/detail/214&quot; data-og-url=&quot;https://www.elancer.co.kr/blog/detail/214&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cTsiPL/hyZI1FhFZ8/u3hOVZYoSQw3xQ6DVORdW1/img.png?width=500&amp;amp;height=281&amp;amp;face=0_0_500_281,https://scrap.kakaocdn.net/dn/c5gWl1/hyZIMuzNSL/BJDxzPRYqNcigcCuobAGw1/img.png?width=500&amp;amp;height=281&amp;amp;face=0_0_500_281,https://scrap.kakaocdn.net/dn/FA5Yy/hyZJiMbq74/8WJq3Y2WSnNH6OzEQkIvw0/img.jpg?width=1920&amp;amp;height=1300&amp;amp;face=0_0_1920_1300&quot;&gt;&lt;a href=&quot;https://www.elancer.co.kr/blog/detail/214&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.elancer.co.kr/blog/detail/214&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cTsiPL/hyZI1FhFZ8/u3hOVZYoSQw3xQ6DVORdW1/img.png?width=500&amp;amp;height=281&amp;amp;face=0_0_500_281,https://scrap.kakaocdn.net/dn/c5gWl1/hyZIMuzNSL/BJDxzPRYqNcigcCuobAGw1/img.png?width=500&amp;amp;height=281&amp;amp;face=0_0_500_281,https://scrap.kakaocdn.net/dn/FA5Yy/hyZJiMbq74/8WJq3Y2WSnNH6OzEQkIvw0/img.jpg?width=1920&amp;amp;height=1300&amp;amp;face=0_0_1920_1300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SPA란? 웹 개발 트렌드 SPA의 특징부터 구현 방법까지 모두 알려드립니다! I 이랜서 블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;웹 페이지 로딩 속도를 향상시키고 트래픽을 줄여 부드러운 페이지 전환과 함께 업데이트가 될 때까지 기다리는 시간을 단축시켜 사용자로 하여금 높은 몰입도와 생동감을 선사하는 웹 페이지&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.elancer.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 공식문서: &lt;a href=&quot;https://ko.react.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.react.dev/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757752506398&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;React&quot; data-og-description=&quot;React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizati&quot; data-og-host=&quot;ko.react.dev&quot; data-og-source-url=&quot;https://ko.react.dev/&quot; data-og-url=&quot;https://ko.react.dev/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xgzAg/hyZI66LnG2/sik854tPJzDfkJi1VGMJY1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/coIpRw/hyZI3WwPZq/IlAe3SuPjjWZ8KbLP9g0tK/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://ko.react.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.react.dev/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xgzAg/hyZI66LnG2/sik854tPJzDfkJi1VGMJY1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/coIpRw/hyZI3WwPZq/IlAe3SuPjjWZ8KbLP9g0tK/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizati&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 기초 및 TodoLIst: &lt;a href=&quot;https://react.vlpt.us/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://react.vlpt.us/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757752699678&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;벨로퍼트와 함께하는 모던 리액트 &amp;middot; GitBook&quot; data-og-description=&quot;벨로퍼트와 함께하는 모던 리액트 본 강의자료는 패스트캠퍼스 온라인 강의에서 제공하는 리액트 강의에서 사용되는 강의 문서입니다. 이 튜토리얼은 여러분들이 JavaScript 의 기초를 잘 알고있&quot; data-og-host=&quot;react.vlpt.us&quot; data-og-source-url=&quot;https://react.vlpt.us/&quot; data-og-url=&quot;https://react.vlpt.us/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://react.vlpt.us/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://react.vlpt.us/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;벨로퍼트와 함께하는 모던 리액트 &amp;middot; GitBook&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;벨로퍼트와 함께하는 모던 리액트 본 강의자료는 패스트캠퍼스 온라인 강의에서 제공하는 리액트 강의에서 사용되는 강의 문서입니다. 이 튜토리얼은 여러분들이 JavaScript 의 기초를 잘 알고있&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;react.vlpt.us&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 따라해보기: &lt;a href=&quot;https://nomadcoders.co/react-for-beginners&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nomadcoders.co/react-for-beginners&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757752671835&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;React 리액트 무료 강의: 영화 웹 서비스 만들기 (56,000명 수강 중)&quot; data-og-description=&quot;리액트의 기본기를 쉽고 실습 위주로 배워보세요. JSX, State, Props, 컴포넌트, 데이터 가져오기, 라우팅 등 핵심 개념을 익히고, 직접 영화 웹 서비스를 만들어보며 실전 경험을 쌓을 수 있습니다. 5&quot; data-og-host=&quot;nomadcoders.co&quot; data-og-source-url=&quot;https://nomadcoders.co/react-for-beginners&quot; data-og-url=&quot;https://nomadcoders.co/react-for-beginners&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Pyv0j/hyZJkb99Y3/NRsqyjdWajxOdJjRsAl3Mk/img.jpg?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260,https://scrap.kakaocdn.net/dn/dcTEZT/hyZIYaHGw3/lvESkkKFOkAP8QkgYVpck0/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://nomadcoders.co/react-for-beginners&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://nomadcoders.co/react-for-beginners&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Pyv0j/hyZJkb99Y3/NRsqyjdWajxOdJjRsAl3Mk/img.jpg?width=2400&amp;amp;height=1260&amp;amp;face=0_0_2400_1260,https://scrap.kakaocdn.net/dn/dcTEZT/hyZIYaHGw3/lvESkkKFOkAP8QkgYVpck0/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;React 리액트 무료 강의: 영화 웹 서비스 만들기 (56,000명 수강 중)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;리액트의 기본기를 쉽고 실습 위주로 배워보세요. JSX, State, Props, 컴포넌트, 데이터 가져오기, 라우팅 등 핵심 개념을 익히고, 직접 영화 웹 서비스를 만들어보며 실전 경험을 쌓을 수 있습니다. 5&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;nomadcoders.co&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 로그/React</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/89</guid>
      <comments>https://jjung2ing.tistory.com/89#entry89comment</comments>
      <pubDate>Sat, 13 Sep 2025 17:38:25 +0900</pubDate>
    </item>
    <item>
      <title>[개발읽기 vol.8] Zustand: 최소한의 코드로 최대한의 상태관리</title>
      <link>https://jjung2ing.tistory.com/88</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.44.43.png&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UoXx4/btsQvzK8KBK/3o2mqgKrZGHsdiIg16qaNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UoXx4/btsQvzK8KBK/3o2mqgKrZGHsdiIg16qaNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UoXx4/btsQvzK8KBK/3o2mqgKrZGHsdiIg16qaNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUoXx4%2FbtsQvzK8KBK%2F3o2mqgKrZGHsdiIg16qaNk%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;3018&quot; height=&quot;1640&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.44.43.png&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 &lt;b&gt;상태관리 라이브러리인 Zustand&lt;/b&gt;에 대해 이야기해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;저희 회사에서는 따로 상태관리 라이브러리를 쓰지 않고 있어서, 실무에서 직접적으로 다룰 기회는 거의 없었어요.&lt;br /&gt;그런데 최근 채용 공고를 살펴보다 보면, 대부분의 회사들이 상태관리 경험을 중요하게 보는 경우가 많더라구요.&lt;br /&gt;특히 Redux, Recoil, Zustand 같은 키워드가 빠지지 않고 등장하는 걸 보면서 &amp;lsquo;나도 한번 제대로 공부해봐야겠다&amp;rsquo;는 생각이 들었습니다.&lt;br /&gt;그래서 이번 기회에 Zustand를 직접 써보고, 기존에 많이 사용되는 Redux와는 어떻게 다른지 비교도 해봤어요.&lt;br /&gt;생각보다 진입 장벽이 낮고, 코드가 간결해서 개인적으로는 꽤 만족스러웠는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm trend 사이트에서 보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 &lt;b&gt;Zustand의 사용량이 급격히 증가&lt;/b&gt;한 것을 확인할 수 있습니다.&lt;br /&gt;현재는 Redux 다음으로 많이 사용되고 있는데,&lt;br /&gt;기존에 대부분의 개발자들이 Redux를 주로 활용해왔다는 점을 고려하면 이 추세가 정말 인상적이라고 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.57.24.png&quot; data-origin-width=&quot;2598&quot; data-origin-height=&quot;1486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP6JAa/btsQvxs0fEy/Cf88nRCUtt1fUlKxnXVC8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP6JAa/btsQvxs0fEy/Cf88nRCUtt1fUlKxnXVC8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP6JAa/btsQvxs0fEy/Cf88nRCUtt1fUlKxnXVC8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP6JAa%2FbtsQvxs0fEy%2FCf88nRCUtt1fUlKxnXVC8k%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;2598&quot; height=&quot;1486&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.57.24.png&quot; data-origin-width=&quot;2598&quot; data-origin-height=&quot;1486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;b&gt;패키지 사이즈&lt;/b&gt; 측면에서도 정말 매력적인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Zustand는 다른 상태관리 라이브러리에 비해 굉장히 가벼운 편이라 번들 크기에 거의 부담을 주지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 설치해보면 &quot;이게 진짜 상태관리 라이브러리 맞아?&quot; 싶을 정도로 크기가 작아서,&lt;br /&gt;프로젝트 성능 최적화를 신경 쓰는 분들에게 특히 매력적으로 다가옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.59.14.png&quot; data-origin-width=&quot;2570&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8e76u/btsQtReM7YA/UWFKRQKKDC7uBcs7Xg3Jc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8e76u/btsQtReM7YA/UWFKRQKKDC7uBcs7Xg3Jc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8e76u/btsQtReM7YA/UWFKRQKKDC7uBcs7Xg3Jc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8e76u%2FbtsQtReM7YA%2FUWFKRQKKDC7uBcs7Xg3Jc1%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;2570&quot; height=&quot;644&quot; data-filename=&quot;스크린샷 2025-09-12 오전 10.59.14.png&quot; data-origin-width=&quot;2570&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 방법도 놀라울 만큼 간단&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Zustand 공식 홈페이지에 들어가면 처음에 딱 보이는 코드 예제가 있는데,&lt;br /&gt;처음 보면 &amp;ldquo;어..? 이거면 진짜 끝이야?&amp;rdquo; 싶을 정도로 간단하더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;복잡한 설정이나 보일러플레이트 코드가 필요 없고, 그냥 몇 줄만 작성하면 바로 상태관리를 시작할 수 있습니다.&lt;br /&gt;덕분에 처음 접하는 사람도 금방 이해할 수 있고,&lt;br /&gt;Redux처럼 설정 단계에서부터 부담을 느낄 필요가 없다는 게 큰 장점이에요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-12 오전 11.02.02.png&quot; data-origin-width=&quot;1486&quot; data-origin-height=&quot;1314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GgrVf/btsQt8HoOmH/KHziLCFCBjlOvGDK0ha6L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GgrVf/btsQt8HoOmH/KHziLCFCBjlOvGDK0ha6L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GgrVf/btsQt8HoOmH/KHziLCFCBjlOvGDK0ha6L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGgrVf%2FbtsQt8HoOmH%2FKHziLCFCBjlOvGDK0ha6L1%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;1486&quot; height=&quot;1314&quot; data-filename=&quot;스크린샷 2025-09-12 오전 11.02.02.png&quot; data-origin-width=&quot;1486&quot; data-origin-height=&quot;1314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 Zustand의 특징과 사용법, 그리고 써보면서 느낀 장단점까지 솔직하게 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zustand 말고도 상태관리 라이브러리도 사실 꽤 많은 편인데요, 이번 포스팅에서는 zustand를 자세히 살펴보려고 해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 상태관리가 궁금하시다면 이전에 제가 정리해둔 포스트가 있으니 궁금하신 분들은 아래 글을 참고해주시면 좋을 것 같아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjung2ing.tistory.com/81&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jjung2ing.tistory.com/81&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757641703190&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[개발읽기 vol.5] 2025년 리액트 상태관리 가이드: Redux, Recoil, Zustand, Jotai, MobX 비교&quot; data-og-description=&quot;요즘 채용 공고를 보면,자격요건이나 우대사항에 꼭 한 번쯤은 Redux, Zustand, MobX 같은 상태관리 라이브러리 이름이 등장합니다. 그만큼 리액트에서 상태관리를 어떻게 하느냐가 실무에서 중요한 &quot; data-og-host=&quot;jjung2ing.tistory.com&quot; data-og-source-url=&quot;https://jjung2ing.tistory.com/81&quot; data-og-url=&quot;https://jjung2ing.tistory.com/81&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cV3hox/hyZJb04oUD/FMd0hAIwft8gtxz4FI1Ri0/img.png?width=800&amp;amp;height=447&amp;amp;face=0_0_800_447,https://scrap.kakaocdn.net/dn/cW4zZK/hyZI1ykwTs/IY2AtV4z6GzBCSGKScjIa1/img.png?width=800&amp;amp;height=447&amp;amp;face=0_0_800_447,https://scrap.kakaocdn.net/dn/dEcjIQ/hyZIR3vKfc/AN1MPUYRx0HLPuvKbUhQk1/img.png?width=3008&amp;amp;height=1372&amp;amp;face=0_0_3008_1372&quot;&gt;&lt;a href=&quot;https://jjung2ing.tistory.com/81&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjung2ing.tistory.com/81&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cV3hox/hyZJb04oUD/FMd0hAIwft8gtxz4FI1Ri0/img.png?width=800&amp;amp;height=447&amp;amp;face=0_0_800_447,https://scrap.kakaocdn.net/dn/cW4zZK/hyZI1ykwTs/IY2AtV4z6GzBCSGKScjIa1/img.png?width=800&amp;amp;height=447&amp;amp;face=0_0_800_447,https://scrap.kakaocdn.net/dn/dEcjIQ/hyZIR3vKfc/AN1MPUYRx0HLPuvKbUhQk1/img.png?width=3008&amp;amp;height=1372&amp;amp;face=0_0_3008_1372');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[개발읽기 vol.5] 2025년 리액트 상태관리 가이드: Redux, Recoil, Zustand, Jotai, MobX 비교&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;요즘 채용 공고를 보면,자격요건이나 우대사항에 꼭 한 번쯤은 Redux, Zustand, MobX 같은 상태관리 라이브러리 이름이 등장합니다. 그만큼 리액트에서 상태관리를 어떻게 하느냐가 실무에서 중요한&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjung2ing.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;그리고 아마 &quot;그럼 상태관리 라이브러리가 왜 필요하지?&quot;라는 궁금증이 생기실 수도 있을 것 같아요.&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그 이유는 &lt;b&gt;기존 React의 상태 관리 방식&lt;/b&gt;&amp;nbsp;때문입니다.&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;299&quot; data-start=&quot;186&quot; data-ke-size=&quot;size16&quot;&gt;React에서는 상태가 &lt;b&gt;단방향&lt;/b&gt;으로만 흐르기 때문에, 다른 컴포넌트나 페이지와 상태를 공유하려면&lt;br /&gt;상태를 상위 컴포넌트로 끌어올린 뒤 다시 하위 컴포넌트로 내려주는 방식으로 관리해야 하죠.&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;문제는 이 과정에서 끝도 없이 상태를 내려줘야 하는 이른바 &lt;b&gt;Props Drilling&lt;/b&gt; 현상이 발생한다는 점입니다.&lt;/p&gt;
&lt;p data-end=&quot;505&quot; data-start=&quot;301&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;310&quot; data-start=&quot;198&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;310&quot; data-start=&quot;198&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;PropsDrilling&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중첩된 컴포넌트간 상태고유를 위해 Props를 전달하는 과정에서 Props 전달이 드릴로 땅을 뚫듯 깊어지는 현상으로&lt;/p&gt;
&lt;p 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-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중간에 props를 받기만 하는 컴포넌트가 많아지면 코드가 길어지고, 어떤 데이터가 어디서 왔는지 추적하기 어려워집니다.&lt;/li&gt;
&lt;li&gt;예: App &amp;rarr; A &amp;rarr; B &amp;rarr; C &amp;rarr; D 구조에서 D에만 필요한 데이터라면 A, B, C는 단순 전달자 역할만 하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p 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-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중간 컴포넌트들이 특정 props를 받아야 하므로, 재사용할 때 불필요한 props를 계속 전달해야 할 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p 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-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부모 컴포넌트가 리렌더링되면, props를 받는 모든 중간 컴포넌트가 함께 리렌더링될 수 있습니다.&lt;/li&gt;
&lt;li&gt;성능 저하로 이어질 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p 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-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;많은 계층을 거쳐 props가 전달되면 코드가 장황해지고, 데이터를 이해하고 수정하기 어려워집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 &lt;b&gt;Zustand가 어떻게 Props Drilling 문제를 해결하는지&lt;/b&gt; 이야기해볼게요.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;Zustand를 사용하면 상태를 중앙 저장소(store)에 보관할 수 있어서, 상위 컴포넌트로 끌어올리거나 하위로 내려줄 필요가 없습니다.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;필요한 컴포넌트는 그냥 store에서 상태를 가져다 쓰면 되죠.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;145&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;327&quot; data-start=&quot;145&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;게다가 Zustand는 사용법이 매우 간단합니다.&lt;br /&gt;몇 줄의 코드로 store를 만들고, 원하는 컴포넌트에서 바로 상태를 읽거나 수정할 수 있죠.&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;Redux처럼 복잡한 액션, 리듀서, 미들웨어 설정이 필요 없어서, 작은 프로젝트나 개인 프로젝트에서도 부담 없이 바로 적용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;498&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;498&quot; data-ke-size=&quot;size16&quot;&gt;결과적으로 &lt;b&gt;코드는 더 깔끔해지고 유지보수도 쉬워지며&lt;/b&gt;, 개발자가 상태 관리 때문에 고민할 시간도 줄일 수 있다는 장점이 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;498&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;498&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;  Zustand&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;적은 보일러 플레이트 코드&lt;br /&gt;직관적인 사용법&lt;br /&gt;작은 패키지 사이즈&lt;br /&gt;Flux처럼 단방향이지만 구조는 더 단순함&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  용어정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  보일러플레이트 코드(Boilerplate Code) : &lt;span style=&quot;color: #ee2323;&quot;&gt;zustand는 보일러 플레이트 코드가 적다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 만들 때 &lt;b&gt;반복적으로 꼭 작성해야 하는 기본 틀이나 코드&lt;/b&gt;를 말합니다.&lt;/p&gt;
&lt;p data-end=&quot;158&quot; data-start=&quot;124&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Redux를 사용하면 상태를 관리하려고 할 때,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;239&quot; data-start=&quot;160&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;177&quot; data-start=&quot;160&quot;&gt;액션(action) 정의&lt;/li&gt;
&lt;li data-end=&quot;197&quot; data-start=&quot;178&quot;&gt;리듀서(reducer) 작성&lt;/li&gt;
&lt;li data-end=&quot;215&quot; data-start=&quot;198&quot;&gt;스토어(store) 설정&lt;/li&gt;
&lt;li data-end=&quot;239&quot; data-start=&quot;216&quot;&gt;미들웨어(middleware) 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;241&quot; data-ke-size=&quot;size16&quot;&gt;이런 과정들을 매번 비슷한 형태로 작성해야 하죠.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;241&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;실제 로직과 상관없이 구조상 꼭 필요한 반복 코드&lt;/b&gt;가 바로 보일러플레이트 코드입니다.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;241&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  Flux 패턴 : &lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;zustand는 Flux패턴 처럼 단방향이지만 구조는 더 단순하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 중앙 집중형 스토어에 저장하고 Action을 통해 데이터를 조작하는 패턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Flux 패턴&lt;/b&gt;은 React 생태계에서 많이 쓰이는 상태 관리 구조 중 하나로,&lt;br /&gt;애플리케이션의 상태(state)를 &lt;b&gt;단방향으로 흐르게 설계&lt;/b&gt;하는 아키텍처입니다.&lt;/p&gt;
&lt;p data-end=&quot;198&quot; data-start=&quot;172&quot; data-ke-size=&quot;size16&quot;&gt;기본 구조는 다음과 같이 이해하면 쉽습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;530&quot; data-start=&quot;200&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;283&quot; data-start=&quot;200&quot;&gt;&lt;b&gt;Action(액션)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;283&quot; data-start=&quot;223&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;247&quot; data-start=&quot;223&quot;&gt;상태를 변경하겠다는 의도를 담은 객체&lt;/li&gt;
&lt;li data-end=&quot;283&quot; data-start=&quot;251&quot;&gt;예: ADD_TODO, REMOVE_ITEM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;368&quot; data-start=&quot;285&quot;&gt;&lt;b&gt;Dispatcher(디스패처)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;368&quot; data-start=&quot;314&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;314&quot;&gt;Action을 받아서 &lt;b&gt;Store로 전달&lt;/b&gt;하는 역할&lt;/li&gt;
&lt;li data-end=&quot;368&quot; data-start=&quot;352&quot;&gt;중앙 허브 역할을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;444&quot; data-start=&quot;370&quot;&gt;&lt;b&gt;Store(스토어)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;444&quot; data-start=&quot;393&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;412&quot; data-start=&quot;393&quot;&gt;상태를 실제로 저장하고 관리&lt;/li&gt;
&lt;li data-end=&quot;444&quot; data-start=&quot;416&quot;&gt;상태가 바뀌면 View에 알려서 화면을 갱신&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;530&quot; data-start=&quot;446&quot;&gt;&lt;b&gt;View(뷰)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;530&quot; data-start=&quot;466&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;493&quot; data-start=&quot;466&quot;&gt;Store의 상태를 기반으로 UI를 렌더링&lt;/li&gt;
&lt;li data-end=&quot;530&quot; data-start=&quot;497&quot;&gt;사용자가 UI를 통해 Action을 발생시킬 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;즉, Flux는 &lt;b&gt;Action &amp;rarr; Dispatcher &amp;rarr; Store &amp;rarr; View&lt;/b&gt; 순으로&lt;br /&gt;데이터가 &lt;b&gt;한 방향&lt;/b&gt;으로만 흐르도록 설계되어 있어,&lt;br /&gt;상태 관리가 예측 가능하고 복잡한 상태 변화를 추적하기 쉬운 구조를 제공합니다.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;이건 WOOWACON에서 나온 내용인데, 이해하기 쉽게 나와있어서 가져와봤습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 2025. 8. 19. 오후 8.52.jpg&quot; data-origin-width=&quot;1414&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9ZCFN/btsQvMXQPA5/8JGvckILR4pD84Z0kp5vz1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9ZCFN/btsQvMXQPA5/8JGvckILR4pD84Z0kp5vz1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9ZCFN/btsQvMXQPA5/8JGvckILR4pD84Z0kp5vz1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9ZCFN%2FbtsQvMXQPA5%2F8JGvckILR4pD84Z0kp5vz1%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;1414&quot; height=&quot;702&quot; data-filename=&quot;이미지 2025. 8. 19. 오후 8.52.jpg&quot; data-origin-width=&quot;1414&quot; data-origin-height=&quot;702&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 &lt;b&gt;Zustand를 실제로 어떻게 사용하는지&lt;/b&gt; 보여드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 홈페이지에도 자세한 예시가 나와 있으니 참고하시면 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://zustand-demo.pmnd.rs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://zustand-demo.pmnd.rs/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757649108589&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Zustand&quot; data-og-description=&quot;&quot; data-og-host=&quot;zustand-demo.pmnd.rs&quot; data-og-source-url=&quot;https://zustand-demo.pmnd.rs/&quot; data-og-url=&quot;https://zustand-demo.pmnd.rs/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://zustand-demo.pmnd.rs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://zustand-demo.pmnd.rs/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Zustand&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;zustand-demo.pmnd.rs&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 여기서도 간단히 설명해드릴게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;62&quot; data-start=&quot;51&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ 설치 방법&lt;/h3&gt;
&lt;p data-end=&quot;122&quot; data-start=&quot;63&quot; data-ke-size=&quot;size16&quot;&gt;Zustand는 &lt;b&gt;NPM 패키지&lt;/b&gt;로 제공되기 때문에, 프로젝트에 바로 설치해서 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757649182736&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NPM
npm install zustand
# Or, use any package manager of your choice.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;89&quot; data-start=&quot;58&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣&amp;nbsp;먼저 스토어(Store)를 만들어주세요&lt;/h3&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;Zustand에서는 스토어가 훅(Hook)입니다.&lt;br /&gt;스토어 안에는 &lt;b&gt;원시값, 객체, 함수&lt;/b&gt; 등 원하는 무엇이든 넣을 수 있고,&lt;br /&gt;set 함수를 사용하면 상태를 쉽게 업데이트할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757649293925&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { create } from 'zustand'

const useStore = create((set) =&amp;gt; ({
  bears: 0,
  increasePopulation: () =&amp;gt; set((state) =&amp;gt; ({ bears: state.bears + 1 })),
  removeAllBears: () =&amp;gt; set({ bears: 0 }),
  updateBears: (newBears) =&amp;gt; set({ bears: newBears }),
}))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;516&quot; data-start=&quot;491&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ 컴포넌트에서 스토어 사용하기&lt;/h3&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;517&quot; data-ke-size=&quot;size16&quot;&gt;스토어 훅을 어디서든 사용할 수 있으며, &lt;b&gt;Provider를 따로 쓸 필요가 없습니다.&lt;/b&gt;&lt;br /&gt;스토어에서 상태를 선택(select)하면, 해당 상태가 변경될 때 컴포넌트가 자동으로 리렌더링 됩니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1757649325904&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function BearCounter() {
  const bears = useStore((state) =&amp;gt; state.bears)
  return &amp;lt;h1&amp;gt;{bears} bears around here...&amp;lt;/h1&amp;gt;
}

function Controls() {
  const increasePopulation = useStore((state) =&amp;gt; state.increasePopulation)
  return &amp;lt;button onClick={increasePopulation}&amp;gt;one up&amp;lt;/button&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;이렇게만 해도 상태 관리가 끝!  &lt;br /&gt;간단하게 상태를 읽고 수정할 수 있으면서, 컴포넌트 간 공유도 아주 쉽게 할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size23&quot;&gt;  비교: Zustand는 다른 상태관리 라이브러리와 어떻게 다른가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zustand는 React에서 사용할 수 있는 여러 상태관리 라이브러리 중 하나입니다.&lt;br /&gt;이번 글에서는 Redux, Valtio, Jotai, Recoil 등과 비교하며 &lt;b&gt;Zustand의 특징과 장단점&lt;/b&gt;을 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;286&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;각 라이브러리는 저마다 장점과 단점이 있으며, 중요한 차이점과 공통점을 중심으로 비교합니다.&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;90&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;310&quot; data-start=&quot;293&quot; data-ke-size=&quot;size20&quot;&gt;  Redux와 비교&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;545&quot; data-start=&quot;311&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;545&quot; data-start=&quot;311&quot;&gt;&lt;b&gt;상태 모델(State Model)&lt;/b&gt;&lt;br /&gt;개념적으로 Zustand와 Redux는 꽤 비슷합니다.&lt;br /&gt;둘 다 &lt;b&gt;불변(Immutable) 상태 모델&lt;/b&gt;을 기반으로 하고 있죠.&lt;br /&gt;하지만 큰 차이점이 있습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;545&quot; data-start=&quot;441&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;490&quot; data-start=&quot;441&quot;&gt;Redux는 앱 전체를 &lt;b&gt;Context Provider&lt;/b&gt;로 감싸야 하는 반면,&lt;/li&gt;
&lt;li data-end=&quot;545&quot; data-start=&quot;493&quot;&gt;Zustand는 이런 설정이 필요 없고, &lt;b&gt;스토어 훅을 바로 사용&lt;/b&gt;할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Zustand&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757649447809&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { create } from 'zustand'

type State = {
  count: number
}

type Actions = {
  increment: (qty: number) =&amp;gt; void
  decrement: (qty: number) =&amp;gt; void
}

const useCountStore = create&amp;lt;State &amp;amp; Actions&amp;gt;((set) =&amp;gt; ({
  count: 0,
  increment: (qty: number) =&amp;gt; set((state) =&amp;gt; ({ count: state.count + qty })),
  decrement: (qty: number) =&amp;gt; set((state) =&amp;gt; ({ count: state.count - qty })),
}))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;663&quot; data-start=&quot;617&quot;&gt;Zustand에서는 먼저 useCountStore라는 훅을 만들어 상태를 관리합니다.&lt;br /&gt;이 스토어 안에는 count라는 상태와, 상태를 변경할 수 있는 increment와 decrement 같은 액션이 들어 있습니다.&lt;br /&gt;상태를 업데이트할 때는 set 함수를 사용하면 되고, Redux처럼 별도의 리듀서나 미들웨어를 만들 필요 없이&lt;br /&gt;단 몇 줄만으로 상태와 액션을 정의할 수 있어서 코드가 훨씬 간결합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1757649459081&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { create } from 'zustand'

type State = {
  count: number
}

type Actions = {
  increment: (qty: number) =&amp;gt; void
  decrement: (qty: number) =&amp;gt; void
}

type Action = {
  type: keyof Actions
  qty: number
}

const countReducer = (state: State, action: Action) =&amp;gt; {
  switch (action.type) {
    case 'increment':
      return { count: state.count + action.qty }
    case 'decrement':
      return { count: state.count - action.qty }
    default:
      return state
  }
}

const useCountStore = create&amp;lt;State &amp;amp; Actions&amp;gt;((set) =&amp;gt; ({
  count: 0,
  dispatch: (action: Action) =&amp;gt; set((state) =&amp;gt; countReducer(state, action)),
}))&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Zustand에서는 필요하다면 Redux처럼 리듀서 패턴도 적용할 수 있습니다.&lt;br /&gt;이 경우, dispatch 함수를 통해 상태를 업데이트하며, 액션 타입과 상태를 변경하는 로직을 분리할 수 있죠.&lt;br /&gt;즉, 구조는 Redux와 비슷하지만, 여전히 Provider 없이 훅만으로 바로 사용할 수 있다는 점이 큰 장점입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Redux&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757649479767&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createStore } from 'redux'
import { useSelector, useDispatch } from 'react-redux'

type State = {
  count: number
}

type Action = {
  type: 'increment' | 'decrement'
  qty: number
}

const countReducer = (state: State, action: Action) =&amp;gt; {
  switch (action.type) {
    case 'increment':
      return { count: state.count + action.qty }
    case 'decrement':
      return { count: state.count - action.qty }
    default:
      return state
  }
}

const countStore = createStore(countReducer)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Redux는 상태 관리 구조가 &lt;b&gt;Store와 Reducer로 명확하게 나뉘어&lt;/b&gt; 있습니다.&lt;br /&gt;하지만 React에서 사용하려면 반드시 &amp;lt;Provider store={countStore}&amp;gt;로 앱 전체를 감싸야 합니다.&lt;br /&gt;상태를 변경하려면 항상 dispatch를 통해서만 가능하며,&lt;br /&gt;전체적으로 코드가 길고 반복되는 부분, 즉 &lt;b&gt;boilerplate 코드&lt;/b&gt;가 많다는 단점이 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1757649488847&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createSlice, configureStore } from '@reduxjs/toolkit'

const countSlice = createSlice({
  name: 'count',
  initialState: { value: 0 },
  reducers: {
    incremented: (state, qty: number) =&amp;gt; {
      // Redux Toolkit does not mutate the state, it uses the Immer library
      // behind scenes, allowing us to have something called &quot;draft state&quot;.
      state.value += qty
    },
    decremented: (state, qty: number) =&amp;gt; {
      state.value -= qty
    },
  },
})

const countStore = configureStore({ reducer: countSlice.reducer })&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Redux Toolkit은 Redux를 더 쉽게 사용할 수 있도록 만든 라이브러리입니다.&lt;br /&gt;내부적으로 &lt;b&gt;Immer 라이브러리&lt;/b&gt;를 사용하기 때문에, state.value += qty처럼 마치 상태를 직접 수정하는 것처럼 코드를 작성할 수 있습니다.&lt;br /&gt;덕분에 반복되는 코드가 줄어들고, 타입스크립트와도 자연스럽게 통합되어 &lt;b&gt;코드가 더 깔끔하고 가독성이 좋아집니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;105&quot; data-start=&quot;56&quot; data-ke-size=&quot;size20&quot;&gt;⚡ 렌더링 최적화(Render Optimization) &amp;ndash; Redux와 비교&lt;/h4&gt;
&lt;p data-end=&quot;266&quot; data-start=&quot;106&quot; data-ke-size=&quot;size16&quot;&gt;앱 내에서 &lt;b&gt;렌더링 최적화&lt;/b&gt;를 고려할 때, Zustand와 Redux 간의 접근 방식에는 큰 차이가 없습니다.&lt;br /&gt;두 라이브러리 모두 &lt;b&gt;선택자(Selector)를 활용해 필요한 상태만 선택&lt;/b&gt;하고,&lt;br /&gt;컴포넌트가 불필요하게 리렌더링되지 않도록 최적화를 적용하는 것이 권장됩니다.&lt;/p&gt;
&lt;p data-end=&quot;345&quot; data-start=&quot;268&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;345&quot; data-start=&quot;268&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;345&quot; data-start=&quot;268&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Zustand&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757649548123&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { create } from 'zustand'

type State = {
  count: number
}

type Actions = {
  increment: (qty: number) =&amp;gt; void
  decrement: (qty: number) =&amp;gt; void
}

const useCountStore = create&amp;lt;State &amp;amp; Actions&amp;gt;((set) =&amp;gt; ({
  count: 0,
  increment: (qty: number) =&amp;gt; set((state) =&amp;gt; ({ count: state.count + qty })),
  decrement: (qty: number) =&amp;gt; set((state) =&amp;gt; ({ count: state.count - qty })),
}))

const Component = () =&amp;gt; {
  const count = useCountStore((state) =&amp;gt; state.count)
  const increment = useCountStore((state) =&amp;gt; state.increment)
  const decrement = useCountStore((state) =&amp;gt; state.decrement)
  // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서는 useCountStore라는 Zustand 스토어를 만들어 &lt;b&gt;count 상태와 상태를 변경하는 함수들&lt;/b&gt;을 정의하고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;241&quot; data-start=&quot;142&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;170&quot; data-start=&quot;142&quot;&gt;count라는 상태를 0으로 초기화하고,&lt;/li&gt;
&lt;li data-end=&quot;241&quot; data-start=&quot;171&quot;&gt;increment와 decrement라는 액션을 만들어 set 함수를 사용해 상태를 업데이트하도록 했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;243&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트에서는 이 스토어 훅을 사용해 상태와 액션을 가져올 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;243&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const&amp;nbsp;count&amp;nbsp;=&amp;nbsp;useCountStore((state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.count)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;increment&amp;nbsp;=&amp;nbsp;useCountStore((state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.increment)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;decrement&amp;nbsp;=&amp;nbsp;useCountStore((state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.decrement)&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;243&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;285&quot; data-start=&quot;243&quot; data-ke-size=&quot;size16&quot;&gt;즉, 필요한 상태나 액션만 선택해서 사용할 수 있고, 상태가 바뀌면 자동으로 해당 컴포넌트가 리렌더링됩니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-end=&quot;657&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;이 방식의 장점은 &lt;b&gt;Provider가 필요 없고, Redux처럼 복잡한 설정 없이 훅 하나로 상태 관리가 가능&lt;/b&gt;하다는 점입니다.&lt;br /&gt;또한, &lt;b&gt;액션과 상태를 한 곳에서 정의할 수 있어 코드가 직관적이고 간결&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-end=&quot;657&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Redux&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757649563346&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createStore } from 'redux'
import { useSelector, useDispatch } from 'react-redux'

type State = {
  count: number
}

type Action = {
  type: 'increment' | 'decrement'
  qty: number
}

const countReducer = (state: State, action: Action) =&amp;gt; {
  switch (action.type) {
    case 'increment':
      return { count: state.count + action.qty }
    case 'decrement':
      return { count: state.count - action.qty }
    default:
      return state
  }
}

const countStore = createStore(countReducer)

const Component = () =&amp;gt; {
  const count = useSelector((state) =&amp;gt; state.count)
  const dispatch = useDispatch()
  // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 countReducer라는 &lt;b&gt;리듀서 함수&lt;/b&gt;를 정의합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;270&quot; data-start=&quot;135&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;158&quot; data-start=&quot;135&quot;&gt;상태 count를 가지고 있고,&lt;/li&gt;
&lt;li data-end=&quot;203&quot; data-start=&quot;159&quot;&gt;액션 타입이 'increment'일 경우 count를 증가시키고,&lt;/li&gt;
&lt;li data-end=&quot;242&quot; data-start=&quot;204&quot;&gt;'decrement'일 경우 count를 감소시킵니다.&lt;/li&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;243&quot;&gt;그 외의 액션은 그대로 상태를 반환합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const&amp;nbsp;countStore&amp;nbsp;=&amp;nbsp;createStore(countReducer)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 리듀서를 전달해 &lt;b&gt;스토어(Store)를 생성&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redux에서는 이 스토어를 앱 전체에 제공하기 위해 &amp;lt;Provider store={countStore}&amp;gt;로 감싸야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트에서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const&amp;nbsp;count&amp;nbsp;=&amp;nbsp;useSelector((state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.count)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;dispatch&amp;nbsp;=&amp;nbsp;useDispatch()&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;618&quot; data-start=&quot;545&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;575&quot; data-start=&quot;545&quot;&gt;useSelector를 사용해 상태를 읽고,&lt;/li&gt;
&lt;li data-end=&quot;618&quot; data-start=&quot;576&quot;&gt;useDispatch를 사용해 액션을 보내 상태를 업데이트합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;661&quot; data-start=&quot;620&quot; data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;Redux는 상태와 액션 관리가 명확하고 예측 가능&lt;/b&gt;하지만,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;741&quot; data-start=&quot;662&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;741&quot; data-start=&quot;662&quot;&gt;스토어와 Provider 설정, dispatch를 통한 상태 변경 등 &lt;b&gt;코드가 상대적으로 길고 구조가 복잡&lt;/b&gt;하다는 특징이 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1757649574211&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { useSelector } from 'react-redux'
import type { TypedUseSelectorHook } from 'react-redux'
import { createSlice, configureStore } from '@reduxjs/toolkit'

const countSlice = createSlice({
  name: 'count',
  initialState: { value: 0 },
  reducers: {
    incremented: (state, qty: number) =&amp;gt; {
      // Redux Toolkit does not mutate the state, it uses the Immer library
      // behind scenes, allowing us to have something called &quot;draft state&quot;.
      state.value += qty
    },
    decremented: (state, qty: number) =&amp;gt; {
      state.value -= qty
    },
  },
})

const countStore = configureStore({ reducer: countSlice.reducer })

const useAppSelector: TypedUseSelectorHook&amp;lt;typeof countStore.getState&amp;gt; =
  useSelector

const useAppDispatch: () =&amp;gt; typeof countStore.dispatch = useDispatch

const Component = () =&amp;gt; {
  const count = useAppSelector((state) =&amp;gt; state.count.value)
  const dispatch = useAppDispatch()
  // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 createSlice를 이용해 상태와 액션을 한 번에 정의합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;348&quot; data-start=&quot;146&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;182&quot; data-start=&quot;146&quot;&gt;countSlice 안에는 상태 value가 있고,&lt;/li&gt;
&lt;li data-end=&quot;232&quot; data-start=&quot;183&quot;&gt;incremented와 decremented라는 액션이 정의되어 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;233&quot;&gt;Redux Toolkit은 내부적으로 &lt;b&gt;Immer 라이브러리&lt;/b&gt;를 사용하기 때문에, state.value += qty처럼 마치 상태를 직접 변경하는 것처럼 작성해도 실제로는 불변성을 유지합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const&amp;nbsp;countStore&amp;nbsp;=&amp;nbsp;configureStore({&amp;nbsp;reducer:&amp;nbsp;countSlice.reducer&amp;nbsp;})&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 스토어를 설정하고, 앱 전체에서 사용할 수 있도록 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;480&quot; data-start=&quot;471&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트에서는&lt;/p&gt;
&lt;p data-end=&quot;480&quot; data-start=&quot;471&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const&amp;nbsp;count&amp;nbsp;=&amp;nbsp;useAppSelector((state)&amp;nbsp;=&amp;gt;&amp;nbsp;state.count.value)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;const&amp;nbsp;dispatch&amp;nbsp;=&amp;nbsp;useAppDispatch()&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;661&quot; data-start=&quot;584&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;616&quot; data-start=&quot;584&quot;&gt;useAppSelector를 통해 상태를 읽고,&lt;/li&gt;
&lt;li data-end=&quot;661&quot; data-start=&quot;617&quot;&gt;useAppDispatch로 액션을 디스패치해 상태를 업데이트합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;723&quot; data-start=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;즉, Redux Toolkit은 &lt;b&gt;기존 Redux보다 훨씬 간단하게 상태와 액션을 정의할 수 있고&lt;/b&gt;,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;777&quot; data-start=&quot;724&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;777&quot; data-start=&quot;724&quot;&gt;불변성을 직접 관리할 필요가 없어 코드를 더 깔끔하게 작성할 수 있다는 장점이 있습니다.&lt;/li&gt;
&lt;/ul&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-filename=&quot;스크린샷 2025-09-12 오후 1.08.41.png&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;1230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIYGdp/btsQvX6i8KL/wsEd6TsdgjgVmk9tS41Iw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIYGdp/btsQvX6i8KL/wsEd6TsdgjgVmk9tS41Iw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIYGdp/btsQvX6i8KL/wsEd6TsdgjgVmk9tS41Iw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIYGdp%2FbtsQvX6i8KL%2FwsEd6TsdgjgVmk9tS41Iw0%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;1598&quot; height=&quot;1230&quot; data-filename=&quot;스크린샷 2025-09-12 오후 1.08.41.png&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;1230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ &lt;b&gt;정리&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2131&quot; data-start=&quot;1958&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2001&quot; data-start=&quot;1958&quot;&gt;&lt;b&gt;Zustand&lt;/b&gt;: 간단하고 직관적, 소규모/중규모 프로젝트에 적합&lt;/li&gt;
&lt;li data-end=&quot;2064&quot; data-start=&quot;2002&quot;&gt;&lt;b&gt;Redux&lt;/b&gt;: 구조가 명확하고 예측 가능, 대규모 프로젝트에 유리하지만 boilerplate가 많음&lt;/li&gt;
&lt;li data-end=&quot;2131&quot; data-start=&quot;2065&quot;&gt;&lt;b&gt;Redux Toolkit&lt;/b&gt;: Redux의 장점은 유지하면서 코드를 간결하게, Immer로 상태 변경이 편리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 코드를 비교해 보자면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-12 오후 1.09.24.png&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qBm8R/btsQxq7IZw0/Sp7hMJuOocKxUHNAQyKtyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qBm8R/btsQxq7IZw0/Sp7hMJuOocKxUHNAQyKtyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qBm8R/btsQxq7IZw0/Sp7hMJuOocKxUHNAQyKtyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqBm8R%2FbtsQxq7IZw0%2FSp7hMJuOocKxUHNAQyKtyK%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;1570&quot; height=&quot;700&quot; data-filename=&quot;스크린샷 2025-09-12 오후 1.09.24.png&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;700&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-filename=&quot;스크린샷 2025-09-12 오후 1.09.52.png&quot; data-origin-width=&quot;1566&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CS3Bx/btsQtUW10B7/KwzVZCtPSUjQiACkXIRg21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CS3Bx/btsQtUW10B7/KwzVZCtPSUjQiACkXIRg21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CS3Bx/btsQtUW10B7/KwzVZCtPSUjQiACkXIRg21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCS3Bx%2FbtsQtUW10B7%2FKwzVZCtPSUjQiACkXIRg21%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;1566&quot; height=&quot;552&quot; data-filename=&quot;스크린샷 2025-09-12 오후 1.09.52.png&quot; data-origin-width=&quot;1566&quot; data-origin-height=&quot;552&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-filename=&quot;스크린샷 2025-09-12 오후 1.10.05.png&quot; data-origin-width=&quot;1568&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lAxW6/btsQwBPsAEc/bqMkiXGYromRKqlR1kkb51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lAxW6/btsQwBPsAEc/bqMkiXGYromRKqlR1kkb51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lAxW6/btsQwBPsAEc/bqMkiXGYromRKqlR1kkb51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlAxW6%2FbtsQwBPsAEc%2FbqMkiXGYromRKqlR1kkb51%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;1568&quot; height=&quot;648&quot; data-filename=&quot;스크린샷 2025-09-12 오후 1.10.05.png&quot; data-origin-width=&quot;1568&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚠️ 상태관리 라이브러리는 무조건 써야 할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;답변:&lt;/b&gt;&lt;br /&gt;무조건 사용할 필요는 없습니다. 상태관리 라이브러리는 프로젝트 &lt;b&gt;규모와 복잡도&lt;/b&gt;에 따라 선택하면 돼요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;195&quot; data-start=&quot;176&quot; data-ke-size=&quot;size23&quot;&gt;  라이브러리가 필요할 때&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;343&quot; data-start=&quot;196&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;232&quot; data-start=&quot;196&quot;&gt;  여러 컴포넌트에서 &lt;b&gt;같은 상태를 공유&lt;/b&gt;해야 할 때&lt;/li&gt;
&lt;li data-end=&quot;267&quot; data-start=&quot;233&quot;&gt;  상태 변화가 많고 &lt;b&gt;복잡한 로직&lt;/b&gt;이 포함될 때&lt;/li&gt;
&lt;li data-end=&quot;310&quot; data-start=&quot;268&quot;&gt;  Props Drilling이 많아져 &lt;b&gt;유지보수가 어려울 때&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;343&quot; data-start=&quot;311&quot;&gt;  상태를 &lt;b&gt;예측 가능하게 관리&lt;/b&gt;하고 싶을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;348&quot; data-start=&quot;345&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;370&quot; data-start=&quot;350&quot; data-ke-size=&quot;size23&quot;&gt;⚡ 라이브러리가 필요 없을 때&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;479&quot; data-start=&quot;371&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;419&quot; data-start=&quot;371&quot;&gt;  상태 공유가 거의 없고 &lt;b&gt;컴포넌트 내부 상태&lt;/b&gt;만 사용하는 작은 프로젝트&lt;/li&gt;
&lt;li data-end=&quot;479&quot; data-start=&quot;420&quot;&gt;  상태 변화가 단순해서 React의 useState나 useReducer만으로 충분할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;484&quot; data-start=&quot;481&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;494&quot; data-start=&quot;486&quot; data-ke-size=&quot;size23&quot;&gt;✅ 정리&lt;/h3&gt;
&lt;p data-end=&quot;593&quot; data-start=&quot;495&quot; data-ke-size=&quot;size16&quot;&gt;상태관리 라이브러리는 &lt;b&gt;규모가 크거나 상태가 복잡한 앱에서 유용&lt;/b&gt;하지만,&lt;br /&gt;작거나 단순한 프로젝트에서는 오히려 &lt;b&gt;불필요한 학습과 코드 복잡도&lt;/b&gt;를 늘릴 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;593&quot; data-start=&quot;495&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;121&quot; data-start=&quot;85&quot; data-ke-size=&quot;size23&quot;&gt;실전에서 상태관리 라이브러리, 언제 쓰고 안 쓰나?&lt;/h3&gt;
&lt;p data-end=&quot;141&quot; data-start=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1️⃣ 사용하면 좋은 경우&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;413&quot; data-start=&quot;142&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;224&quot; data-start=&quot;142&quot;&gt;앱 규모가 크고 여러 페이지나 컴포넌트에서 &lt;b&gt;같은 상태를 공유&lt;/b&gt;해야 할 때&lt;br /&gt;&amp;rarr; 예: 사용자 로그인 정보, 장바구니, 테마 설정 등&lt;/li&gt;
&lt;li data-end=&quot;294&quot; data-start=&quot;225&quot;&gt;상태 변화가 많거나 &lt;b&gt;복잡한 로직&lt;/b&gt;이 포함된 경우&lt;br /&gt;&amp;rarr; 예: 계산 로직, 필터/정렬 기능, 동시성 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;355&quot; data-start=&quot;295&quot;&gt;Props Drilling이 발생해 &lt;b&gt;상위에서 하위로 상태를 계속 내려야 하는 구조&lt;/b&gt;가 반복될 때&lt;/li&gt;
&lt;li data-end=&quot;413&quot; data-start=&quot;356&quot;&gt;상태를 &lt;b&gt;예측 가능하게 관리&lt;/b&gt;하고 싶을 때&lt;br /&gt;&amp;rarr; 팀 협업 시 버그 방지와 유지보수 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;415&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2️⃣ 사용하지 않아도 되는 경우&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;605&quot; data-start=&quot;438&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;514&quot; data-start=&quot;438&quot;&gt;상태 공유가 거의 없고 &lt;b&gt;컴포넌트 자체 상태&lt;/b&gt;만 사용하는 작은 프로젝트&lt;br /&gt;&amp;rarr; 예: 단순 토글 버튼, 입력 폼, 작은 위젯&lt;/li&gt;
&lt;li data-end=&quot;569&quot; data-start=&quot;515&quot;&gt;상태 변화가 단순해서 React의 useState나 useReducer로 충분할 때&lt;/li&gt;
&lt;li data-end=&quot;605&quot; data-start=&quot;570&quot;&gt;라이브러리를 도입할 만큼 &lt;b&gt;복잡도가 크지 않은 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 React 상태관리 라이브러리 중 &lt;b&gt;Zustand, Redux, Redux Toolkit&lt;/b&gt;을 비교하며 살펴봤습니다.&lt;br /&gt;각 라이브러리마다 장점과 단점이 명확하고, 사용 용도에 따라 적합한 선택이 달라집니다.&lt;br /&gt;작고 단순한 프로젝트에서는 굳이 라이브러리를 도입하지 않아도 충분히 상태를 관리할 수 있고,&lt;br /&gt;오히려 코드를 더 간결하게 유지할 수 있다는것을 알게되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;283&quot; data-ke-size=&quot;size16&quot;&gt;반대로 여러 컴포넌트가 상태를 공유하거나, 상태 변화가 복잡한 프로젝트에서는&lt;br /&gt;Zustand처럼 직관적인 라이브러리나 Redux/Redux Toolkit을 활용하면 코드 유지보수가 훨씬 편리해짐을 알게 되었습니다.&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;283&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;283&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Props Drilling을 피하고, 상태를 예측 가능하게 관리할 수 있다는 점도 큰 장점입니다.&lt;/p&gt;
&lt;p data-end=&quot;690&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;상태관리 라이브러리는 &lt;b&gt;도구일 뿐&lt;/b&gt;이며, 항상 프로젝트의 규모와 복잡도를 고려해서 선택하는 것이 중요합니다.&lt;br /&gt;처음에는 작은 프로젝트에서 React 내장 훅으로 시작해보고, 필요할 때 점차 라이브러리를 도입하는 전략도 좋습니다.&lt;/p&gt;
&lt;p data-end=&quot;690&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;690&quot; data-start=&quot;459&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;오늘 소개한 내용이 상태관리 선택에 조금이라도 도움이 되었기를 바라며,&lt;br /&gt;나중에는 실제 프로젝트에서 Zustand를 적용한 &lt;b&gt;실전 예제와 팁&lt;/b&gt;을 공유해보겠습니다!&lt;/p&gt;</description>
      <category>개발 로그/오늘의 개발읽기</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/88</guid>
      <comments>https://jjung2ing.tistory.com/88#entry88comment</comments>
      <pubDate>Fri, 12 Sep 2025 12:55:52 +0900</pubDate>
    </item>
    <item>
      <title>[전시 / 축제] 서울 5대 궁궐에서 만나는 2025 궁중문화축전 가이드</title>
      <link>https://jjung2ing.tistory.com/87</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.35.06.png&quot; data-origin-width=&quot;3004&quot; data-origin-height=&quot;1218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TUkr2/btsQuadf7zu/Z8UVdXPvb8jLkW50ysJwm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TUkr2/btsQuadf7zu/Z8UVdXPvb8jLkW50ysJwm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TUkr2/btsQuadf7zu/Z8UVdXPvb8jLkW50ysJwm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTUkr2%2FbtsQuadf7zu%2FZ8UVdXPvb8jLkW50ysJwm1%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;3004&quot; height=&quot;1218&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.35.06.png&quot; data-origin-width=&quot;3004&quot; data-origin-height=&quot;1218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘, 궁을 만나다&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;궁중문화축전&amp;rsquo;은 대한민국을 대표하는 문화유산이며 조선과 대한제국의 역사를 품고 있는 경복궁, 창덕궁, 창경궁, 덕수궁, 경희궁 등 서울 소재 5개의 궁궐과 종묘에서 펼쳐지는 문화유산 축제입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #393939; text-align: start;&quot;&gt;국가유산청이 주최하고 국가유산진흥원이 주관하는 궁중문화축전에서는 내&amp;middot;외국인에게 &amp;lsquo;오늘, 궁을 만나다&amp;rsquo;라는 취지에 어울리는 다양한 프로그램이 펼쳐집니다. 봄과 가을에 궁궐의 역사를 담고 있으면서 각각의 궁궐 전각과 장소의 특성을 반영한 공연, 전시, 체험, 의례 재현 등의 문화, 예술프로그램을 제공하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #393939; text-align: start;&quot;&gt;궁중문화축전은 궁을 사랑하는 많은 분들이 직접 축전의 주인공이 되고, 더 많은 분이 궁의 매력을 느낄 수 있도록 노력을 다하고 있습니다. 이와 함께 궁중문화축전은 한국을 방문한 외국인에게 품위 있고 흥미로운 역사, 문화 프로그램에 참여하는 기회를 제공함으로써 한국 문화유산과 한국의 문화 역량을 대외적으로 널리 알리는 특별한 장이 될 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;저도 작년부터 열심히 참여하고 있는데요. 무료 체험도 있고 유료 체험도 있지만, 어떤 프로그램을 선택해도 그 가격이 전혀 아깝지 않을 만큼 만족스러운 행사였어요.&lt;br /&gt;특별한 경험과 잊지 못할 추억을 만들고 싶으신 분들께 강력히 추천드려요!&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 프로그램이 있는지 미리 알아야 제대로 즐길 수 있겠죠?&lt;br /&gt;2025 궁중문화축전 공식 페이지에서 확인할 수 있지만, 조금 번거로우실 수 있으니 제가 바로 정리해드릴게요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20250904201928476_XF83BEXC.jpg&quot; data-origin-width=&quot;2916&quot; data-origin-height=&quot;3391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIu2K8/btsQtgL3wwA/n2TtIKcSX6rsdoNz92hB00/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIu2K8/btsQtgL3wwA/n2TtIKcSX6rsdoNz92hB00/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIu2K8/btsQtgL3wwA/n2TtIKcSX6rsdoNz92hB00/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIu2K8%2FbtsQtgL3wwA%2Fn2TtIKcSX6rsdoNz92hB00%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;2916&quot; height=&quot;3391&quot; data-filename=&quot;20250904201928476_XF83BEXC.jpg&quot; data-origin-width=&quot;2916&quot; data-origin-height=&quot;3391&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;홈페이지에서 보시려면 여기로 들어가시면 됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.kh.or.kr/cms/content/view/1532&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.kh.or.kr/cms/content/view/1532&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757565580975&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;궁중문화축전&quot; data-og-description=&quot;매년 봄과 가을 5대궁과 종묘&amp;middot;사직단에서 펼쳐지는 국내최대 문화유산축제&quot; data-og-host=&quot;www.kh.or.kr&quot; data-og-source-url=&quot;https://www.kh.or.kr/cms/content/view/1532&quot; data-og-url=&quot;https://www.kh.or.kr/fest&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rsEJs/hyZIPLclBe/JxyMrUx0jjbwfxAJCiKgKk/img.png?width=286&amp;amp;height=70&amp;amp;face=0_0_286_70,https://scrap.kakaocdn.net/dn/bvkzWW/hyZI1LE3Li/QcFLbx12KixXYD5PUkct11/img.png?width=2000&amp;amp;height=831&amp;amp;face=0_0_2000_831,https://scrap.kakaocdn.net/dn/p5PaY/hyZGZHR09P/43mGVEJ9iKOH4VIbuZ4rG1/img.png?width=1903&amp;amp;height=790&amp;amp;face=0_0_1903_790&quot;&gt;&lt;a href=&quot;https://www.kh.or.kr/cms/content/view/1532&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.kh.or.kr/cms/content/view/1532&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rsEJs/hyZIPLclBe/JxyMrUx0jjbwfxAJCiKgKk/img.png?width=286&amp;amp;height=70&amp;amp;face=0_0_286_70,https://scrap.kakaocdn.net/dn/bvkzWW/hyZI1LE3Li/QcFLbx12KixXYD5PUkct11/img.png?width=2000&amp;amp;height=831&amp;amp;face=0_0_2000_831,https://scrap.kakaocdn.net/dn/p5PaY/hyZGZHR09P/43mGVEJ9iKOH4VIbuZ4rG1/img.png?width=1903&amp;amp;height=790&amp;amp;face=0_0_1903_790');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;궁중문화축전&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;매년 봄과 가을 5대궁과 종묘&amp;middot;사직단에서 펼쳐지는 국내최대 문화유산축제&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kh.or.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;궁중문화축전을 즐기기 위해서는 티켓이 필요하겠죠?&lt;br /&gt;예약 방법도 간단하니 미리 준비하시면 더 편하게 즐길 수 있어요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;티켓 예매 사이트 : 티켓링크 (&lt;a href=&quot;https://www.ticketlink.co.kr/bridge/1378&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ticketlink.co.kr/bridge/1378&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;80&quot; data-start=&quot;50&quot; data-ke-size=&quot;size23&quot;&gt;2025년 가을 궁중문화축전 프로그램 예매 정보&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1255&quot; data-start=&quot;82&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;227&quot; data-start=&quot;82&quot;&gt;&lt;b&gt;궁중문화축전 특별 굿즈 &amp;lt;궁패스 노리개&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;227&quot; data-start=&quot;117&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;143&quot; data-start=&quot;117&quot;&gt;오픈일정: 2025.09.11 12:00&lt;/li&gt;
&lt;li data-end=&quot;173&quot; data-start=&quot;147&quot;&gt;예매마감: 2025.10.12 17:00&lt;/li&gt;
&lt;li data-end=&quot;203&quot; data-start=&quot;177&quot;&gt;취소마감: 2025.10.07 17:00&lt;/li&gt;
&lt;li data-end=&quot;227&quot; data-start=&quot;207&quot;&gt;구매수량: 1인 당 최대 4매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;354&quot; data-start=&quot;229&quot;&gt;&lt;b&gt;&amp;lt;경복궁 한복연향&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;354&quot; data-start=&quot;252&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;278&quot; data-start=&quot;252&quot;&gt;오픈일정: 2025.09.11 12:00&lt;/li&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;282&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;308&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;354&quot; data-start=&quot;334&quot;&gt;구매수량: 1인 당 최대 4매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;356&quot;&gt;&lt;b&gt;&amp;lt;덕수궁 인문학 콘서트&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;484&quot; data-start=&quot;382&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;408&quot; data-start=&quot;382&quot;&gt;오픈일정: 2025.09.11 14:00&lt;/li&gt;
&lt;li data-end=&quot;434&quot; data-start=&quot;412&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;460&quot; data-start=&quot;438&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;464&quot;&gt;구매수량: 1인 당 최대 4매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;612&quot; data-start=&quot;486&quot;&gt;&lt;b&gt;&amp;lt;아침 궁을 깨우다&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;612&quot; data-start=&quot;510&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;536&quot; data-start=&quot;510&quot;&gt;오픈일정: 2025.09.11 14:00&lt;/li&gt;
&lt;li data-end=&quot;562&quot; data-start=&quot;540&quot;&gt;예매마감: 관람일 전일 13:00&lt;/li&gt;
&lt;li data-end=&quot;588&quot; data-start=&quot;566&quot;&gt;취소마감: 관람일 전일 12:00&lt;/li&gt;
&lt;li data-end=&quot;612&quot; data-start=&quot;592&quot;&gt;구매수량: 1인 당 최대 2매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;741&quot; data-start=&quot;614&quot;&gt;&lt;b&gt;&amp;lt;준명당 어린이 학교&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;741&quot; data-start=&quot;639&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;665&quot; data-start=&quot;639&quot;&gt;오픈일정: 2025.09.11 14:00&lt;/li&gt;
&lt;li data-end=&quot;691&quot; data-start=&quot;669&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;717&quot; data-start=&quot;695&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;741&quot; data-start=&quot;721&quot;&gt;구매수량: 1인 당 최대 2매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;743&quot;&gt;&lt;b&gt;&amp;lt;동궐 장원서&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;866&quot; data-start=&quot;764&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;790&quot; data-start=&quot;764&quot;&gt;오픈일정: 2025.09.11 15:00&lt;/li&gt;
&lt;li data-end=&quot;816&quot; data-start=&quot;794&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;842&quot; data-start=&quot;820&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;846&quot;&gt;구매수량: 1인 당 최대 4매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;998&quot; data-start=&quot;868&quot;&gt;&lt;b&gt;&amp;lt;조선의 밤, 하늘과 바람&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;998&quot; data-start=&quot;896&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;922&quot; data-start=&quot;896&quot;&gt;오픈일정: 2025.09.11 15:00&lt;/li&gt;
&lt;li data-end=&quot;948&quot; data-start=&quot;926&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;974&quot; data-start=&quot;952&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;998&quot; data-start=&quot;978&quot;&gt;구매수량: 1인 당 최대 2매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1127&quot; data-start=&quot;1000&quot;&gt;&lt;b&gt;&amp;lt;종묘 인문학 콘서트&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1127&quot; data-start=&quot;1025&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1051&quot; data-start=&quot;1025&quot;&gt;오픈일정: 2025.09.11 16:00&lt;/li&gt;
&lt;li data-end=&quot;1077&quot; data-start=&quot;1055&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;1103&quot; data-start=&quot;1081&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;1127&quot; data-start=&quot;1107&quot;&gt;구매수량: 1인 당 최대 4매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1255&quot; data-start=&quot;1129&quot;&gt;&lt;b&gt;&amp;lt;종묘 건축 탐험대&amp;gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1255&quot; data-start=&quot;1153&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1179&quot; data-start=&quot;1153&quot;&gt;오픈일정: 2025.09.11 16:00&lt;/li&gt;
&lt;li data-end=&quot;1205&quot; data-start=&quot;1183&quot;&gt;예매마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;1231&quot; data-start=&quot;1209&quot;&gt;취소마감: 관람일 전일 17:00&lt;/li&gt;
&lt;li data-end=&quot;1255&quot; data-start=&quot;1235&quot;&gt;구매수량: 1인 당 최대 2매&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.41.57.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;1454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kEIH0/btsQtkgEEiI/Zmt7srxgHeDTLcB9hMYv30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kEIH0/btsQtkgEEiI/Zmt7srxgHeDTLcB9hMYv30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kEIH0/btsQtkgEEiI/Zmt7srxgHeDTLcB9hMYv30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkEIH0%2FbtsQtkgEEiI%2FZmt7srxgHeDTLcB9hMYv30%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;1704&quot; height=&quot;1454&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.41.57.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;1454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선선한 가을, 가족과 연인, 친구들과 함께 특별한 추억을 남기고 싶다면&lt;br /&gt;2025 궁중문화축전을 강력히 추천드려요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;다양한 궁중 체험과 전통 공연, 역사 투어까지&lt;br /&gt;모두가 즐겁게 참여할 수 있는 프로그램이 가득하답니다.&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;207&quot; data-start=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;255&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;저도 오늘 &lt;b&gt;궁패스 티켓팅&lt;/b&gt;에 도전해봤는데,&amp;nbsp; 생각보다 금방 매진되더라고요!&lt;/p&gt;
&lt;p data-end=&quot;255&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;255&quot; data-start=&quot;209&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;307&quot; data-start=&quot;257&quot; data-ke-size=&quot;size16&quot;&gt;모두들 서둘러 예매하시고, 원하는 프로그램 꼭 즐기시길 바라며&lt;br /&gt;&lt;b&gt;화이팅&lt;/b&gt;입니다!&lt;/p&gt;</description>
      <category>휴식 로그/공연 &amp;amp; 영화 &amp;amp; 드라마</category>
      <category>2025궁중문화축전</category>
      <category>경복궁</category>
      <category>궁중문화축전</category>
      <category>서울 축제</category>
      <category>서울놀거리</category>
      <category>서울아이들과</category>
      <category>창경궁</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/87</guid>
      <comments>https://jjung2ing.tistory.com/87#entry87comment</comments>
      <pubDate>Thu, 11 Sep 2025 13:48:25 +0900</pubDate>
    </item>
    <item>
      <title>[여행 로그] 평화누리 캠핑장 이용 후기와 예약 방법 총정리 2편</title>
      <link>https://jjung2ing.tistory.com/86</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2076&quot; data-origin-height=&quot;1326&quot;&gt;&lt;span data-url=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot; data-phocus=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot;&gt;&lt;img src=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=%2F%2Ft1.daumcdn.net%2Ftistory_admin%2Fstatic%2Fimages%2Fno-image-v1.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;2076&quot; height=&quot;1326&quot; data-origin-width=&quot;2076&quot; data-origin-height=&quot;1326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번 포스팅에서는 평화누리 캠핑장의 예약 방법과 기본적인 정보를 알려드렸었죠!  ️&lt;br /&gt;이번에는 드디어 실제로 다녀온 &lt;b&gt;생생한 캠핑장 이용 후기&lt;/b&gt;를 전해드리려고 합니다. ✨&lt;br /&gt;예약만으로는 알 수 없었던 현장 분위기, 시설 이용 팁, 그리고 제가 직접 겪은 에피소드까지 담아왔어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특히 초보 캠퍼분들이 가장 궁금해하실 부분들을 중심으로 솔직하게 작성해봤습니다.  &lt;br /&gt;그럼 지금부터 제가 다녀온 평화누리 캠핑장의 하루를 함께 보실까요?  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  &lt;b&gt;캠핑장 입구 &amp;amp; 체크인&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캠핑장 입구에 들어서면 가장 먼저 차단기가 보입니다. 미리 차량 정보를 입력해두셨다면 자동으로 열리지만, 혹시 열리지 않더라도 당황하지 마세요! 좌측 차단기에 있는 &lt;b&gt;호출 버튼  &lt;/b&gt;을 눌러 &amp;ldquo;캠핑장 예약자입니다&amp;rdquo;라고 말씀하시면 바로 열어주십니다.&lt;br /&gt;차단기가 열리면 그 앞에 차를 잠시 세우고 좌측에 있는 **웰컴센터(관리동)**로 가셔서 예약 내역과 신분증을 보여주시면 체크인이 완료됩니다. 저희는 카키색 박스를 받았는데, 그 안에는 &lt;b&gt;TV 리모콘, 에어컨 리모콘, 드라이기, 카라반 안내서&lt;/b&gt;가 들어있었어요. 특히 안내서에는 &lt;b&gt;외부 화장실 비밀번호와 카라반 비밀번호&lt;/b&gt;가 적혀 있으니 절대 잃어버리시면 안 됩니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진에서 보이는 곳은 바로 &lt;b&gt;텐트존⛺&amp;nbsp;&lt;/b&gt;이에요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 이곳에서 1박을 즐기시는 분들도 꽤 많더라구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불빛 아래서 텐트가 줄지어 있는 모습이 캠핑 분위기를 한층 더 살려주는 것 같았습니다.  ✨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;카라반도 좋지만, 다음에는 꼭 이 텐트존에서 하루 묵어보면서 또 다른 매력을 느껴보고 싶어요.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.14.38.png&quot; data-origin-width=&quot;2072&quot; data-origin-height=&quot;1460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw3Fu8/btsQuioIiaT/6h13kb2EdAVAwd7ZkduGH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw3Fu8/btsQuioIiaT/6h13kb2EdAVAwd7ZkduGH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw3Fu8/btsQuioIiaT/6h13kb2EdAVAwd7ZkduGH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw3Fu8%2FbtsQuioIiaT%2F6h13kb2EdAVAwd7ZkduGH0%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;2072&quot; height=&quot;1460&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.14.38.png&quot; data-origin-width=&quot;2072&quot; data-origin-height=&quot;1460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size20&quot;&gt; ️ &lt;b&gt;Z존 카라반 입장&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;저희는 &lt;b&gt;Z존&lt;/b&gt;을 예약했는데요, 진입은 웰컴센터 바로 우측 길로만 가능합니다.   직진하시면 안 돼요!&lt;br /&gt;짐을 옮기고 난 뒤에는 차량을 반드시 캠핑존 외부 주차장에 주차하셔야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;카라반 문은 &lt;b&gt;키패드 방식  &lt;/b&gt;이라 비밀번호 입력 후 &amp;ldquo;열림(자물쇠 열림)&amp;rdquo; 버튼을 누르면 지잉~ 소리가 나면서 열려요.&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;처음엔 조금 헷갈려서 고생했지만, 익숙해지면 괜찮습니다. (괜찮다고 했지만 버벅거리다 웰컴센터가서 다시 배워온 1인)&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;문을 잠그고 싶으실 때는 &amp;ldquo;잠김&amp;rdquo; 버튼이나 내부의 &lt;b&gt;주황색 고리  &lt;/b&gt;를 이용하면 안전하게 닫을 수 있어요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.17.06.png&quot; data-origin-width=&quot;2070&quot; data-origin-height=&quot;1398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beiGnr/btsQu5P6B60/3XaJJFKsal79OdjqWiQlok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beiGnr/btsQu5P6B60/3XaJJFKsal79OdjqWiQlok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beiGnr/btsQu5P6B60/3XaJJFKsal79OdjqWiQlok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeiGnr%2FbtsQu5P6B60%2F3XaJJFKsal79OdjqWiQlok%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;2070&quot; height=&quot;1398&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.17.06.png&quot; data-origin-width=&quot;2070&quot; data-origin-height=&quot;1398&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-end=&quot;776&quot; data-start=&quot;480&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;837&quot; data-start=&quot;778&quot; data-ke-size=&quot;size20&quot;&gt; ️ &lt;b&gt;카라반 내부 소개&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;837&quot; data-start=&quot;778&quot; data-ke-size=&quot;size16&quot;&gt;카라반 안은 생각보다 넓어서 4명이 사용해도 전혀 좁지 않았습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;999&quot; data-start=&quot;838&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;877&quot; data-start=&quot;838&quot;&gt;오른쪽: &lt;b&gt;2인용 침대  ️, TV  , 화장대, 옷장&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;934&quot; data-start=&quot;878&quot;&gt;중앙: &lt;b&gt;4인용 테이블, 인덕션  , 싱크대, 냉장고, 밥솥, 전자레인지, 커피포트 ☕&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;935&quot;&gt;왼쪽: &lt;b&gt;2층 침대  &lt;/b&gt;화장실도 깔끔하고 크기가 넉넉해서 샤워하기에 불편함이 전혀 없었어요.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 안의 2인용 침대는 성인 두 명이 함께 자기엔 약간 차렷 자세(?)로 바르게 누워야 하는 크기였습니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 답답할 정도는 아니었고, 오히려 아늑한 느낌이 들었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;저는 개인적으로 &lt;b&gt;너무 푹 꺼지는 매트리스보다는 단단한 매트리스&lt;/b&gt;를 좋아하는 편인데, 이곳 침대는 푹신하지 않고 적당히 단단해서 제 취향에 딱 맞았습니다.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.18.26.png&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;1516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmiA40/btsQsPulUog/2woYPKKi6y1CleK1bqNoQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmiA40/btsQsPulUog/2woYPKKi6y1CleK1bqNoQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmiA40/btsQsPulUog/2woYPKKi6y1CleK1bqNoQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmiA40%2FbtsQsPulUog%2F2woYPKKi6y1CleK1bqNoQ1%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;2056&quot; height=&quot;1516&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.18.26.png&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;1516&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 안에 있는 TV는 채널도 꽤 다양해서 볼 거리가 많았습니다.&lt;br /&gt;특히 &lt;b&gt;각도를 자유롭게 돌릴 수 있는 구조&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-filename=&quot;스크린샷 2025-09-11 오후 1.18.57.png&quot; data-origin-width=&quot;2076&quot; data-origin-height=&quot;1504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UR4Cz/btsQsQGMuaN/k2TdV68axkK3b32fFH7wi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UR4Cz/btsQsQGMuaN/k2TdV68axkK3b32fFH7wi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UR4Cz/btsQsQGMuaN/k2TdV68axkK3b32fFH7wi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUR4Cz%2FbtsQsQGMuaN%2Fk2TdV68axkK3b32fFH7wi0%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;2076&quot; height=&quot;1504&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.18.57.png&quot; data-origin-width=&quot;2076&quot; data-origin-height=&quot;1504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 안에는 낭만 가득한 &lt;b&gt;2층 침대&lt;/b&gt;도 마련되어 있었는데요, 아늑하고 포근한 분위기라 아이들이 특히 좋아할 것 같았어요. ✨&lt;br /&gt;제가 앉아 있을 때는 허리나 목을 구부리지 않아도 될 정도의 높이라 편안했습니다.  &lt;/p&gt;
&lt;p 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;2052&quot; data-origin-height=&quot;1556&quot;&gt;&lt;span data-url=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot; data-phocus=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot;&gt;&lt;img src=&quot;//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=%2F%2Ft1.daumcdn.net%2Ftistory_admin%2Fstatic%2Fimages%2Fno-image-v1.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;2052&quot; height=&quot;1556&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;1556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&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;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;카라반 내 &lt;b&gt;수건은 보관함 안에 구비&lt;/b&gt;되어 있어 따로 챙기지 않아도 됩니다. ✅&lt;br /&gt;다만 &lt;b&gt;샴푸, 바디워시 등 세면 용품은 제공되지 않으니&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-filename=&quot;스크린샷 2025-09-11 오후 1.19.37.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;1488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNm1Io/btsQtZv9G0k/QUA6TO56FqVJq3c67DtA61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNm1Io/btsQtZv9G0k/QUA6TO56FqVJq3c67DtA61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNm1Io/btsQtZv9G0k/QUA6TO56FqVJq3c67DtA61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNm1Io%2FbtsQtZv9G0k%2FQUA6TO56FqVJq3c67DtA61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1146&quot; height=&quot;1488&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.19.37.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;1488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 내부에 다른 기구들도 많이 있어서 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커피포트 밥솥 전자렌지 냉장고 등이 있어 밥 해먹기도 편리했어요카라반 안에는 생활에 필요한 기구들이 알차게 갖춰져 있어서 정말 편리했습니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;커피포트 ☕, 밥솥  , 전자레인지, 냉장고 ❄️&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-filename=&quot;스크린샷 2025-09-11 오후 1.24.13.png&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;984&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HRNj4/btsQu4KsKPQ/gRckUQkEop0kYa2K1xNVh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HRNj4/btsQu4KsKPQ/gRckUQkEop0kYa2K1xNVh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HRNj4/btsQu4KsKPQ/gRckUQkEop0kYa2K1xNVh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHRNj4%2FbtsQu4KsKPQ%2FgRckUQkEop0kYa2K1xNVh0%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;1156&quot; height=&quot;984&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.24.13.png&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;984&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 내부를 둘러보니 군데군데 &lt;b&gt;콘센트가 곳곳에 배치&lt;/b&gt;되어 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;덕분에 휴대폰이나 노트북을 충전하기에도 편리했고  ,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전자제품을 사용할 때도 자리를 옮기지 않고 바로 연결할 수 있어 아주 유용했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;사소한 부분 같지만, 이런 디테일 덕분에 캠핑이 훨씬 더 쾌적하게 느껴졌습니다. ✨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.26.13.png&quot; data-origin-width=&quot;2046&quot; data-origin-height=&quot;1476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eaiFKF/btsQu4RflTL/VX6Oy3ukieKm5EeNe8EKWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eaiFKF/btsQu4RflTL/VX6Oy3ukieKm5EeNe8EKWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eaiFKF/btsQu4RflTL/VX6Oy3ukieKm5EeNe8EKWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeaiFKF%2FbtsQu4RflTL%2FVX6Oy3ukieKm5EeNe8EKWK%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;2046&quot; height=&quot;1476&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.26.13.png&quot; data-origin-width=&quot;2046&quot; data-origin-height=&quot;1476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카라반 안에는 &lt;b&gt;에어컨&lt;/b&gt;이 완비되어 있어, 더운 여름이나 추운 겨울에도 쾌적하게 캠핑을 즐길 수 있었습니다.  ️&lt;br /&gt;또한, 테이블에 비치된 &lt;b&gt;태블릿  &lt;/b&gt;을 통해 필요한 도구를 요청하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정해진 시간에 맞춰 &lt;b&gt;카라반까지 직접 가져다주는 서비스&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-filename=&quot;스크린샷 2025-09-11 오후 1.26.39.png&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;1510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mohAY/btsQsTjc8mw/zbkP3ropxgsXdGeEXJHn8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mohAY/btsQsTjc8mw/zbkP3ropxgsXdGeEXJHn8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mohAY/btsQsTjc8mw/zbkP3ropxgsXdGeEXJHn8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmohAY%2FbtsQsTjc8mw%2FzbkP3ropxgsXdGeEXJHn8K%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;2050&quot; height=&quot;1510&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.26.39.png&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;1510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.29.17.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;1538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7hbly/btsQsicv6oM/ecjqc2axHIPV0FugfIkTF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7hbly/btsQsicv6oM/ecjqc2axHIPV0FugfIkTF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7hbly/btsQsicv6oM/ecjqc2axHIPV0FugfIkTF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7hbly%2FbtsQsicv6oM%2Fecjqc2axHIPV0FugfIkTF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1146&quot; height=&quot;1538&quot; data-filename=&quot;스크린샷 2025-09-11 오후 1.29.17.png&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;1538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size20&quot;&gt;  &lt;b&gt;특별했던 포인트&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;카라반 출입문에는 &lt;b&gt;방충망 전용 문&lt;/b&gt;이 설치되어 있어요. 문을 열고 방충망만 닫아두면 바깥 풍경이 시원하게 들어와 개방감이 아주 좋았습니다. 저희는 &lt;b&gt;Z15번&lt;/b&gt; 카라반을 이용했는데, 문 옆이 확 트여 있어서 전망도 좋고 웰컴센터와도 가까워서 정말 만족스러웠어요. &amp;ldquo;다음에 다시 오게 된다면 꼭 Z15로 예약해야겠다!&amp;rdquo;라는 생각이 들 정도였습니다.  &lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size20&quot;&gt;  &lt;b&gt;카라반 옆 타프존&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;카라반 옆에는 마치 타프존처럼 천막 ⛺이 설치되어 있어서 그 안에서 고기를 구워 먹기 딱 좋았습니다.&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&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;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1221&quot; data-start=&quot;1001&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size20&quot;&gt;  &lt;b&gt;여름철 물놀이&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;또 여름 시즌라서 카라반 옆에 &lt;b&gt;간이 수영장  &lt;/b&gt;도 설치되어있더라구요. 추가 비용을 내면 아이들이 마음껏 물놀이를 즐길 수 있어서, 가족 단위 캠퍼분들에게는 정말 좋은 선택지가 될 것 같았습니다. 아이들이 신나게 노는 동안 어른들은 옆 타프존에서 여유롭게 바비큐 파티~ 상상만 해도 너무 즐겁지 않나요?  &lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;전체적으로 캠핑장과 카라반 시설이 정말 잘 갖춰져 있어서 만족도가 높았습니다. ✨&lt;br /&gt;초보 캠퍼인 저희도 큰 걱정 없이 편안하게 캠핑을 즐길 수 있었어요.  ️&lt;br /&gt;카라반 내부도 넓고 아늑해서 4명이서 사용해도 불편함이 없었고,&lt;br /&gt;부대시설과 편의시설 덕분에 준비물 없이 가볍게 와도 충분히 즐길 수 있었습니다.  ️&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특히 에어컨과 다양한 주방 기구, 태블릿 주문 서비스 덕분에 실내에서도 편안하게 시간을 보낼 수 있었어요. ❄️ &lt;br /&gt;타프존과 주변 풍경도 좋아서 바비큐 파티 분위기가 최고였습니다.  &lt;br /&gt;저녁에는 조용하고 평화로운 분위기 덕분에 잘 쉬었고,&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;457&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;다음 날 아침에는 상쾌한 공기를 마시며 캠핑장 주변을 산책했는데 정말 힐링 그 자체였습니다.  &lt;br /&gt;햇살과 바람, 자연의 소리를 느끼면서 걷다 보니 마음까지 가벼워지는 기분이었어요. ☀️ &lt;br /&gt;이번 캠핑은 기대 이상으로 즐거웠고, 다음에도 꼭 다시 방문하고 싶은 캠핑장으로 기억될 것 같습니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>휴식 로그/여행 &amp;amp; Play</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/86</guid>
      <comments>https://jjung2ing.tistory.com/86#entry86comment</comments>
      <pubDate>Thu, 11 Sep 2025 13:31:33 +0900</pubDate>
    </item>
    <item>
      <title>[여행 로그] 평화누리 캠핑장 이용 후기와 예약 방법 총정리 1편</title>
      <link>https://jjung2ing.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025.09.07&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9월 초, 아침저녁으로 선선한 바람이 불어 캠핑하기 딱 좋은 계절이에요.&lt;br /&gt;주말마다 답답한 도심을 벗어나 자연 속에서 힐링하고 싶다는 생각이 점점 커지더라고요.&lt;br /&gt;사실 저는 캠핑 초보라서 지난번에는 오토캠핑장을 예약했는데,&lt;br /&gt;텐트 설치부터 장비 챙기기까지 혼자 하려니 생각보다 너무 힘들었어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그래서 이번에는 조금 편하게 캠핑을 즐기고 싶어서 카라반을 예약했습니다.&lt;br /&gt;평화누리 캠핑장은 넓은 잔디와 잘 정비된 시설 덕분에 초보자도 부담 없이 즐길 수 있다고 하더라고요.&lt;br /&gt;특히 9월의 선선한 날씨 덕분에 캠핑장 주변 산책도, 바람 맞으며 쉬는 것도 정말 상쾌했어요.&lt;br /&gt;카라반 안은 깔끔하게 준비되어 있어서 짐만 들고 와도 바로 캠핑을 시작할 수 있었습니다.&lt;br /&gt;이번 글에서는 캠핑 초보인 제가 경험한 평화누리 캠핑장 카라반 이용 후기와 꿀팁을 자세히 공유하려고 합니다.&lt;br /&gt;편안하고 즐거운 캠핑을 계획 중이라면, 이 글이 도움이 될 거예요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;  위치 &amp;amp; 오시는길&lt;/h2&gt;
&lt;p data-end=&quot;114&quot; data-start=&quot;103&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; &lt;/b&gt; 주소&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;208&quot; data-start=&quot;115&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;150&quot; data-start=&quot;115&quot;&gt;&lt;b&gt;도로명:&lt;/b&gt; 경기 파주시 문산읍 임진각로 148-40&lt;/li&gt;
&lt;li data-end=&quot;172&quot; data-start=&quot;151&quot;&gt;&lt;b&gt;지번:&lt;/b&gt; 마정리 613-1&lt;/li&gt;
&lt;li data-end=&quot;208&quot; data-start=&quot;173&quot;&gt;&lt;b&gt;네비게이션:&lt;/b&gt; 임진각평화누리캠핑장 / 평화누리캠핑장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;233&quot; data-start=&quot;215&quot; data-ke-size=&quot;size18&quot;&gt;  자가용 이용 안내&lt;/p&gt;
&lt;p data-end=&quot;233&quot; data-start=&quot;215&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;257&quot; data-start=&quot;235&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서울문산고속도로(17번) 이용&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;335&quot; data-start=&quot;258&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;335&quot; data-start=&quot;258&quot;&gt;자유로 &amp;rarr; 남고양 IC 또는 북로 JC &amp;rarr; 서울문산고속도로(17번) &amp;rarr; 내포 IC &amp;rarr; 자유로 이용 &amp;rarr; 마정JC에서 판문점 방면 진출&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;337&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;409&quot; data-start=&quot;350&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;409&quot; data-start=&quot;350&quot;&gt;자유로 &amp;rarr; 마정 JC에서 판문점 방면 진출 &amp;rarr; 도로 차단점에서 유턴 후 우측으로 캠핑장 주차장 진입&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;423&quot; data-start=&quot;411&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;472&quot; data-start=&quot;424&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;472&quot; data-start=&quot;424&quot;&gt;1번 국도 통일로 &amp;rarr; 판문점행 도로 차단점 도착 &amp;rarr; 유턴 후 캠핑장 주차장 진입&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;498&quot; data-start=&quot;479&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;498&quot; data-start=&quot;479&quot; data-ke-size=&quot;size18&quot;&gt;  대중교통 이용 안내&lt;/p&gt;
&lt;p data-end=&quot;498&quot; data-start=&quot;479&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;512&quot; data-start=&quot;500&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;642&quot; data-start=&quot;513&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;642&quot; data-start=&quot;513&quot;&gt;서울역 &amp;rarr; 신촌 &amp;rarr; 가좌 &amp;rarr; 디지털미디어시티 &amp;rarr; 수색 &amp;rarr; 한국항공대 &amp;rarr; 강매 &amp;rarr; 행신 &amp;rarr; 능곡 &amp;rarr; 대곡 &amp;rarr; 곡산 &amp;rarr; 백마 &amp;rarr; 풍산 &amp;rarr; 일산 &amp;rarr; 탄현 &amp;rarr; 야당 &amp;rarr; 운정 &amp;rarr; 금릉 &amp;rarr; 금촌 &amp;rarr; 월롱 &amp;rarr; 파주 &amp;rarr; &lt;b&gt;문산역 하차&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;661&quot; data-start=&quot;644&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;790&quot; data-start=&quot;662&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;717&quot; data-start=&quot;662&quot;&gt;문산역 하차 후 플랫폼 이동 &amp;rarr; &lt;b&gt;문산 &amp;harr; 임진강행 전철&lt;/b&gt; 탑승 &amp;rarr; &lt;b&gt;임진강역 하차&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;790&quot; data-start=&quot;718&quot;&gt;또는 문산역 1번 출구 &amp;rarr; [한진1차.문산역] 정류장(30336) 도보 이동 &amp;rarr; &lt;b&gt;058번 버스 탑승&lt;/b&gt; &amp;rarr; 임진각 하차&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;819&quot; data-start=&quot;792&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;경의선 운행 시간표 (문산 &amp;harr; 임진강)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;957&quot; data-start=&quot;820&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;879&quot; data-start=&quot;820&quot;&gt;주중: 문산역 &amp;rarr; 임진강역 10:30 / 17:05 | 임진강역 &amp;rarr; 문산역 10:50 / 17:25&lt;/li&gt;
&lt;li data-end=&quot;957&quot; data-start=&quot;880&quot;&gt;토요일&amp;middot;공휴일: 문산역 &amp;rarr; 임진강역 09:35 / 10:35 / 15:45 / 10:00 / 12:40 / 16:10 / 17:45&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;973&quot; data-start=&quot;959&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;1177&quot; data-start=&quot;974&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1094&quot; data-start=&quot;974&quot;&gt;&lt;b&gt;9710번 (평일 + 주말)&lt;/b&gt;: 광화문 &amp;rarr; 숭례문 &amp;rarr; 독립문역 &amp;rarr; 연신내역 &amp;rarr; 삼송역사거리 &amp;rarr; 관산동&amp;middot;벽제시장 &amp;rarr; 파주삼릉 &amp;rarr; 월롱역 &amp;rarr; 한진1차.문산역 &amp;rarr; &lt;b&gt;058번 마을버스 환승 &amp;rarr; 임진각 하차&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1177&quot; data-start=&quot;1095&quot;&gt;&lt;b&gt;7300번 (주말만)&lt;/b&gt;: 홍대입구역 &amp;rarr; 합정역 &amp;rarr; 헤이리예술마을 &amp;rarr; 동화경모공원 &amp;rarr; 체인지업캠퍼스(파주영어마을) &amp;rarr; &lt;b&gt;임진각 하차&lt;/b&gt;&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;1098&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eyeYwC/btsQp0oGBKe/8z6cFUoIxiklq30YZzkhOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eyeYwC/btsQp0oGBKe/8z6cFUoIxiklq30YZzkhOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eyeYwC/btsQp0oGBKe/8z6cFUoIxiklq30YZzkhOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeyeYwC%2FbtsQp0oGBKe%2F8z6cFUoIxiklq30YZzkhOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1098&quot; height=&quot;348&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; &amp;nbsp; 평화누리 캠핑장 예약 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ggtour.or.kr/camping/00000/00005.web&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ggtour.or.kr/camping/00000/00005.web&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1757464779358&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;예약안내 | 평화누리캠핑장&quot; data-og-description=&quot;예약방식 응모기간 전체 및 결과발표일이 휴일(공휴일)인 경우 그 다음 평일로 일정이 변경될 수 있으며, 매월 예약일정은 공지사항에서 확인하실 수 있습니다. 관광취약계층 우선추첨은 관광&quot; data-og-host=&quot;ggtour.or.kr&quot; data-og-source-url=&quot;https://ggtour.or.kr/camping/00000/00005.web&quot; data-og-url=&quot;https://ggtour.or.kr/camping/00000/00005.web&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bqRrbV/hyZIXhNQH4/qynAzE1TKfyD6bOzPGAidK/img.jpg?width=1920&amp;amp;height=270&amp;amp;face=0_0_1920_270&quot;&gt;&lt;a href=&quot;https://ggtour.or.kr/camping/00000/00005.web&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ggtour.or.kr/camping/00000/00005.web&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bqRrbV/hyZIXhNQH4/qynAzE1TKfyD6bOzPGAidK/img.jpg?width=1920&amp;amp;height=270&amp;amp;face=0_0_1920_270');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;예약안내 | 평화누리캠핑장&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예약방식 응모기간 전체 및 결과발표일이 휴일(공휴일)인 경우 그 다음 평일로 일정이 변경될 수 있으며, 매월 예약일정은 공지사항에서 확인하실 수 있습니다. 관광취약계층 우선추첨은 관광&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ggtour.or.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;홈페이지에 들어가시면 오른쪽 하단에 있는 &lt;b&gt;캠핑장 예약하기&lt;/b&gt; 버튼을 눌러주시면 됩니다!&lt;br /&gt;평화누리 캠핑장은 &lt;b&gt;우선 추첨제&lt;/b&gt;로 예약이 진행되고, 이후 &lt;b&gt;잔여석은 선착순&lt;/b&gt;으로 예약할 수 있어요. ⏳&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;저는 운 좋게 &lt;b&gt;잔여석으로 예약&lt;/b&gt;해서 다녀왔답니다.  &lt;br /&gt;잔여석 예약은 **전월 11일 오후 2시(14시)**에 열리니, 그 시간에 맞춰 미리 대기하면 예약 성공 확률이 높아요!  ️&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-filename=&quot;스크린샷 2025-09-10 오전 9.40.47.png&quot; data-origin-width=&quot;2928&quot; data-origin-height=&quot;1444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSzlV4/btsQrIuJtuS/LYWTRfVynbYv1JXUYkRMOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSzlV4/btsQrIuJtuS/LYWTRfVynbYv1JXUYkRMOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSzlV4/btsQrIuJtuS/LYWTRfVynbYv1JXUYkRMOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSzlV4%2FbtsQrIuJtuS%2FLYWTRfVynbYv1JXUYkRMOk%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;2928&quot; height=&quot;1444&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.40.47.png&quot; data-origin-width=&quot;2928&quot; data-origin-height=&quot;1444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  예약 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 &lt;b&gt;회원가입 후 로그인&lt;/b&gt;은 필수예요!  &amp;zwj;♀️ &amp;zwj;♂️&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;1️⃣ 화면 &lt;b&gt;우측에 있는 &quot;캠핑장 예약하기&quot; 버튼&lt;/b&gt;을 클릭하면 예약 페이지가 열립니다.  ️&lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;예약 페이지 &lt;b&gt;우측 상단&lt;/b&gt;에는 &lt;b&gt;로그아웃 &amp;middot; 개인정보 관리 &amp;middot; 예약 확인 및 취소 버튼&lt;/b&gt;이 있어요.  &lt;br /&gt;나중에 예약을 확인하거나 취소하려면 반드시 이 페이지에서만 가능하답니다.  &lt;br /&gt;  저도 처음에는 어디서 취소해야 하는지 몰라서 한참 헤맸었어요.  &lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;원하는 타입을 선택할 때, &lt;b&gt;이름 앞에 색깔 동그라미( )&lt;/b&gt; 안에 표시된 숫자가 바로 &lt;b&gt;잔여 자리 수&lt;/b&gt;예요.&lt;br /&gt;저도 처음엔 이게 뭔지 몰라서 잠깐 헷갈렸는데, 알고 나니까 훨씬 예약하기 편하더라고요!  &lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&quot; data-ke-size=&quot;size16&quot;&gt;원하는 타입을 클릭하면, 다음 단계인 [ &lt;b&gt;02 자리선택&lt;/b&gt; ] 페이지로 이동합니다!  ️➡️ &lt;/p&gt;
&lt;p data-end=&quot;334&quot; data-start=&quot;119&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-filename=&quot;스크린샷 2025-09-10 오후 1.47.23.png&quot; data-origin-width=&quot;2020&quot; data-origin-height=&quot;1618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sifPc/btsQqBiV5HN/YCtP5MzT1CshC7nDn36FUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sifPc/btsQqBiV5HN/YCtP5MzT1CshC7nDn36FUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sifPc/btsQqBiV5HN/YCtP5MzT1CshC7nDn36FUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsifPc%2FbtsQqBiV5HN%2FYCtP5MzT1CshC7nDn36FUk%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;2020&quot; height=&quot;1618&quot; data-filename=&quot;스크린샷 2025-09-10 오후 1.47.23.png&quot; data-origin-width=&quot;2020&quot; data-origin-height=&quot;1618&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2️⃣ &lt;b&gt;자리 선택 단계&lt;/b&gt;에서는 먼저 &lt;b&gt;숙박 일수&lt;/b&gt;를 선택해야 해요.&lt;br /&gt;드롭박스 ⬇️를 클릭해서 원하는 숙박 일수를 고르면 됩니다.  ️✨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;244&quot; data-start=&quot;138&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;244&quot; data-start=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;244&quot; data-start=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;선택하신 &lt;b&gt;캠핑 사이트 타입&lt;/b&gt; 외에는 클릭이 되지 않아요.  &lt;br /&gt;만약 다른 타입으로 변경하고 싶으시다면, &lt;b&gt;⬅️ 이전 버튼&lt;/b&gt;을 눌러 다시 처음부터 타입을 선택하셔야 합니다.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 1.54.40.png&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;1456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fr6wv/btsQtgdjuWe/xCCelsmoVjvxv2Raf6XfxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fr6wv/btsQtgdjuWe/xCCelsmoVjvxv2Raf6XfxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fr6wv/btsQtgdjuWe/xCCelsmoVjvxv2Raf6XfxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFr6wv%2FbtsQtgdjuWe%2FxCCelsmoVjvxv2Raf6XfxK%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;1856&quot; height=&quot;1456&quot; data-filename=&quot;스크린샷 2025-09-10 오후 1.54.40.png&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙박일수를 선택하시면 아래와 같이 예약가능 여부를 알 수 있어요.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 1.57.07.png&quot; data-origin-width=&quot;1498&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVXOYC/btsQtefwYkV/lnje5URaA0FUjqYVwz6qf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVXOYC/btsQtefwYkV/lnje5URaA0FUjqYVwz6qf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVXOYC/btsQtefwYkV/lnje5URaA0FUjqYVwz6qf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVXOYC%2FbtsQtefwYkV%2Flnje5URaA0FUjqYVwz6qf0%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;1498&quot; height=&quot;1254&quot; data-filename=&quot;스크린샷 2025-09-10 오후 1.57.07.png&quot; data-origin-width=&quot;1498&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3️⃣ &lt;b&gt;약관동의 및&amp;nbsp;결제 단계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자리를 고르고 &lt;b&gt;다음 버튼&lt;/b&gt;을 누르면 결제 페이지로 이동합니다.  ✨&lt;br /&gt;이때 &lt;b&gt;차량 정보 입력란  &lt;/b&gt;이 있는데, 꼭 미리 입력해두셔야 해요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;만약 입력하지 않으면 캠핑장 입구 차단기가 열리지 않는 불편한 상황이 생깁니다.  &lt;/p&gt;
&lt;p data-end=&quot;303&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;혹시 깜빡했다면 당황하지 마시고, 차단기 옆에 있는 &lt;b&gt;호출 버튼  &lt;/b&gt;을 눌러&lt;/p&gt;
&lt;p data-end=&quot;303&quot; data-start=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;캠핑 예약자입니다&amp;rdquo; 하고 말씀하시면 입장이 가능하답니다.  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.01.26.png&quot; data-origin-width=&quot;1972&quot; data-origin-height=&quot;1568&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RLRBg/btsQssL6U6W/WsVZ90D3BC7IocXQ8P1ADk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RLRBg/btsQssL6U6W/WsVZ90D3BC7IocXQ8P1ADk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RLRBg/btsQssL6U6W/WsVZ90D3BC7IocXQ8P1ADk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRLRBg%2FbtsQssL6U6W%2FWsVZ90D3BC7IocXQ8P1ADk%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;1972&quot; height=&quot;1568&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.01.26.png&quot; data-origin-width=&quot;1972&quot; data-origin-height=&quot;1568&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;추가로 알아두면 좋은 주의사항&lt;/b&gt;&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-filename=&quot;스크린샷 2025-09-10 오전 9.44.17.png&quot; data-origin-width=&quot;2922&quot; data-origin-height=&quot;1576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsKkEb/btsQrTQhgVd/GZsdegZMjeiqTBKWhsYuxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsKkEb/btsQrTQhgVd/GZsdegZMjeiqTBKWhsYuxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsKkEb/btsQrTQhgVd/GZsdegZMjeiqTBKWhsYuxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsKkEb%2FbtsQrTQhgVd%2FGZsdegZMjeiqTBKWhsYuxk%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;2922&quot; height=&quot;1576&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.44.17.png&quot; data-origin-width=&quot;2922&quot; data-origin-height=&quot;1576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  평화누리 캠핑장 요금 정보&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.46.58.png&quot; data-origin-width=&quot;2150&quot; data-origin-height=&quot;1634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3lRhT/btsQpGYXSe7/HYPKOVFORdbIwgAxurUimK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3lRhT/btsQpGYXSe7/HYPKOVFORdbIwgAxurUimK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3lRhT/btsQpGYXSe7/HYPKOVFORdbIwgAxurUimK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3lRhT%2FbtsQpGYXSe7%2FHYPKOVFORdbIwgAxurUimK%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;2150&quot; height=&quot;1634&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.46.58.png&quot; data-origin-width=&quot;2150&quot; data-origin-height=&quot;1634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ 평화누리 캠핑장 부대서비스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 부대시설이 잘 갖춰져 있어서, 짐을 많이 챙기지 않아도 가볍게 캠핑을 즐길 수 있을 것 같아요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.48.00.png&quot; data-origin-width=&quot;2150&quot; data-origin-height=&quot;618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mtyr5/btsQtbikkrQ/yG0jOg5V7V9Czm5tKn0kmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mtyr5/btsQtbikkrQ/yG0jOg5V7V9Czm5tKn0kmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mtyr5/btsQtbikkrQ/yG0jOg5V7V9Czm5tKn0kmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmtyr5%2FbtsQtbikkrQ%2FyG0jOg5V7V9Czm5tKn0kmk%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;2150&quot; height=&quot;618&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.48.00.png&quot; data-origin-width=&quot;2150&quot; data-origin-height=&quot;618&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.48.19.png&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;1632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFyl6L/btsQpHKoSMQ/J9AW8OVrcYULs5mO8eCFK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFyl6L/btsQpHKoSMQ/J9AW8OVrcYULs5mO8eCFK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFyl6L/btsQpHKoSMQ/J9AW8OVrcYULs5mO8eCFK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFyl6L%2FbtsQpHKoSMQ%2FJ9AW8OVrcYULs5mO8eCFK0%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;1888&quot; height=&quot;1632&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.48.19.png&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;1632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;** 유의사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;모든 대여용품은 양도불가하며, 퇴실시 반납 부탁드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;미사용한 물품은 결제 30분 이내 반납시에만 환불 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;보증품 : 신분증, 신용카드 또는 현금 5천원 ※ 대여용품 반납시 웰컴센터에서 돌려드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;물품 반납기한은 퇴실 전(오전 11시)까지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;등유는 별도로 판매하지 않습니다. 직접 구비해주시기 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.50.03.png&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;1634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clzekg/btsQsovLCML/96Y1GIA4Tkuwy0dDWxf2j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clzekg/btsQsovLCML/96Y1GIA4Tkuwy0dDWxf2j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clzekg/btsQsovLCML/96Y1GIA4Tkuwy0dDWxf2j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fclzekg%2FbtsQsovLCML%2F96Y1GIA4Tkuwy0dDWxf2j0%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;1922&quot; height=&quot;1634&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.50.03.png&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;1634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  평화누리 캠핑장 이용수칙&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; ️ 캠핑 사이트에서는 &lt;b&gt;매점에서 음식물 쓰레기와 종량제 봉투를 구매&lt;/b&gt;해서 사용해야 한답니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.51.48.png&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2zywR/btsQtcuMLDZ/pol8H9MG6emqDf5umLph10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2zywR/btsQtcuMLDZ/pol8H9MG6emqDf5umLph10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2zywR/btsQtcuMLDZ/pol8H9MG6emqDf5umLph10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2zywR%2FbtsQtcuMLDZ%2Fpol8H9MG6emqDf5umLph10%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;1754&quot; height=&quot;946&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.51.48.png&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.52.52.png&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qHtk0/btsQq0JdY6p/kgaKfs8n4JvxiqKlJKClDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qHtk0/btsQq0JdY6p/kgaKfs8n4JvxiqKlJKClDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qHtk0/btsQq0JdY6p/kgaKfs8n4JvxiqKlJKClDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqHtk0%2FbtsQq0JdY6p%2FkgaKfs8n4JvxiqKlJKClDk%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;1922&quot; height=&quot;732&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.52.52.png&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; ️ 평화누리 캠핑장 정보&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.55.08.png&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;1542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1kpTq/btsQtajtAmi/gNr2IKZCGKp22gayypepPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1kpTq/btsQtajtAmi/gNr2IKZCGKp22gayypepPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1kpTq/btsQtajtAmi/gNr2IKZCGKp22gayypepPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1kpTq%2FbtsQtajtAmi%2FgNr2IKZCGKp22gayypepPK%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;1898&quot; height=&quot;1542&quot; data-filename=&quot;스크린샷 2025-09-10 오전 9.55.08.png&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;1542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.03.37.png&quot; data-origin-width=&quot;2228&quot; data-origin-height=&quot;1252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nBwyk/btsQshqmdzV/WYFB57uwQYcIvniSiG5Vj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nBwyk/btsQshqmdzV/WYFB57uwQYcIvniSiG5Vj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nBwyk/btsQshqmdzV/WYFB57uwQYcIvniSiG5Vj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnBwyk%2FbtsQshqmdzV%2FWYFB57uwQYcIvniSiG5Vj1%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;2228&quot; height=&quot;1252&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.03.37.png&quot; data-origin-width=&quot;2228&quot; data-origin-height=&quot;1252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.04.05.png&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;1246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKuFo1/btsQroKfLaw/KUNXMRGEXfzluqJsJLVJO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKuFo1/btsQroKfLaw/KUNXMRGEXfzluqJsJLVJO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKuFo1/btsQroKfLaw/KUNXMRGEXfzluqJsJLVJO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKuFo1%2FbtsQroKfLaw%2FKUNXMRGEXfzluqJsJLVJO1%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;2252&quot; height=&quot;1246&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.04.05.png&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;1246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.04.38.png&quot; data-origin-width=&quot;2238&quot; data-origin-height=&quot;1096&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/do4UQc/btsQrwVOmen/yA9qppGJlfsRkdUZlZmn00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/do4UQc/btsQrwVOmen/yA9qppGJlfsRkdUZlZmn00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/do4UQc/btsQrwVOmen/yA9qppGJlfsRkdUZlZmn00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdo4UQc%2FbtsQrwVOmen%2FyA9qppGJlfsRkdUZlZmn00%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;2238&quot; height=&quot;1096&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.04.38.png&quot; data-origin-width=&quot;2238&quot; data-origin-height=&quot;1096&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.11.png&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/peK0T/btsQs69CzkP/qQpZdzjIzXupU8yKmyasL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/peK0T/btsQs69CzkP/qQpZdzjIzXupU8yKmyasL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/peK0T/btsQs69CzkP/qQpZdzjIzXupU8yKmyasL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpeK0T%2FbtsQs69CzkP%2FqQpZdzjIzXupU8yKmyasL0%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;2236&quot; height=&quot;1074&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.11.png&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1074&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.31.png&quot; data-origin-width=&quot;2228&quot; data-origin-height=&quot;1476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9O9Uz/btsQskACqFR/1gvFKEcC1tF92bCzjue7kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9O9Uz/btsQskACqFR/1gvFKEcC1tF92bCzjue7kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9O9Uz/btsQskACqFR/1gvFKEcC1tF92bCzjue7kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9O9Uz%2FbtsQskACqFR%2F1gvFKEcC1tF92bCzjue7kK%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;2228&quot; height=&quot;1476&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.31.png&quot; data-origin-width=&quot;2228&quot; data-origin-height=&quot;1476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.52.png&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baHYP8/btsQrnkc5Ly/NDQlPmddbpHjpAZK4gqUTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baHYP8/btsQrnkc5Ly/NDQlPmddbpHjpAZK4gqUTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baHYP8/btsQrnkc5Ly/NDQlPmddbpHjpAZK4gqUTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaHYP8%2FbtsQrnkc5Ly%2FNDQlPmddbpHjpAZK4gqUTK%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;2236&quot; height=&quot;1264&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.05.52.png&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.05.png&quot; data-origin-width=&quot;2238&quot; data-origin-height=&quot;1244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSm2Z5/btsQrZja8XR/nKZobiOR6xOBzSprfYOkxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSm2Z5/btsQrZja8XR/nKZobiOR6xOBzSprfYOkxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSm2Z5/btsQrZja8XR/nKZobiOR6xOBzSprfYOkxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSm2Z5%2FbtsQrZja8XR%2FnKZobiOR6xOBzSprfYOkxK%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;2238&quot; height=&quot;1244&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.05.png&quot; data-origin-width=&quot;2238&quot; data-origin-height=&quot;1244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.18.png&quot; data-origin-width=&quot;2242&quot; data-origin-height=&quot;1196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/soU5S/btsQt3q00eq/bKa5rBhYYnxUzK9nxDIMrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/soU5S/btsQt3q00eq/bKa5rBhYYnxUzK9nxDIMrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/soU5S/btsQt3q00eq/bKa5rBhYYnxUzK9nxDIMrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsoU5S%2FbtsQt3q00eq%2FbKa5rBhYYnxUzK9nxDIMrK%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;2242&quot; height=&quot;1196&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.18.png&quot; data-origin-width=&quot;2242&quot; data-origin-height=&quot;1196&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.38.png&quot; data-origin-width=&quot;2234&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWrwud/btsQroXMBe3/p23JXxGF5JpQvOTNKMKHYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWrwud/btsQroXMBe3/p23JXxGF5JpQvOTNKMKHYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWrwud/btsQroXMBe3/p23JXxGF5JpQvOTNKMKHYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWrwud%2FbtsQroXMBe3%2Fp23JXxGF5JpQvOTNKMKHYK%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;2234&quot; height=&quot;1058&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.06.38.png&quot; data-origin-width=&quot;2234&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  편의시설 안내&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캠핑장에 들어서면 제일 먼저 왼쪽에 **관리동(웰컴센터)**이 보입니다.&lt;br /&gt;입실을 위해서는 차량을 잠시 갓길에 세워두고, 웰컴센터에서 체크인을 하셔야 해요. ✅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;346&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;웰컴센터 기준으로 왼쪽에는 &lt;b&gt;무인 편의점  &lt;/b&gt;이 자리하고 있는데요, 체크인하면서 꼭 들러보시는 걸 추천드립니다!&lt;/p&gt;
&lt;p data-end=&quot;346&quot; data-start=&quot;164&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;346&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;346&quot; data-start=&quot;164&quot; data-ke-size=&quot;size16&quot;&gt;무인 편의점은 현금 결제 불가 ❌이며, &lt;b&gt;카드 결제만 가능&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-filename=&quot;스크린샷 2025-09-10 오후 2.10.22.png&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;1434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cudHg8/btsQtiI2iv2/zxs7sgzQBy7nQJEs9vPA4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cudHg8/btsQtiI2iv2/zxs7sgzQBy7nQJEs9vPA4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cudHg8/btsQtiI2iv2/zxs7sgzQBy7nQJEs9vPA4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcudHg8%2FbtsQtiI2iv2%2Fzxs7sgzQBy7nQJEs9vPA4k%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;1892&quot; height=&quot;1434&quot; data-filename=&quot;스크린샷 2025-09-10 오후 2.10.22.png&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;1434&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 평화누리 캠핑장의 &lt;b&gt;예약 방법과 기본 정보&lt;/b&gt;를 정리해보았습니다.&lt;br /&gt;처음 캠핑을 준비하시는 분들이나 예약 과정이 헷갈리셨던 분들께 도움이 되었길 바라요. ✨&lt;br /&gt;특히 잔여석 예약 팁이나 차량 정보 입력 같은 부분은 꼭 기억해두시면 좋아요.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;저도 처음엔 조금 헤맸지만, 이번에 정리하면서 다시 한 번 확실히 알게 되었답니다.  &lt;br /&gt;캠핑은 준비 단계부터 설레고, 하나하나 알아가는 재미가 있는 것 같아요.&lt;br /&gt;덕분에 캠핑 초보라도 큰 걱정 없이 떠날 수 있겠죠?  ️&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;평화누리 캠핑장은 시설과 부대 서비스가 잘 갖춰져 있어 초보자도 편하게 즐길 수 있습니다.&lt;br /&gt;이번 글이 캠핑을 준비하는 분들께 작은 가이드북 같은 역할이 되었으면 합니다.  &lt;br /&gt;다음 편에서는 제가 직접 다녀온 &lt;b&gt;평화누리 캠핑장 이용 후기&lt;/b&gt;를 자세히 들려드릴게요!  &lt;br /&gt;기대해주셔도 좋습니다. 그럼 오늘도 즐거운 하루 보내세요.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>휴식 로그/여행 &amp;amp; Play</category>
      <category>서울근교글램핑</category>
      <category>서울근교캠핑</category>
      <category>서울캠핑</category>
      <category>평화누리캠핑장</category>
      <author>콘솔로그</author>
      <guid isPermaLink="true">https://jjung2ing.tistory.com/85</guid>
      <comments>https://jjung2ing.tistory.com/85#entry85comment</comments>
      <pubDate>Wed, 10 Sep 2025 14:14:28 +0900</pubDate>
    </item>
  </channel>
</rss>