{
    "version": "https://jsonfeed.org/version/1",
    "title": "alvin.ing",
    "home_page_url": "https://alvin.ing/blog",
    "description": "아파트 실거래가와 부동산 통계를 제대로 읽는 기준부터 취득세·양도세 거래비용 계산기, 분양권 손피 계산기까지 제공하는 데이터 아카이브입니다.",
    "items": [
        {
            "id": "https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment",
            "content_html": "<p>미국만 난리가 아닙니다. 9월 초 독일 10년물 국채금리는 <strong>2011년 5월 이후 처음으로 3.3%를 넘었고</strong>, 프랑스 금리는 2008년 이후, 영국 30년물 국채금리는 <strong>1998년 이후 최고 수준</strong>까지 올라섰습니다. 유럽중앙은행(ECB)은 9월 예금금리를 2.25%에서 2.50%로 올리면서 물가가 “상당 기간 목표를 크게 웃돌 수 있다”고 경고했습니다.</p>\n<p>유럽 국채 이야기는 한국 아파트와 거리가 멀어 보이지만, 금리·환율·에너지 가격을 거치면 생각보다 가깝습니다. 이 글은 유럽발 채권시장 충격이 한국 주택시장으로 들어오는 경로를 세 가지로 나눠 정리합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"유럽-채권시장에서-벌어진-일\">유럽 채권시장에서 벌어진 일<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EC%9C%A0%EB%9F%BD-%EC%B1%84%EA%B6%8C%EC%8B%9C%EC%9E%A5%EC%97%90%EC%84%9C-%EB%B2%8C%EC%96%B4%EC%A7%84-%EC%9D%BC\" class=\"hash-link\" aria-label=\"유럽 채권시장에서 벌어진 일에 대한 직접 링크\" title=\"유럽 채권시장에서 벌어진 일에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>구분</th><th>2026년 9월 보도 기준</th></tr></thead><tbody><tr><td>독일 10년물</td><td>3.3% 돌파, 2011년 5월 이후 최고</td></tr><tr><td>프랑스 국채</td><td>2008년 11월 이후 최고 수준</td></tr><tr><td>영국 10년물</td><td>5.3%대, 2007년 이후 최고</td></tr><tr><td>영국 30년물</td><td>5.9%대, 1998년 이후 최고</td></tr><tr><td>유럽중앙은행</td><td>예금금리 2.25% → 2.50% 인상</td></tr></tbody></table>\n<p>배경으로는 에너지 가격 상승, 끈질긴 물가, 주요 중앙은행의 긴축 신호가 함께 꼽힙니다. 9월 말 일부 유럽 금리가 숨을 고르긴 했지만, 같은 시기 미국 장기금리는 오히려 2000년대 초반 이후 최고치를 경신했습니다. 한 지역의 문제가 아니라 <strong>전 세계 장기금리가 함께 다시 올라가는 국면</strong>이라는 점이 핵심입니다. 미국 쪽 상황은 <a class=\"\" href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate\">미국 30년물 금리와 주담대 금리</a>에서 따로 정리했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"경로-1-글로벌-금리-동조화--국내-대출금리\">경로 1. 글로벌 금리 동조화 → 국내 대출금리<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EA%B2%BD%EB%A1%9C-1-%EA%B8%80%EB%A1%9C%EB%B2%8C-%EA%B8%88%EB%A6%AC-%EB%8F%99%EC%A1%B0%ED%99%94--%EA%B5%AD%EB%82%B4-%EB%8C%80%EC%B6%9C%EA%B8%88%EB%A6%AC\" class=\"hash-link\" aria-label=\"경로 1. 글로벌 금리 동조화 → 국내 대출금리에 대한 직접 링크\" title=\"경로 1. 글로벌 금리 동조화 → 국내 대출금리에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>채권시장은 국경을 넘어 연결돼 있습니다. 유럽과 미국의 장기금리가 함께 오르면 국내 국고채·은행채 금리도 상승 압력을 받습니다. 은행채 금리는 고정형·혼합형 주택담보대출 금리의 기준이 되기 때문에, 해외 채권시장의 흔들림이 시차를 두고 대출 창구까지 내려옵니다.</p>\n<p>실제로 국내 은행 주담대 신규취급 금리는 8월 기준 연 4.66%로 4개월 연속 올랐고, 한국은행도 7월과 8월에 기준금리를 연속으로 인상해 연 3.00%가 됐습니다. 해외발 금리 압력과 국내 긴축이 겹친 상황입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"경로-2-환율--수입물가와-금리-결정\">경로 2. 환율 → 수입물가와 금리 결정<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EA%B2%BD%EB%A1%9C-2-%ED%99%98%EC%9C%A8--%EC%88%98%EC%9E%85%EB%AC%BC%EA%B0%80%EC%99%80-%EA%B8%88%EB%A6%AC-%EA%B2%B0%EC%A0%95\" class=\"hash-link\" aria-label=\"경로 2. 환율 → 수입물가와 금리 결정에 대한 직접 링크\" title=\"경로 2. 환율 → 수입물가와 금리 결정에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>유럽·미국 금리가 오르면 해외 자산의 상대적인 수익률이 높아져, 원화 가치가 압력을 받을 수 있습니다. 원·달러 환율이 오르면 다음 순서로 주택시장에 간접적인 영향이 생깁니다.</p>\n<ul>\n<li class=\"\"><strong>수입물가 상승</strong> — 원자재·에너지 수입 비용이 커지면서 물가 부담이 늘어납니다.</li>\n<li class=\"\"><strong>금리 인하 여력 축소</strong> — 물가와 환율이 불안하면 한국은행이 금리를 내리기 어려워집니다.</li>\n<li class=\"\"><strong>건설 원가 부담</strong> — 수입 자재 가격이 오르면 신축 공사비와 분양가에 부담이 쌓입니다.</li>\n</ul>\n<p>환율은 집값을 직접 움직이기보다 <strong>금리가 내려오기 어려운 환경을 만드는 쪽</strong>으로 작용하는 경우가 많습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"경로-3-에너지-가격--물가--긴축-장기화\">경로 3. 에너지 가격 → 물가 → 긴축 장기화<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EA%B2%BD%EB%A1%9C-3-%EC%97%90%EB%84%88%EC%A7%80-%EA%B0%80%EA%B2%A9--%EB%AC%BC%EA%B0%80--%EA%B8%B4%EC%B6%95-%EC%9E%A5%EA%B8%B0%ED%99%94\" class=\"hash-link\" aria-label=\"경로 3. 에너지 가격 → 물가 → 긴축 장기화에 대한 직접 링크\" title=\"경로 3. 에너지 가격 → 물가 → 긴축 장기화에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이번 유럽 채권 매도의 직접적인 계기 중 하나는 에너지 가격입니다. 유가와 가스 가격이 오르면 물가가 쉽게 내려오지 않고, 중앙은행은 금리를 더 오래 높게 유지할 가능성이 커집니다.</p>\n<p>주택시장 입장에서는 “금리가 언제 내려오느냐”가 매수 수요의 가장 큰 변수인데, 에너지발 물가는 그 시점을 뒤로 미루는 요인입니다. 한국처럼 에너지를 대부분 수입하는 나라는 이 경로의 영향을 더 크게 받습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"세-경로를-한-번에-보면\">세 경로를 한 번에 보면<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EC%84%B8-%EA%B2%BD%EB%A1%9C%EB%A5%BC-%ED%95%9C-%EB%B2%88%EC%97%90-%EB%B3%B4%EB%A9%B4\" class=\"hash-link\" aria-label=\"세 경로를 한 번에 보면에 대한 직접 링크\" title=\"세 경로를 한 번에 보면에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>경로</th><th>해외 변화</th><th>국내에서 나타나는 모습</th><th>주택시장 영향</th></tr></thead><tbody><tr><td>금리 동조화</td><td>유럽·미국 장기금리 상승</td><td>은행채·주담대 금리 상승</td><td>대출 부담 증가, 매수 수요 위축</td></tr><tr><td>환율</td><td>해외 금리 매력 상승</td><td>원화 약세 압력</td><td>금리 인하 지연, 건설 원가 부담</td></tr><tr><td>에너지</td><td>유가·가스 가격 상승</td><td>수입물가·소비자물가 상승</td><td>긴축 장기화 가능성</td></tr></tbody></table>\n<p>세 경로는 따로 움직이지 않고 서로를 강화합니다. 금리·환율·유가가 <strong>동시에</strong> 불리한 방향으로 움직일 때 주택시장의 부담이 커지고, 반대로 하나라도 방향이 바뀌면 분위기가 빠르게 달라질 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"그래도-지역과-단지마다-결과는-다릅니다\">그래도 지역과 단지마다 결과는 다릅니다<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EA%B7%B8%EB%9E%98%EB%8F%84-%EC%A7%80%EC%97%AD%EA%B3%BC-%EB%8B%A8%EC%A7%80%EB%A7%88%EB%8B%A4-%EA%B2%B0%EA%B3%BC%EB%8A%94-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"그래도 지역과 단지마다 결과는 다릅니다에 대한 직접 링크\" title=\"그래도 지역과 단지마다 결과는 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>거시 충격은 전국에 같이 오지만, 가격이 반응하는 크기는 단지마다 다릅니다. 입주 물량이 많은 지역, 전세가율이 낮아 매매가를 받쳐 주는 힘이 약한 단지, 대출 의존도가 높은 가격대는 같은 충격에도 더 크게 흔들릴 수 있습니다. 반대로 공급이 적고 실수요가 두터운 곳은 거래만 줄고 가격은 버티는 경우도 있습니다. 전세가율이 왜 중요한지는 <a class=\"\" href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk\">전세가율이 높으면 매수하기 좋을까?</a>에서 다뤘습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"관심-단지의-1년-뒤-범위부터-확인해-보기\">관심 단지의 1년 뒤 범위부터 확인해 보기<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EA%B4%80%EC%8B%AC-%EB%8B%A8%EC%A7%80%EC%9D%98-1%EB%85%84-%EB%92%A4-%EB%B2%94%EC%9C%84%EB%B6%80%ED%84%B0-%ED%99%95%EC%9D%B8%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"관심 단지의 1년 뒤 범위부터 확인해 보기에 대한 직접 링크\" title=\"관심 단지의 1년 뒤 범위부터 확인해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>해외 뉴스가 쏟아질수록 “그래서 내가 보는 아파트는?”이라는 질문으로 돌아와야 합니다. <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 가입 없이 1년 시세 체험</a>에서는 관심 단지와 평형을 고르면, 최근 실거래와 금리·환율 같은 시장 정보를 바탕으로 한 1년 뒤 예상 범위를 바로 볼 수 있습니다. 범위를 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값 읽는 법</a>을 참고하세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"유럽-금리가-오르면-한국-금리도-오르나요\">유럽 금리가 오르면 한국 금리도 오르나요?<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EC%9C%A0%EB%9F%BD-%EA%B8%88%EB%A6%AC%EA%B0%80-%EC%98%A4%EB%A5%B4%EB%A9%B4-%ED%95%9C%EA%B5%AD-%EA%B8%88%EB%A6%AC%EB%8F%84-%EC%98%A4%EB%A5%B4%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"유럽 금리가 오르면 한국 금리도 오르나요?에 대한 직접 링크\" title=\"유럽 금리가 오르면 한국 금리도 오르나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>같은 폭으로 움직이지는 않지만, 글로벌 채권시장이 연결돼 있어 국내 국고채·은행채 금리에 상승 압력이 생깁니다. 특히 미국 장기금리까지 함께 오르는 시기에는 국내 대출금리에도 반영될 가능성이 커집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"환율이-오르면-아파트-가격도-오르나요-내리나요\">환율이 오르면 아파트 가격도 오르나요, 내리나요?<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%ED%99%98%EC%9C%A8%EC%9D%B4-%EC%98%A4%EB%A5%B4%EB%A9%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EB%8F%84-%EC%98%A4%EB%A5%B4%EB%82%98%EC%9A%94-%EB%82%B4%EB%A6%AC%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"환율이 오르면 아파트 가격도 오르나요, 내리나요?에 대한 직접 링크\" title=\"환율이 오르면 아파트 가격도 오르나요, 내리나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>환율은 집값을 한 방향으로 직접 움직이기보다 물가와 금리를 거쳐 간접적으로 영향을 줍니다. 환율 상승이 물가를 자극해 금리 인하를 늦추면 매수 수요에는 부담이 되고, 수입 자재 비용 상승은 신축 원가 부담으로 이어질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"해외-금리-뉴스가-나올-때마다-매수-계획을-바꿔야-하나요\">해외 금리 뉴스가 나올 때마다 매수 계획을 바꿔야 하나요?<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%ED%95%B4%EC%99%B8-%EA%B8%88%EB%A6%AC-%EB%89%B4%EC%8A%A4%EA%B0%80-%EB%82%98%EC%98%AC-%EB%95%8C%EB%A7%88%EB%8B%A4-%EB%A7%A4%EC%88%98-%EA%B3%84%ED%9A%8D%EC%9D%84-%EB%B0%94%EA%BF%94%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"해외 금리 뉴스가 나올 때마다 매수 계획을 바꿔야 하나요?에 대한 직접 링크\" title=\"해외 금리 뉴스가 나올 때마다 매수 계획을 바꿔야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>뉴스 하나로 계획을 바꾸기보다 금리·환율·유가가 같은 방향으로 계속 움직이는지, 관심 단지의 실제 거래가 줄거나 가격 범위가 바뀌는지를 함께 확인하는 것이 좋습니다. 지켜볼 지표를 정리하는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist\">거시지표가 흔들릴 때 아파트 매수 타이밍 체크리스트</a>를 참고하세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.euronews.com/business/2026/09/01/european-government-bond-yields-surge-to-15-year-highs-as-sell-off-deepens\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">euronews — European government bond yields surge to 15-year highs as sell-off deepens (2026-09-01)</a></li>\n<li class=\"\"><a href=\"https://www.bloomberg.com/news/articles/2026-09-10/european-bond-selloff-deepens-as-ecb-flags-inflationary-risks\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Bloomberg — ECB Flags Inflation Threat, European Bond Yields Hit Multi-Year Highs (2026-09-10)</a></li>\n<li class=\"\"><a href=\"https://www.euronews.com/business/2026/09/11/european-bond-yields-hit-multi-year-highs-as-global-sell-off-continues\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">euronews — European bond yields hit multi-year highs as global sell-off continues (2026-09-11)</a></li>\n<li class=\"\"><a href=\"https://www.bloomberg.com/news/articles/2026-09-29/us-30-year-treasury-yield-approaches-highest-level-since-2002\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Bloomberg — US 30-Year Treasury Yield Rises to Highest Level Since 2002 (2026-09-29)</a></li>\n<li class=\"\"><a href=\"https://m.inews24.com/v/2010449\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아이뉴스24 — 은행 주담대 금리 연 4.66%, 3년 9개월 만에 최고치</a></li>\n</ul>\n<blockquote>\n<p>이 글은 공개 보도를 바탕으로 해외 채권시장 변화가 국내 주택시장에 전달되는 일반적인 경로를 설명한 참고 자료입니다. 특정 아파트의 매수·매도를 권유하지 않으며, 예상 범위는 오차가 있을 수 있고 가격이나 수익을 보장하지 않습니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment",
            "title": "독일 2011년, 영국 1998년 이후 최고… 유럽 국채 쇼크가 한국 아파트에 닿는 3가지 경로",
            "summary": "2026년 9월 독일·프랑스·영국 국채금리가 십수 년 만의 최고치를 기록하고 유럽중앙은행이 금리를 올렸습니다. 유럽 채권시장 충격이 환율, 에너지 가격, 글로벌 금리 동조화를 거쳐 한국 아파트 시장에 영향을 주는 경로를 정리합니다.",
            "date_modified": "2026-10-03T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "금융·세금",
                "아파트"
            ]
        },
        {
            "id": "https://alvin.ing/blog/macro-volatility-apartment-timing-checklist",
            "content_html": "<p>미국 30년물 국채금리는 2002년 이후 최고, 독일 국채금리는 2011년 이후 최고, 영국 30년물은 1998년 이후 최고. 연준은 2023년 이후 처음으로 금리를 올렸고, 한국은행은 7월과 8월 연속 인상으로 기준금리를 연 3.00%까지 올렸습니다. 국내 은행 주담대 금리는 3년 9개월 만의 최고치입니다.</p>\n<p>이런 뉴스가 한꺼번에 쏟아지면 “지금 사면 꼭지 아닐까”, “더 떨어지기 전에 팔아야 하나” 같은 불안이 커집니다. 하지만 거시지표가 혼란스러운 시기일수록 <strong>바닥과 꼭지를 맞히려는 시도는 거의 실패</strong>합니다. 대신 무엇을 지켜보고, 어떤 신호가 나오면 움직일지 기준을 미리 정해 두는 쪽이 훨씬 현실적입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"타이밍은-맞히는-것이-아니라-기준을-정하는-것\">타이밍은 “맞히는 것”이 아니라 “기준을 정하는 것”<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%ED%83%80%EC%9D%B4%EB%B0%8D%EC%9D%80-%EB%A7%9E%ED%9E%88%EB%8A%94-%EA%B2%83%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EA%B8%B0%EC%A4%80%EC%9D%84-%EC%A0%95%ED%95%98%EB%8A%94-%EA%B2%83\" class=\"hash-link\" aria-label=\"타이밍은 “맞히는 것”이 아니라 “기준을 정하는 것”에 대한 직접 링크\" title=\"타이밍은 “맞히는 것”이 아니라 “기준을 정하는 것”에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>금리 상승기에는 두 가지 실수가 자주 나옵니다.</p>\n<ul>\n<li class=\"\"><strong>공포 매도·매수 포기</strong>: 뉴스 헤드라인만 보고 실수요 계획까지 무기한 미루거나, 급하게 매도를 결정합니다.</li>\n<li class=\"\"><strong>반등 기대 추격</strong>: 금리가 잠깐 내려가는 날 “이제 바닥”이라며 준비 없이 들어갑니다.</li>\n</ul>\n<p>둘 다 기준 없이 뉴스에 반응한 결과입니다. 아래 체크리스트는 “지금 사라”, “지금 팔아라”를 말하지 않습니다. 대신 <strong>어떤 지표가 어느 방향으로 바뀌는지 꾸준히 기록하는 틀</strong>입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"체크리스트-1-거시지표-5가지\">체크리스트 1. 거시지표 5가지<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8-1-%EA%B1%B0%EC%8B%9C%EC%A7%80%ED%91%9C-5%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"체크리스트 1. 거시지표 5가지에 대한 직접 링크\" title=\"체크리스트 1. 거시지표 5가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>지표</th><th>확인할 질문</th><th>왜 중요한가</th></tr></thead><tbody><tr><td>미국·유럽 장기금리</td><td>상승이 멈추고 몇 주 이상 안정되는가?</td><td>국내 은행채·고정형 대출금리의 바깥쪽 압력입니다.</td></tr><tr><td>한국 기준금리</td><td>다음 금융통화위원회에서 동결·인상 중 어느 쪽 신호인가?</td><td>변동형 대출금리와 시장 기대를 직접 바꿉니다.</td></tr><tr><td>국내 주담대 금리</td><td>신규취급 금리가 몇 달째 같은 방향인가?</td><td>매수 수요에 가장 직접적인 숫자입니다.</td></tr><tr><td>원·달러 환율</td><td>급등이 진정되는가?</td><td>물가와 금리 인하 여력에 영향을 줍니다.</td></tr><tr><td>유가·에너지 가격</td><td>물가를 다시 자극하는가?</td><td>긴축이 길어질지 가늠하는 단서입니다.</td></tr></tbody></table>\n<p>이 다섯 가지를 매일 볼 필요는 없습니다. <strong>한 달에 한두 번, 같은 날짜에, 같은 기준으로</strong> 기록하는 것만으로도 “분위기”가 아니라 “방향”을 볼 수 있습니다. 미국·유럽 금리 상황은 <a class=\"\" href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate\">미국 30년물 금리와 주담대 금리</a>, <a class=\"\" href=\"https://alvin.ing/blog/europe-bond-yield-surge-korea-apartment\">유럽 국채 쇼크가 한국 아파트에 닿는 경로</a>에서 정리했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"체크리스트-2-관심-단지-신호-4가지\">체크리스트 2. 관심 단지 신호 4가지<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8-2-%EA%B4%80%EC%8B%AC-%EB%8B%A8%EC%A7%80-%EC%8B%A0%ED%98%B8-4%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"체크리스트 2. 관심 단지 신호 4가지에 대한 직접 링크\" title=\"체크리스트 2. 관심 단지 신호 4가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>거시지표가 “바람의 방향”이라면, 관심 단지의 거래는 “내 집 앞의 실제 날씨”입니다.</p>\n<ol>\n<li class=\"\"><strong>같은 평형 최근 1년 거래 범위</strong> — 최근 거래가 범위의 위쪽에 붙는지, 아래쪽으로 내려오는지 봅니다.</li>\n<li class=\"\"><strong>거래 건수</strong> — 금리 충격은 가격보다 거래량에 먼저 나타나는 경우가 많습니다. 거래가 급감하면 가격 신호를 해석할 표본도 줄어듭니다.</li>\n<li class=\"\"><strong>전세가율</strong> — 전세가가 매매가를 받쳐 주는 힘이 유지되는지 확인합니다. 해석 방법은 <a class=\"\" href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk\">전세가율이 높으면 매수하기 좋을까?</a>를 참고하세요.</li>\n<li class=\"\"><strong>1년 뒤 예상 범위의 변화</strong> — 한 번의 예측값보다 지난달 대비 범위가 위·아래 어느 쪽으로 옮겨 갔는지가 더 유용합니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"체크리스트-3-내-자금-조건-3가지\">체크리스트 3. 내 자금 조건 3가지<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8-3-%EB%82%B4-%EC%9E%90%EA%B8%88-%EC%A1%B0%EA%B1%B4-3%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"체크리스트 3. 내 자금 조건 3가지에 대한 직접 링크\" title=\"체크리스트 3. 내 자금 조건 3가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>금리 1%p 상승을 견디는가</strong> — 지금보다 1%p 높은 금리에서도 월 상환액이 감당되는지 계산합니다.</li>\n<li class=\"\"><strong>거래비용까지 넣었는가</strong> — 취득세·중개보수·이사비를 포함한 총자금은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator\">아파트 거래비용 계산기</a>로 미리 확인합니다.</li>\n<li class=\"\"><strong>언제까지 결정해야 하는가</strong> — 전세 만기, 입학, 이직처럼 실제 마감일이 있는 실수요자는 “최적의 시점”보다 “감당 가능한 시점”을 기준으로 삼는 편이 안전합니다.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"신호가-엇갈릴-때-읽는-법\">신호가 엇갈릴 때 읽는 법<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%8B%A0%ED%98%B8%EA%B0%80-%EC%97%87%EA%B0%88%EB%A6%B4-%EB%95%8C-%EC%9D%BD%EB%8A%94-%EB%B2%95\" class=\"hash-link\" aria-label=\"신호가 엇갈릴 때 읽는 법에 대한 직접 링크\" title=\"신호가 엇갈릴 때 읽는 법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>현실에서는 지표가 한 방향으로 깔끔하게 정리되는 경우가 드뭅니다. 자주 나오는 조합을 정리하면 다음과 같습니다.</p>\n<table><thead><tr><th>상황</th><th>해석</th><th>할 일</th></tr></thead><tbody><tr><td>거시지표 악화 + 관심 단지 거래 유지</td><td>실수요가 받치고 있지만 금리 부담이 누적되는 중</td><td>거래 범위가 아래로 이동하는지 계속 기록</td></tr><tr><td>거시지표 악화 + 거래 급감</td><td>관망세가 짙어짐, 가격 신호는 아직 불확실</td><td>표본이 다시 쌓일 때까지 범위 변화 위주로 관찰</td></tr><tr><td>장기금리 안정 + 거래 회복</td><td>분위기 전환 가능성, 다만 일시적 반등일 수 있음</td><td>몇 달 이상 같은 방향인지 확인 후 자금 계획 점검</td></tr><tr><td>금리 하락 + 환율·유가 불안</td><td>금리 인하 기대가 다시 꺾일 위험</td><td>금리 시나리오를 여러 개로 나눠 비교</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트로-모니터링하는-방법\">아파트 인사이트로 모니터링하는 방법<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EB%A1%9C-%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"아파트 인사이트로 모니터링하는 방법에 대한 직접 링크\" title=\"아파트 인사이트로 모니터링하는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>체크리스트를 손으로 매달 채우는 것은 생각보다 번거롭습니다. <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트</a>에서는 위 흐름을 한곳에서 이어서 볼 수 있습니다.</p>\n<ul>\n<li class=\"\"><strong>부동산 시장 국면</strong> — 홈 화면에서 지금 시장을 0~100점 점수와 “매우 우호·우호·관망·주의·위험” 단계로 요약하고, 지난번 대비 변화와 함께 금리·심리·정책·대외환경 가운데 유리·불리하게 작용하는 주요 신호를 보여줍니다.</li>\n<li class=\"\"><strong>관심 아파트와 실거래 변화</strong> — 관심 단지를 등록해 두면 새 실거래가 반영된 흐름을 단지 상세에서 확인하고, 변경 사항을 알림으로 받을 수 있습니다.</li>\n<li class=\"\"><strong>조건을 바꾼 시나리오 비교</strong> — 시뮬레이션에서 금리 같은 거시경제 조건을 직접 조절해, 기준 예측과 조건을 바꾼 결과를 나란히 놓고 볼 수 있습니다. “금리가 0.5%p 더 오르면”, “금리가 지금 수준에서 멈추면” 같은 경우를 미리 비교해 두면, 실제 뉴스가 나왔을 때 당황하지 않고 기준대로 판단할 수 있습니다.</li>\n</ul>\n<p>먼저 가입 없이 관심 단지의 1년 뒤 예상 범위만 보고 싶다면 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">가입 없이 1년 시세 체험</a>에서 시작해도 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리가-오르는-지금은-아파트를-사면-안-되나요\">금리가 오르는 지금은 아파트를 사면 안 되나요?<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EA%B8%88%EB%A6%AC%EA%B0%80-%EC%98%A4%EB%A5%B4%EB%8A%94-%EC%A7%80%EA%B8%88%EC%9D%80-%EC%95%84%ED%8C%8C%ED%8A%B8%EB%A5%BC-%EC%82%AC%EB%A9%B4-%EC%95%88-%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"금리가 오르는 지금은 아파트를 사면 안 되나요?에 대한 직접 링크\" title=\"금리가 오르는 지금은 아파트를 사면 안 되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>금리 상승은 매수 부담을 키우지만, 그것만으로 매수 여부를 정할 수는 없습니다. 실거주 필요 시점, 금리 1%p 상승 시 상환 여력, 관심 단지의 실제 거래 흐름을 함께 확인하고, 여러 금리 시나리오에서도 감당 가능한지 따져 보는 것이 좋습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"부동산-시장-국면-점수가-높으면-사도-된다는-뜻인가요\">부동산 시장 국면 점수가 높으면 사도 된다는 뜻인가요?<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EB%B6%80%EB%8F%99%EC%82%B0-%EC%8B%9C%EC%9E%A5-%EA%B5%AD%EB%A9%B4-%EC%A0%90%EC%88%98%EA%B0%80-%EB%86%92%EC%9C%BC%EB%A9%B4-%EC%82%AC%EB%8F%84-%EB%90%9C%EB%8B%A4%EB%8A%94-%EB%9C%BB%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"부동산 시장 국면 점수가 높으면 사도 된다는 뜻인가요?에 대한 직접 링크\" title=\"부동산 시장 국면 점수가 높으면 사도 된다는 뜻인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 시장 국면 점수는 전체 시장 분위기를 요약한 참고 지표이며 특정 단지의 매수 시점을 알려주는 신호가 아닙니다. 단지별 판단은 해당 단지의 거래 흐름과 예상 범위, 개인의 자금 조건을 함께 봐야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거시지표는-얼마나-자주-확인해야-하나요\">거시지표는 얼마나 자주 확인해야 하나요?<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EA%B1%B0%EC%8B%9C%EC%A7%80%ED%91%9C%EB%8A%94-%EC%96%BC%EB%A7%88%EB%82%98-%EC%9E%90%EC%A3%BC-%ED%99%95%EC%9D%B8%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"거시지표는 얼마나 자주 확인해야 하나요?에 대한 직접 링크\" title=\"거시지표는 얼마나 자주 확인해야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>뉴스가 많은 시기라도 한 달에 한두 번, 같은 기준으로 기록하는 정도면 충분합니다. 하루하루의 등락보다 몇 주에서 몇 달에 걸친 방향이 주택시장에는 더 의미가 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/macro-volatility-apartment-timing-checklist#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.bloomberg.com/news/articles/2026-09-29/us-30-year-treasury-yield-approaches-highest-level-since-2002\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Bloomberg — US 30-Year Treasury Yield Rises to Highest Level Since 2002 (2026-09-29)</a></li>\n<li class=\"\"><a href=\"https://www.cnbc.com/2026/09/16/fed-rate-decision-september-2026.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">CNBC — Fed rate decision September 2026 (2026-09-16)</a></li>\n<li class=\"\"><a href=\"https://www.euronews.com/business/2026/09/11/european-bond-yields-hit-multi-year-highs-as-global-sell-off-continues\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">euronews — European bond yields hit multi-year highs as global sell-off continues (2026-09-11)</a></li>\n<li class=\"\"><a href=\"https://www.mt.co.kr/economy/2026/08/27/2026082709050770978\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">머니투데이 — 한은, 기준금리 3% 두 달 연속 인상 (2026-08-27)</a></li>\n<li class=\"\"><a href=\"https://m.inews24.com/v/2010449\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아이뉴스24 — 은행 주담대 금리 연 4.66%, 3년 9개월 만에 최고치</a></li>\n</ul>\n<blockquote>\n<p>이 글은 거시지표와 주택시장 신호를 정리하는 방법을 설명한 참고 자료이며, 투자 권유나 매수·매도 추천이 아닙니다. 시장 국면과 예상 범위는 오차가 있을 수 있고 가격·거래 가능성·수익을 보장하지 않습니다. 최종 결정과 책임은 이용자에게 있으며, 실제 계약 전에는 금융기관 조건과 공식 자료를 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/macro-volatility-apartment-timing-checklist",
            "title": "채권 발작에 금리 인상까지… 지금 아파트 사도 될까? 거시지표 혼란기 타이밍 체크리스트",
            "summary": "미국·유럽 장기금리 급등과 국내 기준금리 인상이 겹친 2026년 가을, 아파트 매수·매도 시점을 고민할 때 지켜봐야 할 거시지표 5가지와 관심 단지 신호를 체크리스트로 정리합니다.",
            "date_modified": "2026-10-03T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "금융·세금",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate",
            "content_html": "<p>미국 30년 만기 국채금리가 9월 말 <strong>2002년 이후 가장 높은 수준</strong>까지 올라섰습니다. 10월 2일 기준 30년물은 5.6%대, 10년물은 5.2%대에 머물러 있습니다. 미국 연방준비제도(연준)는 9월 16일 기준금리를 0.25%p 올려 3.75~4.00%로 맞췄는데, 2023년 이후 첫 인상입니다.</p>\n<p>“미국 채권 이야기가 내 아파트랑 무슨 상관이냐”고 생각하기 쉽지만, 같은 기간 한국의 은행 주택담보대출 금리는 <strong>연 4.66%로 3년 9개월 만에 최고치</strong>를 찍었습니다. 이 글은 태평양 건너 장기금리가 내 대출이자와 아파트 매수 수요까지 어떻게 이어지는지, 숫자를 볼 때 무엇을 헷갈리면 안 되는지 정리합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"지금-무슨-일이-벌어지고-있나\">지금 무슨 일이 벌어지고 있나<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EC%A7%80%EA%B8%88-%EB%AC%B4%EC%8A%A8-%EC%9D%BC%EC%9D%B4-%EB%B2%8C%EC%96%B4%EC%A7%80%EA%B3%A0-%EC%9E%88%EB%82%98\" class=\"hash-link\" aria-label=\"지금 무슨 일이 벌어지고 있나에 대한 직접 링크\" title=\"지금 무슨 일이 벌어지고 있나에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>최근 한 달 동안 확인된 사실만 먼저 모아 보겠습니다.</p>\n<table><thead><tr><th>구분</th><th>최근 상황 (2026년 9월~10월 초 보도 기준)</th></tr></thead><tbody><tr><td>미국 30년물 국채금리</td><td>9월 말 2002년 이후 최고 수준, 10월 2일 5.6%대</td></tr><tr><td>미국 10년물 국채금리</td><td>10월 2일 5.2%대</td></tr><tr><td>미국 기준금리</td><td>9월 16일 0.25%p 인상, 3.75~4.00% (2023년 이후 첫 인상)</td></tr><tr><td>한국 기준금리</td><td>7월·8월 연속 인상, 8월 27일 연 3.00%</td></tr><tr><td>국내 은행 주담대 금리</td><td>8월 신규취급 가중평균 연 4.66%, 2022년 11월 이후 최고, 4개월 연속 상승</td></tr></tbody></table>\n<p>시장에서 꼽는 배경은 대체로 비슷합니다. 물가가 예상보다 오래 높게 유지되고 있고, 중동 정세로 유가가 올랐으며, 미국 정부 부채가 커지면서 장기채를 사려는 쪽이 더 높은 금리를 요구하고 있다는 것입니다. 10월 2일 발표된 미국 9월 고용지표가 예상보다 크게 약했는데도 장기금리가 다시 올랐다는 점은, 이번 금리 상승이 경기만으로 설명되지 않는다는 신호로 읽힙니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"미국-장기금리가-내-주담대까지-오는-4단계\">미국 장기금리가 내 주담대까지 오는 4단계<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EB%AF%B8%EA%B5%AD-%EC%9E%A5%EA%B8%B0%EA%B8%88%EB%A6%AC%EA%B0%80-%EB%82%B4-%EC%A3%BC%EB%8B%B4%EB%8C%80%EA%B9%8C%EC%A7%80-%EC%98%A4%EB%8A%94-4%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"미국 장기금리가 내 주담대까지 오는 4단계에 대한 직접 링크\" title=\"미국 장기금리가 내 주담대까지 오는 4단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>미국 국채금리가 한국 대출금리에 그대로 더해지는 것은 아닙니다. 다만 다음 경로로 압력이 전달됩니다.</p>\n<ol>\n<li class=\"\"><strong>미국 장기금리 상승</strong> — 전 세계 채권 금리의 기준점 역할을 하는 미국 국채금리가 오르면, 다른 나라 채권도 상대적으로 매력이 떨어집니다.</li>\n<li class=\"\"><strong>국내 시장금리 동반 상승</strong> — 국고채, 은행채 같은 국내 채권 금리도 따라 오를 압력을 받습니다. 은행이 대출 재원을 마련하는 비용이 커집니다.</li>\n<li class=\"\"><strong>고정형·혼합형 주담대 금리 상승</strong> — 은행채 금리를 기준으로 삼는 고정형·혼합형 대출 금리가 먼저 움직이고, 변동형은 코픽스 등 기준금리를 따라 시차를 두고 반영됩니다.</li>\n<li class=\"\"><strong>매수 수요와 거래량 변화</strong> — 같은 소득으로 빌릴 수 있는 금액이 줄고, 매달 갚을 이자가 늘어나면서 매수 결정을 미루는 사람이 늘어납니다.</li>\n</ol>\n<p>여기에 한국은행이 7월과 8월에 기준금리를 연속으로 올린 것까지 겹쳤습니다. 이번 대출금리 상승은 미국발 장기금리 압력과 국내 통화 긴축이 <strong>동시에</strong> 작용한 결과라는 점이 이전과 다릅니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리-05p가-매달-갚는-돈을-얼마나-바꿀까\">금리 0.5%p가 매달 갚는 돈을 얼마나 바꿀까<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EA%B8%88%EB%A6%AC-05p%EA%B0%80-%EB%A7%A4%EB%8B%AC-%EA%B0%9A%EB%8A%94-%EB%8F%88%EC%9D%84-%EC%96%BC%EB%A7%88%EB%82%98-%EB%B0%94%EA%BF%80%EA%B9%8C\" class=\"hash-link\" aria-label=\"금리 0.5%p가 매달 갚는 돈을 얼마나 바꿀까에 대한 직접 링크\" title=\"금리 0.5%p가 매달 갚는 돈을 얼마나 바꿀까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>금리 변화는 퍼센트로 보면 작아 보이지만, 월 상환액으로 바꾸면 체감이 달라집니다. 3억 원을 30년 원리금균등상환으로 빌린다고 가정해 보겠습니다.</p>\n<table><thead><tr><th>대출금리</th><th>월 상환액(약)</th><th>연 4.0% 대비 차이</th></tr></thead><tbody><tr><td>연 4.0%</td><td>143만 원</td><td>—</td></tr><tr><td>연 4.5%</td><td>152만 원</td><td>약 +9만 원</td></tr><tr><td>연 5.0%</td><td>161만 원</td><td>약 +18만 원</td></tr><tr><td>연 5.5%</td><td>170만 원</td><td>약 +27만 원</td></tr></tbody></table>\n<blockquote>\n<p>단순 계산 예시입니다. 실제 대출 조건은 상환 방식, 가산금리, 우대금리, 규제 비율에 따라 달라집니다.</p>\n</blockquote>\n<p>같은 월 상환 여력으로 버틸 수 있는 대출 원금도 줄어듭니다. 금리가 오를 때 거래가 먼저 줄고 가격은 시차를 두고 움직이는 경우가 많은 이유가 여기에 있습니다. 금리와 아파트 가격의 일반적인 관계는 <a class=\"\" href=\"https://alvin.ing/blog/mortgage-rate-apartment-price\">주택담보대출 금리와 아파트 가격의 상관관계</a>에서 더 자세히 다뤘습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리-오르면-집값-폭락이-항상-맞지-않는-이유\">“금리 오르면 집값 폭락”이 항상 맞지 않는 이유<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EA%B8%88%EB%A6%AC-%EC%98%A4%EB%A5%B4%EB%A9%B4-%EC%A7%91%EA%B0%92-%ED%8F%AD%EB%9D%BD%EC%9D%B4-%ED%95%AD%EC%83%81-%EB%A7%9E%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"“금리 오르면 집값 폭락”이 항상 맞지 않는 이유에 대한 직접 링크\" title=\"“금리 오르면 집값 폭락”이 항상 맞지 않는 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>금리 상승은 분명한 하방 압력이지만, 그것 하나로 가격 방향이 정해지지는 않습니다.</p>\n<ul>\n<li class=\"\"><strong>공급</strong>: 같은 시기에 새 아파트 입주 물량이 적은 지역은 금리 부담이 커져도 가격이 쉽게 밀리지 않을 수 있습니다.</li>\n<li class=\"\"><strong>전세가율</strong>: 전세가가 매매가를 받쳐 주는 단지와 그렇지 않은 단지는 같은 금리 충격에도 반응이 다릅니다.</li>\n<li class=\"\"><strong>소득과 경기</strong>: 한국은행은 올해 성장률 전망을 3.3%로 올렸습니다. 소득이 함께 늘면 금리 부담 일부가 상쇄됩니다.</li>\n<li class=\"\"><strong>정책</strong>: 대출 규제나 세제 변화는 금리보다 더 직접적으로 매수 수요를 바꾸기도 합니다.</li>\n</ul>\n<p>그래서 “미국 금리가 올랐으니 지금 집을 팔아야 한다” 또는 “곧 폭락하니 기다리면 된다” 같은 단정은 위험합니다. 중요한 것은 <strong>금리 변화가 내가 보는 단지와 내 자금 계획에 얼마나 영향을 주는지</strong>를 따로 확인하는 일입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"지금-확인해-볼-3가지\">지금 확인해 볼 3가지<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EC%A7%80%EA%B8%88-%ED%99%95%EC%9D%B8%ED%95%B4-%EB%B3%BC-3%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"지금 확인해 볼 3가지에 대한 직접 링크\" title=\"지금 확인해 볼 3가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\"><strong>내 대출의 금리 유형</strong> — 고정형인지, 혼합형이라면 언제 변동으로 바뀌는지, 변동형이라면 몇 개월 주기로 재산정되는지 확인합니다.</li>\n<li class=\"\"><strong>금리 1%p 상승 시 월 상환액</strong> — 지금 금리보다 1%p 높은 조건에서도 생활비가 버티는지 미리 계산해 둡니다.</li>\n<li class=\"\"><strong>관심 단지의 최근 거래 흐름</strong> — 금리 뉴스보다 실제 거래가 줄고 있는지, 같은 평형 거래 범위가 아래로 움직이는지가 더 직접적인 신호입니다. 최근 거래를 읽는 순서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region\">지역별 아파트 실거래가 조회하는 법</a>에 정리했습니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리-조건을-바꿔-내-단지에-적용해-보기\">금리 조건을 바꿔 내 단지에 적용해 보기<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EA%B8%88%EB%A6%AC-%EC%A1%B0%EA%B1%B4%EC%9D%84-%EB%B0%94%EA%BF%94-%EB%82%B4-%EB%8B%A8%EC%A7%80%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"금리 조건을 바꿔 내 단지에 적용해 보기에 대한 직접 링크\" title=\"금리 조건을 바꿔 내 단지에 적용해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>뉴스의 금리는 “시장 평균”이고, 내가 궁금한 것은 “내 단지와 내 조건”입니다. <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트</a>의 시뮬레이션에서는 관심 아파트를 고른 뒤 주담대 금리 같은 거시경제 조건을 직접 조절해, 기준 예측과 조건을 바꾼 결과를 나란히 비교할 수 있습니다. “금리가 지금보다 0.5%p 더 오르면 1년 뒤 예상 범위가 어떻게 달라지는가”를 한 화면에서 확인하는 식입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"미국-국채금리가-오르면-한국-주담대-금리도-바로-오르나요\">미국 국채금리가 오르면 한국 주담대 금리도 바로 오르나요?<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EB%AF%B8%EA%B5%AD-%EA%B5%AD%EC%B1%84%EA%B8%88%EB%A6%AC%EA%B0%80-%EC%98%A4%EB%A5%B4%EB%A9%B4-%ED%95%9C%EA%B5%AD-%EC%A3%BC%EB%8B%B4%EB%8C%80-%EA%B8%88%EB%A6%AC%EB%8F%84-%EB%B0%94%EB%A1%9C-%EC%98%A4%EB%A5%B4%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"미국 국채금리가 오르면 한국 주담대 금리도 바로 오르나요?에 대한 직접 링크\" title=\"미국 국채금리가 오르면 한국 주담대 금리도 바로 오르나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>바로 같은 폭으로 오르지는 않습니다. 다만 국내 국고채·은행채 금리가 함께 오를 압력을 받기 때문에, 은행채를 기준으로 하는 고정형·혼합형 대출 금리에 먼저 반영되는 경우가 많습니다. 변동형은 기준 지표에 따라 시차를 두고 움직입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"지금-고정금리로-갈아타는-게-유리한가요\">지금 고정금리로 갈아타는 게 유리한가요?<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EC%A7%80%EA%B8%88-%EA%B3%A0%EC%A0%95%EA%B8%88%EB%A6%AC%EB%A1%9C-%EA%B0%88%EC%95%84%ED%83%80%EB%8A%94-%EA%B2%8C-%EC%9C%A0%EB%A6%AC%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"지금 고정금리로 갈아타는 게 유리한가요?에 대한 직접 링크\" title=\"지금 고정금리로 갈아타는 게 유리한가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>개인의 대출 잔액, 남은 기간, 중도상환수수료, 앞으로의 금리 경로에 따라 답이 달라집니다. 금리가 더 오를지 내릴지는 누구도 확정할 수 없으므로, 갈아타기 비용과 금리 1%p 상승·하락 시 월 상환액 차이를 함께 계산해 보고 결정하는 것이 좋습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리가-오르면-아파트-가격은-반드시-떨어지나요\">금리가 오르면 아파트 가격은 반드시 떨어지나요?<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EA%B8%88%EB%A6%AC%EA%B0%80-%EC%98%A4%EB%A5%B4%EB%A9%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EC%9D%80-%EB%B0%98%EB%93%9C%EC%8B%9C-%EB%96%A8%EC%96%B4%EC%A7%80%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"금리가 오르면 아파트 가격은 반드시 떨어지나요?에 대한 직접 링크\" title=\"금리가 오르면 아파트 가격은 반드시 떨어지나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>금리 상승은 하방 압력이지만 공급, 전세가율, 소득, 정책에 따라 지역과 단지별 반응이 다릅니다. 거래량이 먼저 줄고 가격은 시차를 두고 움직이는 경우가 많아, 금리 뉴스와 실제 거래 흐름을 함께 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.bloomberg.com/news/articles/2026-09-29/us-30-year-treasury-yield-approaches-highest-level-since-2002\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Bloomberg — US 30-Year Treasury Yield Rises to Highest Level Since 2002 (2026-09-29)</a></li>\n<li class=\"\"><a href=\"https://www.cnbc.com/2026/10/02/treasury-yields-bonds-nonfarm-payrolls.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">CNBC — 10-year Treasury yield ticks higher despite weaker-than-expected jobs report (2026-10-02)</a></li>\n<li class=\"\"><a href=\"https://www.cnbc.com/2026/09/16/fed-rate-decision-september-2026.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">CNBC — Fed rate decision September 2026 (2026-09-16)</a></li>\n<li class=\"\"><a href=\"https://www.mt.co.kr/economy/2026/08/27/2026082709050770978\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">머니투데이 — 한은, 기준금리 3% 두 달 연속 인상 (2026-08-27)</a></li>\n<li class=\"\"><a href=\"https://m.inews24.com/v/2010449\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아이뉴스24 — 은행 주담대 금리 연 4.66%, 3년 9개월 만에 최고치</a></li>\n<li class=\"\"><a href=\"https://ecos.bok.or.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국은행 경제통계시스템 ECOS</a></li>\n</ul>\n<blockquote>\n<p>이 글은 공개 보도와 통계를 바탕으로 금리 변화의 전달 경로를 설명한 참고 자료이며, 특정 대출 상품이나 아파트의 매수·매도를 권유하지 않습니다. 금리와 가격 전망은 오차가 있을 수 있고 수익을 보장하지 않으므로, 실제 결정 전에는 금융기관 조건과 공식 자료를 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/us-long-bond-yield-surge-mortgage-rate",
            "title": "미국 30년물 금리 2002년 이후 최고… 왜 내 주담대 금리까지 오를까",
            "summary": "미국 30년 만기 국채금리가 2000년대 초반 이후 최고 수준까지 오르면서 국내 주택담보대출 금리도 3년 9개월 만에 최고치를 기록했습니다. 미국 장기금리가 한국 아파트 대출이자와 매수 수요로 이어지는 경로를 정리합니다.",
            "date_modified": "2026-10-03T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "금융·세금",
                "아파트"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-app-guest-mode",
            "content_html": "<p>아파트 시세 앱을 설치했는데 첫 화면부터 회원가입을 요구하면, “그냥 우리 아파트 하나만 보고 싶은데”라는 생각이 들기 마련입니다. 관심 단지 하나의 시세와 앞으로의 흐름을 가볍게 확인하는 데 계정까지 만들 필요는 없습니다.</p>\n<p>이 글은 로그인 없이 아파트 앱에서 관심 단지의 시세와 전망을 확인하는 흐름을 정리합니다. 무엇을 고르면 되는지, 어떤 정보가 보이는지, 그리고 어떤 경우에 로그인이 필요한지를 순서대로 살펴봅니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"로그인-없이-보는-방식이-맞는-사람\">로그인 없이 보는 방식이 맞는 사람<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%86%EC%9D%B4-%EB%B3%B4%EB%8A%94-%EB%B0%A9%EC%8B%9D%EC%9D%B4-%EB%A7%9E%EB%8A%94-%EC%82%AC%EB%9E%8C\" class=\"hash-link\" aria-label=\"로그인 없이 보는 방식이 맞는 사람에 대한 직접 링크\" title=\"로그인 없이 보는 방식이 맞는 사람에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음 상황이라면 로그인 없는 이용 방식으로 충분합니다.</p>\n<ul>\n<li class=\"\">지금 사는 집이나 관심 있는 <strong>단지 한 곳</strong>의 시세가 궁금할 때</li>\n<li class=\"\">이사·갈아타기를 고민 중인데 <strong>특정 시점</strong>의 가격 흐름을 가볍게 보고 싶을 때</li>\n<li class=\"\">앱이 내 질문에 맞는지 먼저 써 보고, 필요하면 나중에 가입하고 싶을 때</li>\n</ul>\n<p>반대로 여러 단지를 저장해 비교하거나, 금리·세금 같은 조건을 바꿔 가며 시나리오를 돌려 보거나, 전망이 바뀔 때 알림을 받고 싶다면 로그인 후 기능이 더 맞습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"고르는-것은-세-가지뿐입니다\">고르는 것은 세 가지뿐입니다<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EA%B3%A0%EB%A5%B4%EB%8A%94-%EA%B2%83%EC%9D%80-%EC%84%B8-%EA%B0%80%EC%A7%80%EB%BF%90%EC%9E%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"고르는 것은 세 가지뿐입니다에 대한 직접 링크\" title=\"고르는 것은 세 가지뿐입니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>로그인 없는 이용 방식의 핵심은 선택지를 줄이는 것입니다. 앱에서 다음 세 가지만 고르면 됩니다.</p>\n<table><thead><tr><th>선택</th><th>의미</th><th>고를 때 확인할 점</th></tr></thead><tbody><tr><td>아파트 1곳</td><td>시세와 전망을 확인할 단지</td><td>같은 이름의 단지가 있으면 지역과 준공 연도를 맞춰 봅니다.</td></tr><tr><td>평형 1개</td><td>비교 기준이 되는 면적</td><td>실제 관심 있는 전용면적과 같은지 확인합니다.</td></tr><tr><td>목표 월 1개</td><td>가격을 확인하고 싶은 시점</td><td>이사·매수·매도 계획과 맞는 달을 고릅니다.</td></tr></tbody></table>\n<p>목표 월을 고르는 이유는 “1년 뒤”라는 막연한 기준보다 <strong>내 계획과 맞는 시점</strong>의 가격을 보기 위해서입니다. 다만 목표 월이 멀어질수록 금리·공급·정책이 바뀔 시간도 길어지므로 예상 범위가 넓어질 수 있습니다. 기간에 따라 결과를 어떻게 읽는지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 아파트 전망 비교하기</a>에서 다뤘습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"화면은-두-개-전망과-내-아파트\">화면은 두 개: 전망과 내 아파트<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%ED%99%94%EB%A9%B4%EC%9D%80-%EB%91%90-%EA%B0%9C-%EC%A0%84%EB%A7%9D%EA%B3%BC-%EB%82%B4-%EC%95%84%ED%8C%8C%ED%8A%B8\" class=\"hash-link\" aria-label=\"화면은 두 개: 전망과 내 아파트에 대한 직접 링크\" title=\"화면은 두 개: 전망과 내 아파트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>선택을 마치면 두 화면을 오가며 정보를 확인합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"전망-화면\">전망 화면<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%A0%84%EB%A7%9D-%ED%99%94%EB%A9%B4\" class=\"hash-link\" aria-label=\"전망 화면에 대한 직접 링크\" title=\"전망 화면에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>대표 시세</strong>: 선택한 평형의 최근 유효 거래를 바탕으로 한 기준값</li>\n<li class=\"\"><strong>목표 월 전망</strong>: 고른 시점의 예상 가격과 예상 범위</li>\n<li class=\"\"><strong>최근 실거래</strong>: 기준월을 포함한 최근 12개월 거래 목록과 흐름 차트</li>\n</ul>\n<p>차트에서 궁금한 거래를 짚으면 그 거래의 시점과 가격이 강조되어 표시됩니다. 거래 하나하나를 읽기 전에 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만 믿으면 위험한 이유</a>를 한 번 읽어 두면 해석이 훨씬 쉬워집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"내-아파트-화면\">내 아파트 화면<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EB%82%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%ED%99%94%EB%A9%B4\" class=\"hash-link\" aria-label=\"내 아파트 화면에 대한 직접 링크\" title=\"내 아파트 화면에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">교통·학군·생활 인프라 같은 <strong>입지 정보</strong></li>\n<li class=\"\">금리·환율 같은 <strong>시장 지표와 기준일</strong></li>\n</ul>\n<p>입지와 시장 지표는 가격 전망을 해석할 때의 배경 정보입니다. 지표마다 갱신 주기가 다르므로 값 옆의 기준일을 함께 보는 습관을 들이세요. 기준일을 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">예측 결과의 기준일·시장 정보·표본 신뢰도 읽는 법</a>에 정리했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"선택은-내-기기에만-저장됩니다\">선택은 내 기기에만 저장됩니다<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%84%A0%ED%83%9D%EC%9D%80-%EB%82%B4-%EA%B8%B0%EA%B8%B0%EC%97%90%EB%A7%8C-%EC%A0%80%EC%9E%A5%EB%90%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"선택은 내 기기에만 저장됩니다에 대한 직접 링크\" title=\"선택은 내 기기에만 저장됩니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>로그인 없이 이용할 때는 서버에 계정을 만들지 않습니다. 고른 단지·평형·목표 월은 <strong>휴대폰 안에만 저장</strong>되고, 같은 앱을 다시 열면 이어서 볼 수 있습니다.</p>\n<p>그래서 다음 경우에는 선택이 사라질 수 있습니다.</p>\n<ul>\n<li class=\"\">앱을 삭제했다가 다시 설치한 경우</li>\n<li class=\"\">앱 데이터를 초기화한 경우</li>\n<li class=\"\">다른 기기로 바꾼 경우</li>\n</ul>\n<p>계속 같은 단지를 추적하고 싶다면 로그인해 두는 편이 안전합니다. 로그인하면 기기에 저장된 선택을 회원 계정으로 이어서 사용할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"웹-체험앱-비회원회원-기능-비교\">웹 체험·앱 비회원·회원 기능 비교<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%9B%B9-%EC%B2%B4%ED%97%98%EC%95%B1-%EB%B9%84%ED%9A%8C%EC%9B%90%ED%9A%8C%EC%9B%90-%EA%B8%B0%EB%8A%A5-%EB%B9%84%EA%B5%90\" class=\"hash-link\" aria-label=\"웹 체험·앱 비회원·회원 기능 비교에 대한 직접 링크\" title=\"웹 체험·앱 비회원·회원 기능 비교에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>같은 서비스라도 이용 방식에 따라 볼 수 있는 범위가 다릅니다.</p>\n<table><thead><tr><th>구분</th><th>웹 가입 없는 체험</th><th>앱 로그인 없이</th><th>앱·웹 회원</th></tr></thead><tbody><tr><td>이용 방법</td><td>브라우저에서 단지 검색</td><td>앱에서 단지·평형·목표 월 선택</td><td>로그인 후 관심 단지 등록</td></tr><tr><td>가격 전망</td><td>1년 뒤 예상 범위</td><td>고른 목표 월의 전망</td><td>여러 시점·조건별 시나리오 비교</td></tr><tr><td>실거래</td><td>대표 시세 중심</td><td>최근 12개월 거래와 흐름</td><td>매매·전세 흐름, 평형별 분석</td></tr><tr><td>저장</td><td>저장하지 않음</td><td>내 기기에만 저장</td><td>계정에 저장, 여러 기기에서 이용</td></tr><tr><td>추적·알림</td><td>없음</td><td>없음</td><td>예측 변경 이력과 알림</td></tr></tbody></table>\n<p>처음에는 웹이나 앱에서 로그인 없이 써 보고, 관심 단지가 두 곳 이상으로 늘어나거나 조건을 바꿔 비교하고 싶을 때 가입을 검토하는 순서가 자연스럽습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과를-읽을-때-지킬-것\">결과를 읽을 때 지킬 것<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EC%9D%BD%EC%9D%84-%EB%95%8C-%EC%A7%80%ED%82%AC-%EA%B2%83\" class=\"hash-link\" aria-label=\"결과를 읽을 때 지킬 것에 대한 직접 링크\" title=\"결과를 읽을 때 지킬 것에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>로그인 여부와 상관없이 가격 전망은 <strong>확정 가격이 아닙니다</strong>. 다음 세 가지는 꼭 함께 확인하세요.</p>\n<ol>\n<li class=\"\"><strong>평형이 맞는지</strong>: 다른 면적의 결과를 내 집 가격으로 읽고 있지 않은지 확인합니다.</li>\n<li class=\"\"><strong>범위의 폭</strong>: 가운데 값 하나보다 아래·위 값과 폭을 함께 봅니다. 자세한 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위 읽는 법</a>을 참고하세요.</li>\n<li class=\"\"><strong>기준일</strong>: 언제 계산된 결과인지 기록해 두면, 나중에 숫자가 바뀌었을 때 이유를 추적하기 쉽습니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"로그인-없이-쓰면-개인정보가-저장되나요\">로그인 없이 쓰면 개인정보가 저장되나요?<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%86%EC%9D%B4-%EC%93%B0%EB%A9%B4-%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EA%B0%80-%EC%A0%80%EC%9E%A5%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"로그인 없이 쓰면 개인정보가 저장되나요?에 대한 직접 링크\" title=\"로그인 없이 쓰면 개인정보가 저장되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>로그인 없이 이용할 때는 계정을 만들지 않고, 고른 단지·평형·목표 월만 기기에 저장합니다. 화면을 이용하는 과정에서 자동 입력 방지 확인이 나타날 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"단지를-여러-개-저장할-수는-없나요\">단지를 여러 개 저장할 수는 없나요?<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EB%8B%A8%EC%A7%80%EB%A5%BC-%EC%97%AC%EB%9F%AC-%EA%B0%9C-%EC%A0%80%EC%9E%A5%ED%95%A0-%EC%88%98%EB%8A%94-%EC%97%86%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"단지를 여러 개 저장할 수는 없나요?에 대한 직접 링크\" title=\"단지를 여러 개 저장할 수는 없나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>로그인 없는 이용 방식은 단지 하나에 집중하도록 설계되어 있습니다. 여러 단지를 저장하고 비교하려면 로그인 후 관심 단지로 등록해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"검색한-단지의-자료가-아직-준비-중이라고-나와요\">검색한 단지의 자료가 아직 준비 중이라고 나와요.<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EA%B2%80%EC%83%89%ED%95%9C-%EB%8B%A8%EC%A7%80%EC%9D%98-%EC%9E%90%EB%A3%8C%EA%B0%80-%EC%95%84%EC%A7%81-%EC%A4%80%EB%B9%84-%EC%A4%91%EC%9D%B4%EB%9D%BC%EA%B3%A0-%EB%82%98%EC%99%80%EC%9A%94\" class=\"hash-link\" aria-label=\"검색한 단지의 자료가 아직 준비 중이라고 나와요.에 대한 직접 링크\" title=\"검색한 단지의 자료가 아직 준비 중이라고 나와요.에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>모든 단지의 자료가 항상 준비되어 있지는 않습니다. 자료가 준비되지 않은 단지에 다른 단지의 숫자를 대신 보여주지 않기 때문에, 준비가 끝날 때까지 기다리거나 다른 단지를 먼저 둘러볼 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"웹에서-본-결과와-앱-결과가-다르면-어느-쪽이-맞나요\">웹에서 본 결과와 앱 결과가 다르면 어느 쪽이 맞나요?<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%9B%B9%EC%97%90%EC%84%9C-%EB%B3%B8-%EA%B2%B0%EA%B3%BC%EC%99%80-%EC%95%B1-%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%8B%A4%EB%A5%B4%EB%A9%B4-%EC%96%B4%EB%8A%90-%EC%AA%BD%EC%9D%B4-%EB%A7%9E%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"웹에서 본 결과와 앱 결과가 다르면 어느 쪽이 맞나요?에 대한 직접 링크\" title=\"웹에서 본 결과와 앱 결과가 다르면 어느 쪽이 맞나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저 평형과 목표 시점이 같은지 확인하세요. 웹 체험은 1년 뒤를, 앱은 내가 고른 목표 월을 기준으로 보여주므로 시점이 다르면 숫자도 달라집니다. 같은 조건이라면 기준일 차이도 함께 확인해 보세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"앱에서-바로-확인하기\">앱에서 바로 확인하기<a href=\"https://alvin.ing/blog/apartment-app-guest-mode#%EC%95%B1%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"앱에서 바로 확인하기에 대한 직접 링크\" title=\"앱에서 바로 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 인사이트 앱은 <a href=\"https://apps.apple.com/kr/app/id6785690190\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">App Store</a>와 <a href=\"https://play.google.com/store/apps/details?id=com.aptinsights.twa\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Google Play</a>에서 받을 수 있습니다. 앱을 열고 로그인 없이 시작하면 단지·평형·목표 월을 고르는 화면으로 이어집니다.</p>\n<p>설치 없이 먼저 보고 싶다면 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">웹에서 가입 없이 아파트 가격 확인하기</a>를, 최근 거래부터 보고 싶다면 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>를 이용해 보세요. 웹 체험의 이용 순서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a>에 자세히 정리했습니다.</p>\n<blockquote>\n<p>아파트 인사이트의 가격 전망은 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석입니다. 예측값과 가격 범위는 실제 결과와 다를 수 있으며 가격·거래 가능성·수익을 보장하지 않습니다. 투자 권유·투자 자문·매수·매도 추천이 아니며, 최종 판단과 책임은 이용자에게 있습니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-app-guest-mode",
            "title": "로그인 없이 아파트 시세 앱 쓰는 법: 단지·평형·목표 월 하나로 전망 보기",
            "summary": "회원가입이나 로그인 없이 아파트 앱에서 관심 단지의 대표 시세와 목표 월 전망, 최근 실거래와 입지 정보를 확인하는 방법과 웹 체험·회원 기능과의 차이를 정리합니다.",
            "date_modified": "2026-10-02T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest",
            "content_html": "<p>아파트 가격을 예측해 준다는 서비스는 많지만, “그래서 얼마나 맞았나요?”에 답하는 곳은 많지 않습니다. 답하더라도 “정확도 95%”처럼 무엇을 어떻게 잰 것인지 알 수 없는 숫자 하나만 보여주는 경우가 대부분입니다.</p>\n<p>이 글은 아파트 가격 예측의 정확도를 스스로 판단할 수 있도록 <strong>백테스트가 무엇인지, 오차율 지표는 어떻게 읽는지, 좋아 보이는 숫자에 속지 않으려면 무엇을 확인해야 하는지</strong> 정리합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"정확도를-묻기-전에-고정해야-할-두-가지\">정확도를 묻기 전에 고정해야 할 두 가지<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%A0%95%ED%99%95%EB%8F%84%EB%A5%BC-%EB%AC%BB%EA%B8%B0-%EC%A0%84%EC%97%90-%EA%B3%A0%EC%A0%95%ED%95%B4%EC%95%BC-%ED%95%A0-%EB%91%90-%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"정확도를 묻기 전에 고정해야 할 두 가지에 대한 직접 링크\" title=\"정확도를 묻기 전에 고정해야 할 두 가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>예측이 맞았는지 따지려면 먼저 두 가지를 고정해야 합니다.</p>\n<ol>\n<li class=\"\"><strong>무엇을 예측했는가</strong>: 어느 단지의 어느 평형을, 언제 기준으로, 몇 개월 뒤 가격을 예측했는지</li>\n<li class=\"\"><strong>실제값은 무엇인가</strong>: 그 시점 이후 실제로 신고된 거래 중 어떤 거래와 비교했는지</li>\n</ol>\n<p>이 두 가지가 빠진 정확도 숫자는 비교할 수 없습니다. “서울 아파트 평균 상승률을 맞혔다”와 “특정 단지 84㎡의 1년 뒤 거래가를 맞혔다”는 전혀 다른 난이도의 질문이기 때문입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"백테스트-과거로-돌아가-다시-예측해-보기\">백테스트: 과거로 돌아가 다시 예측해 보기<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EB%B0%B1%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B3%BC%EA%B1%B0%EB%A1%9C-%EB%8F%8C%EC%95%84%EA%B0%80-%EB%8B%A4%EC%8B%9C-%EC%98%88%EC%B8%A1%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"백테스트: 과거로 돌아가 다시 예측해 보기에 대한 직접 링크\" title=\"백테스트: 과거로 돌아가 다시 예측해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>백테스트는 <strong>과거의 특정 날짜로 돌아가, 그 시점에 알 수 있었던 정보만으로 미래를 예측한 뒤, 이후 실제 거래와 비교하는 방법</strong>입니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">기준일: 2024년 9월</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> ├─ 이 날짜까지의 실거래·시장 지표만 사용해 1년 뒤 가격을 예측</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> └─ 2025년 9월 전후의 실제 신고 거래와 비교 → 오차 계산</span><br></div></code></pre></div></div>\n<p>여기서 가장 중요한 원칙은 <strong>기준일 이후의 정보를 섞지 않는 것</strong>입니다. 나중에 알게 된 금리나 거래를 과거 예측에 몰래 넣으면 결과는 훨씬 좋아 보이지만, 실제로 그 시점에 쓸 수 있었던 예측의 실력은 아닙니다. 이를 흔히 “미래 정보 누수”라고 부릅니다.</p>\n<p>백테스트 결과를 볼 때는 다음을 확인하세요.</p>\n<ul>\n<li class=\"\">기준일 당시 <strong>실제로 이용할 수 있었던 자료만</strong> 썼다고 밝히는가</li>\n<li class=\"\">비교한 실제 거래의 <strong>표본 수</strong>가 얼마인가</li>\n<li class=\"\"><strong>어느 기간</strong>을 검증했는가 (상승기만 골랐는지, 하락기도 포함했는지)</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"오차율-지표-세-가지-읽는-법\">오차율 지표 세 가지 읽는 법<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%98%A4%EC%B0%A8%EC%9C%A8-%EC%A7%80%ED%91%9C-%EC%84%B8-%EA%B0%80%EC%A7%80-%EC%9D%BD%EB%8A%94-%EB%B2%95\" class=\"hash-link\" aria-label=\"오차율 지표 세 가지 읽는 법에 대한 직접 링크\" title=\"오차율 지표 세 가지 읽는 법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>예측 정확도는 보통 몇 가지 오차 지표로 표현합니다. 각 지표가 답하는 질문이 다릅니다.</p>\n<table><thead><tr><th>지표</th><th>쉬운 뜻</th><th>읽을 때 주의할 점</th></tr></thead><tbody><tr><td>평균 오차율 (MAPE)</td><td>예측 가격과 실제 가격이 평균적으로 몇 % 차이 났나</td><td>일부 큰 오차가 평균을 끌어올릴 수 있습니다.</td></tr><tr><td>중간 오차율 (MedAE)</td><td>오차를 크기순으로 세웠을 때 가운데 값</td><td>큰 오차 몇 건에 덜 흔들리는 대표 오차입니다.</td></tr><tr><td>예상 범위 적중률</td><td>실제 거래 가격이 예상 범위 안에 들어온 비율</td><td>범위가 넓을수록 쉽게 높아집니다. 범위의 폭과 함께 봐야 합니다.</td></tr></tbody></table>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"평균-오차율-예시\">평균 오차율 예시<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%ED%8F%89%EA%B7%A0-%EC%98%A4%EC%B0%A8%EC%9C%A8-%EC%98%88%EC%8B%9C\" class=\"hash-link\" aria-label=\"평균 오차율 예시에 대한 직접 링크\" title=\"평균 오차율 예시에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>10억 원으로 예측한 단지가 실제로 10억 5,000만 원에 거래됐다면 오차율은 약 4.8%입니다. 이런 오차를 여러 단지에서 구해 평균을 낸 것이 평균 오차율입니다. 평균 오차율이 6%라면 “대체로 실제 가격과 6% 안팎의 차이가 났다”고 읽을 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위-적중률은-높을수록-좋은가\">범위 적중률은 높을수록 좋은가?<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EB%B2%94%EC%9C%84-%EC%A0%81%EC%A4%91%EB%A5%A0%EC%9D%80-%EB%86%92%EC%9D%84%EC%88%98%EB%A1%9D-%EC%A2%8B%EC%9D%80%EA%B0%80\" class=\"hash-link\" aria-label=\"범위 적중률은 높을수록 좋은가?에 대한 직접 링크\" title=\"범위 적중률은 높을수록 좋은가?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>꼭 그렇지는 않습니다. 이 부분이 가장 많이 오해받는 지점입니다.</p>\n<ul>\n<li class=\"\">예상 범위를 <strong>가운데 50%</strong> 구간으로 만들었다면, 잘 만든 범위일수록 실제 가격이 그 안에 들어오는 비율도 <strong>50% 안팎</strong>이어야 합니다.</li>\n<li class=\"\">적중률이 90%라면 범위를 지나치게 넓게 잡았을 가능성이 있습니다. “5억~20억 사이”라고 말하면 거의 항상 맞지만 아무 도움이 되지 않는 것과 같습니다.</li>\n<li class=\"\">반대로 적중률이 20%라면 범위가 너무 좁거나 가운데 값이 한쪽으로 치우쳤을 수 있습니다.</li>\n</ul>\n<p>그래서 범위 적중률은 <strong>범위가 몇 % 구간인지, 범위의 폭은 얼마인지</strong>와 함께 읽어야 의미가 있습니다. 예상 범위 자체를 읽는 법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값 해석하기</a>에서 다뤘습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"좋아-보이는-숫자에-속지-않는-체크리스트\">좋아 보이는 숫자에 속지 않는 체크리스트<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%A2%8B%EC%95%84-%EB%B3%B4%EC%9D%B4%EB%8A%94-%EC%88%AB%EC%9E%90%EC%97%90-%EC%86%8D%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"좋아 보이는 숫자에 속지 않는 체크리스트에 대한 직접 링크\" title=\"좋아 보이는 숫자에 속지 않는 체크리스트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>정확도 숫자를 보면 다음 질문을 하나씩 던져 보세요.</p>\n<ol>\n<li class=\"\"><strong>잘 맞은 사례만 고른 것은 아닌가?</strong> 성공 사례 몇 개만 보여주는 것은 정확도가 아니라 홍보입니다. 무작위로 고른 단지, 또는 오차가 가운데인 사례를 공개하는지 확인하세요.</li>\n<li class=\"\"><strong>표본 수는 충분한가?</strong> 10건으로 낸 평균 오차율과 3,000건으로 낸 평균 오차율은 신뢰도가 다릅니다.</li>\n<li class=\"\"><strong>어떤 시기를 검증했는가?</strong> 모두가 오르던 시기에는 “오른다”만 말해도 잘 맞아 보입니다. 하락기와 급등기를 따로 확인했는지 보세요.</li>\n<li class=\"\"><strong>학습에 쓴 자료로 다시 채점한 것은 아닌가?</strong> 모델을 만들 때 쓴 데이터로 다시 평가하면 점수가 높게 나옵니다. 학습에 쓰지 않은 단지나 기간에서 따로 검증했는지 확인하세요.</li>\n<li class=\"\"><strong>지표의 단위가 명확한가?</strong> 가격 오차(%)인지, 변동률 오차(%p)인지, 금액 오차(원)인지에 따라 같은 숫자도 의미가 완전히 다릅니다.</li>\n<li class=\"\"><strong>한계를 함께 밝히는가?</strong> 어떤 검증도 미래를 보장하지 않습니다. 검증 방식의 한계를 스스로 적어 두는 곳이 오히려 믿을 만합니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"실제-공개-사례로-읽어-보기\">실제 공개 사례로 읽어 보기<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%8B%A4%EC%A0%9C-%EA%B3%B5%EA%B0%9C-%EC%82%AC%EB%A1%80%EB%A1%9C-%EC%9D%BD%EC%96%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"실제 공개 사례로 읽어 보기에 대한 직접 링크\" title=\"실제 공개 사례로 읽어 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 인사이트는 검증 방법과 수치를 <a href=\"https://apt-insights.com/guides/backtest-validation\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공식 검증 가이드</a>에 공개하고 있습니다. 글 작성 시점(2026년 10월) 기준으로 공개된 내용을 위 체크리스트에 맞춰 읽어 보면 다음과 같습니다.</p>\n<table><thead><tr><th>체크 항목</th><th>공개된 내용</th></tr></thead><tbody><tr><td>지표와 값</td><td>12개월 가격 평균 오차율 5.98%, 결정계수(R²) 0.630, 변동률 오차 7.94%p</td></tr><tr><td>표본</td><td>결정계수·변동률 오차는 과거 평가 3,228건, 12개월 가격 오차율은 별도 120건</td></tr><tr><td>단위 구분</td><td>변동률 오차는 가격 변동률의 %p 오차이며 금액 오차가 아니라고 명시</td></tr><tr><td>사례 선정</td><td>무작위로 고른 5개 단지 중 가장 잘 맞은 사례가 아니라 오차가 가운데인 결과를 공개</td></tr><tr><td>시기</td><td>안정기뿐 아니라 급등기·금리 충격 하락기를 별도로 확인</td></tr><tr><td>한계</td><td>검증 결과가 미래 가격이나 수익을 보장하지 않으며 최대 오차 보장값이 아니라고 명시</td></tr></tbody></table>\n<p>이 표를 “정확하다/부정확하다”로 판정하자는 것이 아닙니다. 어떤 서비스를 보든 <strong>이 정도 수준의 정보가 공개되어 있어야 숫자를 비교할 수 있다</strong>는 기준으로 활용하세요. 수치는 모델이 바뀌면 달라질 수 있으므로 최신 값은 공식 페이지에서 다시 확인하는 것이 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"내-관심-단지에-적용할-때\">내 관심 단지에 적용할 때<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EB%82%B4-%EA%B4%80%EC%8B%AC-%EB%8B%A8%EC%A7%80%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%A0-%EB%95%8C\" class=\"hash-link\" aria-label=\"내 관심 단지에 적용할 때에 대한 직접 링크\" title=\"내 관심 단지에 적용할 때에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>전체 평균 오차율이 낮아도 내 관심 단지의 결과가 꼭 그만큼 정확한 것은 아닙니다. 개별 단지 결과를 볼 때는 다음을 추가로 확인하세요.</p>\n<ul>\n<li class=\"\"><strong>거래 표본</strong>: 최근 거래가 드문 단지는 오차가 커질 수 있습니다. 결과 화면의 표본 신뢰도를 확인하세요.</li>\n<li class=\"\"><strong>평형</strong>: 거래가 많은 평형과 적은 평형은 결과의 안정성이 다릅니다.</li>\n<li class=\"\"><strong>특수한 거래</strong>: 분양권·손피 거래가 섞인 신축 단지는 가격 기준 자체가 흔들릴 수 있습니다. <a class=\"\" href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference\">일반 매매와 분양권 실거래가 차이</a>를 참고하세요.</li>\n<li class=\"\"><strong>기준일</strong>: 언제 계산된 결과인지 기록해 두면 나중에 실제 거래와 직접 비교해 볼 수 있습니다. 기록 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">기준일·시장 정보·표본 신뢰도 읽는 법</a>에 정리했습니다.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"평균-오차율-6면-정확한-편인가요\">평균 오차율 6%면 정확한 편인가요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%ED%8F%89%EA%B7%A0-%EC%98%A4%EC%B0%A8%EC%9C%A8-6%EB%A9%B4-%EC%A0%95%ED%99%95%ED%95%9C-%ED%8E%B8%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"평균 오차율 6%면 정확한 편인가요?에 대한 직접 링크\" title=\"평균 오차율 6%면 정확한 편인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>비교 기준에 따라 다릅니다. 1년 뒤 개별 단지 가격을 예측했는지, 지역 평균을 예측했는지에 따라 같은 6%의 의미가 달라집니다. 10억 원 아파트라면 6%는 6,000만 원이므로, 계약 판단에서는 결코 작은 차이가 아닙니다. 그래서 가운데 값 하나보다 예상 범위를 함께 봐야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"백테스트-성적이-좋으면-앞으로도-잘-맞나요\">백테스트 성적이 좋으면 앞으로도 잘 맞나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EB%B0%B1%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%84%B1%EC%A0%81%EC%9D%B4-%EC%A2%8B%EC%9C%BC%EB%A9%B4-%EC%95%9E%EC%9C%BC%EB%A1%9C%EB%8F%84-%EC%9E%98-%EB%A7%9E%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"백테스트 성적이 좋으면 앞으로도 잘 맞나요?에 대한 직접 링크\" title=\"백테스트 성적이 좋으면 앞으로도 잘 맞나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>보장되지 않습니다. 백테스트는 과거의 시장 환경에서 검증한 결과이며, 금리·정책·공급 환경이 크게 달라지면 성능도 달라질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예측이-틀렸다는-건-어떻게-확인하나요\">예측이 틀렸다는 건 어떻게 확인하나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%98%88%EC%B8%A1%EC%9D%B4-%ED%8B%80%EB%A0%B8%EB%8B%A4%EB%8A%94-%EA%B1%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%99%95%EC%9D%B8%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"예측이 틀렸다는 건 어떻게 확인하나요?에 대한 직접 링크\" title=\"예측이 틀렸다는 건 어떻게 확인하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>예측을 확인한 날짜와 결과(가운데 값, 범위)를 기록해 두고, 목표 시점 이후 같은 평형의 실제 거래와 비교해 보세요. 실제 거래가 범위 안에 들어왔는지, 가운데 값과 몇 % 차이 났는지를 직접 계산할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"직접-비교해-보기\">직접 비교해 보기<a href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest#%EC%A7%81%EC%A0%91-%EB%B9%84%EA%B5%90%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"직접 비교해 보기에 대한 직접 링크\" title=\"직접 비교해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>관심 단지의 대표 시세와 1년 뒤 예상 범위는 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">가입 없이 아파트 가격 확인하기</a>에서, 비교 기준이 되는 최근 거래는 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>에서 확인할 수 있습니다. 결과를 처음 읽는다면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a>부터 읽어 보세요.</p>\n<blockquote>\n<p>이 글의 수치는 작성 시점에 공개된 자료를 인용한 것이며 이후 달라질 수 있습니다. 아파트 가격 예측은 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석이며, 가격·거래 가능성·수익을 보장하지 않습니다. 투자 권유·투자 자문·매수·매도 추천이 아닙니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest",
            "title": "아파트 가격 예측, 맞았는지 확인하는 법: 백테스트와 오차율 읽기",
            "summary": "아파트 가격 예측의 정확도를 판단할 때 백테스트, 평균 오차율(MAPE), 중간 오차율, 예상 범위 적중률을 어떻게 읽어야 하는지와 좋아 보이는 숫자에 속지 않는 체크리스트를 정리합니다.",
            "date_modified": "2026-10-02T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-real-transaction-price-by-region",
            "content_html": "<p>“우리 동네 아파트가 요즘 얼마에 거래되나요?”라는 질문에는 생각보다 많은 조건이 숨어 있습니다. 같은 구 안에서도 단지마다 가격대가 다르고, 같은 단지 안에서도 59㎡와 84㎡는 전혀 다른 시장입니다. 그래서 실거래가는 <strong>지역 → 단지 → 평형</strong> 순서로 좁혀서 봐야 숫자가 흔들리지 않습니다.</p>\n<p>이 글은 지역별 아파트 실거래가를 조회할 때 어떤 순서로 범위를 좁히고, 단지 화면에서 어떤 숫자를 먼저 읽어야 하는지 정리합니다. 마지막에는 국토교통부 공개자료와 대조하는 방법도 함께 다룹니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"실거래가-조회-전에-알아-둘-세-가지\">실거래가 조회 전에 알아 둘 세 가지<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80-%EC%A1%B0%ED%9A%8C-%EC%A0%84%EC%97%90-%EC%95%8C%EC%95%84-%EB%91%98-%EC%84%B8-%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"실거래가 조회 전에 알아 둘 세 가지에 대한 직접 링크\" title=\"실거래가 조회 전에 알아 둘 세 가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>실거래가는 “지금 이 집의 가격”이 아니라 <strong>이미 계약된 거래의 기록</strong>입니다. 조회 화면을 열기 전에 다음 세 가지를 알고 있으면 숫자를 오해할 가능성이 크게 줄어듭니다.</p>\n<table><thead><tr><th>알아 둘 점</th><th>이유</th></tr></thead><tbody><tr><td>신고까지 시간 차이가 있다</td><td>아파트 매매 거래는 계약일로부터 30일 이내에 신고하므로, 최근 한 달 거래는 아직 덜 쌓였을 수 있습니다.</td></tr><tr><td>거래 한 건은 조건이 제각각이다</td><td>층·향·타입·수리 상태·직거래 여부에 따라 같은 평형도 가격 차이가 납니다.</td></tr><tr><td>해제·정정되는 거래가 있다</td><td>신고 후 계약이 해제되면 기록에 해제 표시가 붙습니다. 해제 거래를 시세로 읽으면 안 됩니다.</td></tr></tbody></table>\n<p>그래서 실거래가를 볼 때는 “가장 최근 한 건”보다 <strong>같은 평형에서 최근 1년 동안 어떤 범위로 거래됐는지</strong>를 먼저 보는 편이 안전합니다. 한 건의 거래가 왜 시세를 대표하지 못하는지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a>에서 자세히 설명했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1단계-시군구를-먼저-고릅니다\">1단계: 시군구를 먼저 고릅니다<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#1%EB%8B%A8%EA%B3%84-%EC%8B%9C%EA%B5%B0%EA%B5%AC%EB%A5%BC-%EB%A8%BC%EC%A0%80-%EA%B3%A0%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"1단계: 시군구를 먼저 고릅니다에 대한 직접 링크\" title=\"1단계: 시군구를 먼저 고릅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지명을 바로 검색하면 같은 이름의 단지가 여러 지역에서 함께 나옵니다. “래미안”, “자이”, “센트럴”처럼 흔한 브랜드명은 물론이고, 같은 구 안에도 이름이 비슷한 단지가 여러 개 있을 수 있습니다.</p>\n<p>시군구를 먼저 고르면 다음 장점이 있습니다.</p>\n<ul>\n<li class=\"\">같은 이름의 다른 지역 단지를 실수로 고를 가능성이 줄어듭니다.</li>\n<li class=\"\">해당 지역에 실거래가 꾸준한 단지가 어떤 곳인지 한눈에 볼 수 있습니다.</li>\n<li class=\"\">관심 단지와 같은 생활권의 비교 단지를 함께 찾을 수 있습니다.</li>\n</ul>\n<p>같은 시군구에 이름이 같은 단지가 두 곳 이상 있다면 준공 연도와 지번을 함께 확인하세요. 예를 들어 “1989년 준공 · ○○동 720”처럼 지번까지 맞춰 보면 다른 단지와 섞일 일이 없습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2단계-단지-화면에서-대표-시세와-거래-범위를-읽습니다\">2단계: 단지 화면에서 대표 시세와 거래 범위를 읽습니다<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#2%EB%8B%A8%EA%B3%84-%EB%8B%A8%EC%A7%80-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C-%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EC%99%80-%EA%B1%B0%EB%9E%98-%EB%B2%94%EC%9C%84%EB%A5%BC-%EC%9D%BD%EC%8A%B5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"2단계: 단지 화면에서 대표 시세와 거래 범위를 읽습니다에 대한 직접 링크\" title=\"2단계: 단지 화면에서 대표 시세와 거래 범위를 읽습니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지를 고르면 보통 다음 숫자가 함께 보입니다. 각 숫자가 답하는 질문이 다르므로 하나로 섞지 않는 것이 중요합니다.</p>\n<table><thead><tr><th>화면의 숫자</th><th>답하는 질문</th><th>읽는 방법</th></tr></thead><tbody><tr><td>대표 시세</td><td>이 단지의 대표 평형은 지금 어느 수준인가?</td><td>최근 유효 거래를 바탕으로 한 기준값입니다. 개별 호가나 한 건의 거래와 다릅니다.</td></tr><tr><td>최근 1년 거래 범위</td><td>지난 1년 동안 얼마에서 얼마 사이로 거래됐나?</td><td>아래·위 끝값보다 범위의 폭을 봅니다. 폭이 넓으면 층·타입 차이나 시장 변화가 컸다는 뜻입니다.</td></tr><tr><td>최근 거래 목록</td><td>어떤 조건의 거래가 언제 있었나?</td><td>계약일·면적·층을 함께 확인하고, 해제 표시가 있는 거래는 제외해서 읽습니다.</td></tr><tr><td>최근 1년 거래 건수</td><td>비교할 표본이 충분한가?</td><td>거래가 드문 단지는 새 거래 한 건에도 대표 시세가 크게 움직일 수 있습니다.</td></tr></tbody></table>\n<p>대표 시세와 최근 거래가 다르다고 해서 어느 한쪽이 틀린 것은 아닙니다. 대표 시세는 여러 거래를 비교하기 위한 기준값이고, 최근 거래는 특정 조건의 한 기록입니다. 두 숫자의 차이가 크면 그 거래가 저층·특수 타입·직거래였는지부터 확인해 보세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3단계-평형을-맞춰서-비교합니다\">3단계: 평형을 맞춰서 비교합니다<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#3%EB%8B%A8%EA%B3%84-%ED%8F%89%ED%98%95%EC%9D%84-%EB%A7%9E%EC%B6%B0%EC%84%9C-%EB%B9%84%EA%B5%90%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"3단계: 평형을 맞춰서 비교합니다에 대한 직접 링크\" title=\"3단계: 평형을 맞춰서 비교합니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>같은 단지라도 평형이 다르면 비교 대상이 달라집니다. 단지 화면에서 평형 배지를 바꿔 가며 확인할 때는 다음 순서를 지켜 보세요.</p>\n<ol>\n<li class=\"\"><strong>내가 찾는 전용면적</strong>과 화면에서 선택된 평형이 같은지 확인합니다.</li>\n<li class=\"\">그 평형에서 <strong>최근 1년 거래 건수</strong>가 충분한지 봅니다.</li>\n<li class=\"\">대표 시세와 최근 1년 거래 범위를 <strong>같은 평형끼리</strong> 비교합니다.</li>\n<li class=\"\">다른 단지와 비교할 때도 <strong>비슷한 전용면적</strong>을 기준으로 맞춥니다.</li>\n</ol>\n<p>59㎡ 거래가 많은 단지에서 84㎡ 가격을 판단하려고 59㎡ 거래를 끌어오면 숫자는 쉽게 왜곡됩니다. 평형별 거래가 부족하다면 무리하게 다른 평형으로 채우기보다 “표본이 부족하다”는 사실 자체를 기록해 두는 편이 낫습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"같은-지역의-다른-단지와-비교하는-법\">같은 지역의 다른 단지와 비교하는 법<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EA%B0%99%EC%9D%80-%EC%A7%80%EC%97%AD%EC%9D%98-%EB%8B%A4%EB%A5%B8-%EB%8B%A8%EC%A7%80%EC%99%80-%EB%B9%84%EA%B5%90%ED%95%98%EB%8A%94-%EB%B2%95\" class=\"hash-link\" aria-label=\"같은 지역의 다른 단지와 비교하는 법에 대한 직접 링크\" title=\"같은 지역의 다른 단지와 비교하는 법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>관심 단지 하나만 보면 가격이 비싼지 싼지 판단하기 어렵습니다. 같은 시군구 안에서 다음 조건이 비슷한 단지 2~3곳을 함께 보면 감이 잡힙니다.</p>\n<ul>\n<li class=\"\">준공 연도(연식)가 비슷한가</li>\n<li class=\"\">전용면적이 같은가</li>\n<li class=\"\">역·학교 같은 생활 인프라와의 거리가 비슷한가</li>\n<li class=\"\">최근 1년 거래 건수가 비슷한 수준인가</li>\n</ul>\n<p>이때도 대표 시세 한 숫자만 나란히 놓기보다 <strong>최근 1년 거래 범위의 위치</strong>를 함께 비교해 보세요. 한 단지의 대표 시세가 범위의 위쪽에 붙어 있고 다른 단지는 아래쪽에 있다면, 최근 흐름이 서로 다를 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"국토교통부-공개자료와-대조하는-방법\">국토교통부 공개자료와 대조하는 방법<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EA%B5%AD%ED%86%A0%EA%B5%90%ED%86%B5%EB%B6%80-%EA%B3%B5%EA%B0%9C%EC%9E%90%EB%A3%8C%EC%99%80-%EB%8C%80%EC%A1%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"국토교통부 공개자료와 대조하는 방법에 대한 직접 링크\" title=\"국토교통부 공개자료와 대조하는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>어떤 서비스로 실거래가를 보든 원자료는 <a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>입니다. 중요한 의사결정 전에는 원자료와 한 번 대조해 보는 습관이 좋습니다.</p>\n<ol>\n<li class=\"\">공개시스템에서 같은 시군구와 단지를 선택합니다.</li>\n<li class=\"\">전용면적이 같은 거래만 남깁니다.</li>\n<li class=\"\">계약일, 층, 거래 유형(중개·직거래), 해제 여부를 확인합니다.</li>\n<li class=\"\">정리된 화면의 최근 거래 목록과 날짜·금액이 맞는지 봅니다.</li>\n</ol>\n<p>숫자가 조금 다르다면 대부분 신고 시점, 해제·정정 반영 시점, 면적 구분 기준의 차이입니다. 이 차이를 오류로 단정하기 전에 기준일을 먼저 맞춰 보세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"실거래가-다음에-확인할-것\">실거래가 다음에 확인할 것<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80-%EB%8B%A4%EC%9D%8C%EC%97%90-%ED%99%95%EC%9D%B8%ED%95%A0-%EA%B2%83\" class=\"hash-link\" aria-label=\"실거래가 다음에 확인할 것에 대한 직접 링크\" title=\"실거래가 다음에 확인할 것에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>실거래가는 “지금까지”의 기록입니다. 매수·매도 시점을 고민하고 있다면 그다음 질문으로 넘어가야 합니다.</p>\n<ul>\n<li class=\"\"><strong>앞으로의 가격 범위</strong>: 실거래 기준값에서 1년 뒤 어떤 범위가 가능한지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값 읽는 법</a>을 참고하세요.</li>\n<li class=\"\"><strong>거래에 드는 실제 비용</strong>: 취득세·중개보수·양도세까지 넣은 총자금은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator\">아파트 거래비용 계산기</a>로 계산할 수 있습니다.</li>\n<li class=\"\"><strong>분양권 거래가 섞였는지</strong>: 신축 단지는 <a class=\"\" href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference\">일반 매매와 분양권 실거래가를 같은 시세로 합치면 안 되는 이유</a>를 먼저 확인하세요.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"왜-우리-단지는-목록에-없나요\">왜 우리 단지는 목록에 없나요?<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%99%9C-%EC%9A%B0%EB%A6%AC-%EB%8B%A8%EC%A7%80%EB%8A%94-%EB%AA%A9%EB%A1%9D%EC%97%90-%EC%97%86%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"왜 우리 단지는 목록에 없나요?에 대한 직접 링크\" title=\"왜 우리 단지는 목록에 없나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>거래가 적거나 마지막 거래가 오래된 단지는 대표 시세를 안정적으로 계산하기 어렵습니다. 이런 단지는 숫자가 한두 건의 거래에 크게 흔들리기 때문에 목록에서 제외되는 경우가 많습니다. 이때는 국토교통부 공개시스템에서 개별 거래를 직접 확인하고, 주변의 비슷한 단지를 함께 참고하세요.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"대표-시세는-호가와-같은-건가요\">대표 시세는 호가와 같은 건가요?<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EB%8A%94-%ED%98%B8%EA%B0%80%EC%99%80-%EA%B0%99%EC%9D%80-%EA%B1%B4%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"대표 시세는 호가와 같은 건가요?에 대한 직접 링크\" title=\"대표 시세는 호가와 같은 건가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 호가는 매도자가 원하는 가격이고, 대표 시세는 실제 신고된 거래를 바탕으로 한 기준값입니다. 시장이 빠르게 움직이는 시기에는 호가와 대표 시세의 차이가 커질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최근-거래가-대표-시세보다-훨씬-높으면-시세가-오른-건가요\">최근 거래가 대표 시세보다 훨씬 높으면 시세가 오른 건가요?<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98%EA%B0%80-%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EB%B3%B4%EB%8B%A4-%ED%9B%A8%EC%94%AC-%EB%86%92%EC%9C%BC%EB%A9%B4-%EC%8B%9C%EC%84%B8%EA%B0%80-%EC%98%A4%EB%A5%B8-%EA%B1%B4%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"최근 거래가 대표 시세보다 훨씬 높으면 시세가 오른 건가요?에 대한 직접 링크\" title=\"최근 거래가 대표 시세보다 훨씬 높으면 시세가 오른 건가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>한 건만으로는 판단하기 어렵습니다. 그 거래의 층·타입·수리 상태를 확인하고, 이후 비슷한 가격의 거래가 이어지는지 지켜보는 것이 좋습니다. 같은 수준의 거래가 여러 건 쌓이면 대표 시세도 따라 움직입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"실거래가-화면에서-1년-뒤-가격도-볼-수-있나요\">실거래가 화면에서 1년 뒤 가격도 볼 수 있나요?<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C-1%EB%85%84-%EB%92%A4-%EA%B0%80%EA%B2%A9%EB%8F%84-%EB%B3%BC-%EC%88%98-%EC%9E%88%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"실거래가 화면에서 1년 뒤 가격도 볼 수 있나요?에 대한 직접 링크\" title=\"실거래가 화면에서 1년 뒤 가격도 볼 수 있나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>실거래가 화면은 지금까지의 거래 기록을 보여주는 데 집중합니다. 1년 뒤 예상 범위는 별도의 예측 화면에서 확인하는 것이 일반적이며, 그 결과는 확정 가격이 아니라 참고용 범위입니다. 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a>에 정리했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"지역별-실거래가-바로-확인하기\">지역별 실거래가 바로 확인하기<a href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region#%EC%A7%80%EC%97%AD%EB%B3%84-%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80-%EB%B0%94%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"지역별 실거래가 바로 확인하기에 대한 직접 링크\" title=\"지역별 실거래가 바로 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>시군구별·단지별 최근 거래와 대표 시세는 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 지역별 아파트 실거래가</a>에서 바로 확인할 수 있습니다. 국토교통부 실거래가 공개자료를 바탕으로 대표 평형 기준 시세, 최근 1년 거래 범위, 최근 거래, 같은 지역 단지를 한 화면에 모아 보여줍니다.</p>\n<p>예를 들어 <a href=\"https://apt-insights.com/apt/11680\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">서울 강남구</a>, <a href=\"https://apt-insights.com/apt/11710\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">송파구</a>, <a href=\"https://apt-insights.com/apt/11350\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">노원구</a>, <a href=\"https://apt-insights.com/apt/41135\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">성남 분당구</a>처럼 시군구를 먼저 고른 뒤 단지를 선택하면 됩니다.</p>\n<p>처음부터 통계를 읽는 전체 순서가 궁금하다면 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>를 함께 읽어 보세요.</p>\n<blockquote>\n<p>실거래가와 대표 시세는 공개 자료를 바탕으로 정리한 참고 정보입니다. 신고·해제·정정 시점에 따라 실제와 차이가 날 수 있으며, 특정 거래 가격이나 수익을 보장하지 않습니다. 계약 전에는 공식 자료와 현장 조건을 반드시 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-real-transaction-price-by-region",
            "title": "지역별 아파트 실거래가 조회하는 법: 시군구에서 단지·평형까지 3단계",
            "summary": "아파트 실거래가를 시군구, 단지, 평형 순서로 좁혀 조회하는 방법과 최근 거래·대표 시세·최근 1년 거래 범위를 읽는 기준, 국토교통부 공개자료와 대조하는 방법을 정리합니다.",
            "date_modified": "2026-10-02T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk",
            "content_html": "\n<p>부동산 시장에서 “전세가율이 80%를 넘었으니 소액으로 갭투자하기 좋다”거나 “전세가가 매매가를 밀어 올릴 타이밍”이라는 이야기를 자주 접합니다. 매매가와 전세가의 차이(Gap)가 줄어들면 매수에 들어가는 초기 자본이 줄어드는 것은 사실입니다.</p>\n<p>하지만 전세가율이라는 하나의 숫자만 보고 매수를 결정하면 시장의 가장 위험한 함정에 빠지기 쉽습니다. <strong>전세가율이 높아진 원인이 무엇인지, 그리고 그 비율이 자산의 안전성을 보장하는지</strong>를 반드시 분리해서 살펴봐야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"전세가율이-높아지는-두-가지-상반된-경로\">전세가율이 높아지는 두 가지 상반된 경로<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#%EC%A0%84%EC%84%B8%EA%B0%80%EC%9C%A8%EC%9D%B4-%EB%86%92%EC%95%84%EC%A7%80%EB%8A%94-%EB%91%90-%EA%B0%80%EC%A7%80-%EC%83%81%EB%B0%98%EB%90%9C-%EA%B2%BD%EB%A1%9C\" class=\"hash-link\" aria-label=\"전세가율이 높아지는 두 가지 상반된 경로에 대한 직접 링크\" title=\"전세가율이 높아지는 두 가지 상반된 경로에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>전세가율은 <code>전세가격 ÷ 매매가격</code>의 공식으로 계산됩니다. 분수가 커지는 방법은 두 가지입니다.</p>\n<ol>\n<li class=\"\"><strong>분자(전세가)가 오르는 경우</strong>: 실거주 수요가 풍부하고 입주 물량이 부족해 전세보증금이 상승하는 건강한 흐름</li>\n<li class=\"\"><strong>분모(매매가)가 떨어지는 경우</strong>: 미래 가치에 대한 기대가 꺾여 매매가격이 하락하면서 상대적으로 전세가율이 치솟는 흐름</li>\n</ol>\n<p>겉으로 보이는 전세가율 수치는 똑같이 80%라도, 1번과 2번이 의미하는 시장 상황은 완전히 정반대입니다. 매매가격이 지속적으로 하락해 전세가율이 높아진 지역에 갭투자로 진입하면, 매매가 추가 하락 시 곧바로 보증금 미반환(깡통전세) 리스크에 노출됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"갭투자자가-놓치기-쉬운-5가지-위험\">갭투자자가 놓치기 쉬운 5가지 위험<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#%EA%B0%AD%ED%88%AC%EC%9E%90%EC%9E%90%EA%B0%80-%EB%86%93%EC%B9%98%EA%B8%B0-%EC%89%AC%EC%9A%B4-5%EA%B0%80%EC%A7%80-%EC%9C%84%ED%97%98\" class=\"hash-link\" aria-label=\"갭투자자가 놓치기 쉬운 5가지 위험에 대한 직접 링크\" title=\"갭투자자가 놓치기 쉬운 5가지 위험에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-전세가는-하방-지지선이-아니라-변동성-지표다\">1. 전세가는 하방 지지선이 아니라 변동성 지표다<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#1-%EC%A0%84%EC%84%B8%EA%B0%80%EB%8A%94-%ED%95%98%EB%B0%A9-%EC%A7%80%EC%A7%80%EC%84%A0%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EB%B3%80%EB%8F%99%EC%84%B1-%EC%A7%80%ED%91%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 전세가는 하방 지지선이 아니라 변동성 지표다에 대한 직접 링크\" title=\"1. 전세가는 하방 지지선이 아니라 변동성 지표다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>많은 사람들이 “전세가가 매매가의 하한선을 받쳐준다”고 믿지만, 전세가 역시 만기 시점의 입주 물량과 금리에 따라 급격히 흔들립니다. 인근에 대단지 신축 아파트가 입주하거나 전세대출 금리가 급등하면 전세가는 수개월 만에 수천만원에서 수억원씩 급락할 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-역전세-발생-시-유동성-버퍼가-있는가\">2. 역전세 발생 시 유동성 버퍼가 있는가<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#2-%EC%97%AD%EC%A0%84%EC%84%B8-%EB%B0%9C%EC%83%9D-%EC%8B%9C-%EC%9C%A0%EB%8F%99%EC%84%B1-%EB%B2%84%ED%8D%BC%EA%B0%80-%EC%9E%88%EB%8A%94%EA%B0%80\" class=\"hash-link\" aria-label=\"2. 역전세 발생 시 유동성 버퍼가 있는가에 대한 직접 링크\" title=\"2. 역전세 발생 시 유동성 버퍼가 있는가에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전세가율이 높은 상태에서 재계약 시점에 전세 시세가 하락(역전세)하면, 임대인은 그 차액을 현금으로 세입자에게 내어주어야 합니다. 초기 투자금이 적게 들었다는 이유로 현금 여력 없이 갭투자를 진행했다면 심각한 자금 경색에 직면하게 됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-취득세와-보유세-중개보수-등-거래비용의-누락\">3. 취득세와 보유세, 중개보수 등 거래비용의 누락<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#3-%EC%B7%A8%EB%93%9D%EC%84%B8%EC%99%80-%EB%B3%B4%EC%9C%A0%EC%84%B8-%EC%A4%91%EA%B0%9C%EB%B3%B4%EC%88%98-%EB%93%B1-%EA%B1%B0%EB%9E%98%EB%B9%84%EC%9A%A9%EC%9D%98-%EB%88%84%EB%9D%BD\" class=\"hash-link\" aria-label=\"3. 취득세와 보유세, 중개보수 등 거래비용의 누락에 대한 직접 링크\" title=\"3. 취득세와 보유세, 중개보수 등 거래비용의 누락에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>매매가와 전세가의 단순 차액(Gap)만 계산하고, 취득세·지방교육세, 부동산 중개보수, 주택 채권 매입비, 그리고 보유 기간 중 발생하는 재산세와 종합부동산세를 계산에 넣지 않으면 실제 수익률은 마이너스로 돌아설 수 있습니다. <a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator\">아파트 거래비용 계산기</a>를 통해 실제 부대비용을 먼저 점검해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-매매-수요가-없는-임대차-전용-단지의-함정\">4. 매매 수요가 없는 ‘임대차 전용 단지’의 함정<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#4-%EB%A7%A4%EB%A7%A4-%EC%88%98%EC%9A%94%EA%B0%80-%EC%97%86%EB%8A%94-%EC%9E%84%EB%8C%80%EC%B0%A8-%EC%A0%84%EC%9A%A9-%EB%8B%A8%EC%A7%80%EC%9D%98-%ED%95%A8%EC%A0%95\" class=\"hash-link\" aria-label=\"4. 매매 수요가 없는 ‘임대차 전용 단지’의 함정에 대한 직접 링크\" title=\"4. 매매 수요가 없는 ‘임대차 전용 단지’의 함정에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>지방 비역세권이나 노후 구축 단지 중에는 전세 수요는 꾸준하지만 매수하려는 사람이 거의 없는 단지들이 있습니다. 이런 곳은 전세가율이 85~90%에 육박하더라도 몇 년이 지나도 매매가격이 오르지 않아 자본 이득을 기대하기 어렵고, 매도하고 싶을 때 매수자를 찾지 못해 환금성이 크게 떨어집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-보증보험-가입-요건-강화와-깡통전세-규제\">5. 보증보험 가입 요건 강화와 깡통전세 규제<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#5-%EB%B3%B4%EC%A6%9D%EB%B3%B4%ED%97%98-%EA%B0%80%EC%9E%85-%EC%9A%94%EA%B1%B4-%EA%B0%95%ED%99%94%EC%99%80-%EA%B9%A1%ED%86%B5%EC%A0%84%EC%84%B8-%EA%B7%9C%EC%A0%9C\" class=\"hash-link\" aria-label=\"5. 보증보험 가입 요건 강화와 깡통전세 규제에 대한 직접 링크\" title=\"5. 보증보험 가입 요건 강화와 깡통전세 규제에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>최근 HUG(주택도시보증공사)의 전세보증금 반환보증 가입 기준이 공시가격의 126% 이내(공시가격 반영률 140% × 전세가율 90%) 등으로 엄격해졌습니다. 전세가율이 너무 높은 아파트는 다음 세입자가 전세보증보험에 가입할 수 없어, 새로운 임차인을 구하기가 극도로 어려워질 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"전세가율을-제대로-읽는-4단계-점검-순서\">전세가율을 제대로 읽는 4단계 점검 순서<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#%EC%A0%84%EC%84%B8%EA%B0%80%EC%9C%A8%EC%9D%84-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%9D%BD%EB%8A%94-4%EB%8B%A8%EA%B3%84-%EC%A0%90%EA%B2%80-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"전세가율을 제대로 읽는 4단계 점검 순서에 대한 직접 링크\" title=\"전세가율을 제대로 읽는 4단계 점검 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\"><strong>원인 구분하기</strong>: 매매가가 내려서 전세가율이 오른 것인지, 전세 실거래가가 상승해서 오른 것인지 확인합니다.</li>\n<li class=\"\"><strong>입주 물량 확인하기</strong>: 향후 2~3년간 해당 시·군·구 및 인접 지역의 아파트 입주 예정 물량을 점검합니다.</li>\n<li class=\"\"><strong>매매 거래량 동반 여부</strong>: 전세 거래만 활발하고 매매 거래가 완전히 끊겨 있다면 매수 전환 수요가 없다는 신호입니다.</li>\n<li class=\"\"><strong>역전세 시나리오 대비</strong>: 전세 시세가 10~20% 하락하더라도 보증금을 반환해줄 수 있는 현금 흐름이 확보되어 있는지 검토합니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-전세가율이란-무엇인가요\">Q. 전세가율이란 무엇인가요?<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#q-%EC%A0%84%EC%84%B8%EA%B0%80%EC%9C%A8%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 전세가율이란 무엇인가요?에 대한 직접 링크\" title=\"Q. 전세가율이란 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전세가율이란 아파트 매매가격 대비 전세보증금의 비율(전세가 / 매매가 × 100)을 의미하며, 통상 매매 수요와 임대차 수요의 상대적 강도를 가늠하는 지표로 활용됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-전세가율이-80-이상으로-높으면-무조건-좋은-투자처인가요\">Q. 전세가율이 80% 이상으로 높으면 무조건 좋은 투자처인가요?<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#q-%EC%A0%84%EC%84%B8%EA%B0%80%EC%9C%A8%EC%9D%B4-80-%EC%9D%B4%EC%83%81%EC%9C%BC%EB%A1%9C-%EB%86%92%EC%9C%BC%EB%A9%B4-%EB%AC%B4%EC%A1%B0%EA%B1%B4-%EC%A2%8B%EC%9D%80-%ED%88%AC%EC%9E%90%EC%B2%98%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 전세가율이 80% 이상으로 높으면 무조건 좋은 투자처인가요?에 대한 직접 링크\" title=\"Q. 전세가율이 80% 이상으로 높으면 무조건 좋은 투자처인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 전세가율이 지나치게 높은 단지는 매매 수요가 정체되어 미래 자산 가치 상승 여력이 낮거나, 향후 매매가 소폭 하락 시 보증금을 반환하지 못하는 깡통전세·역전세 위험이 매우 큽니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-전세가율-상승이-매매가-상승으로-이어지려면-어떤-조건이-필요한가요\">Q. 전세가율 상승이 매매가 상승으로 이어지려면 어떤 조건이 필요한가요?<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#q-%EC%A0%84%EC%84%B8%EA%B0%80%EC%9C%A8-%EC%83%81%EC%8A%B9%EC%9D%B4-%EB%A7%A4%EB%A7%A4%EA%B0%80-%EC%83%81%EC%8A%B9%EC%9C%BC%EB%A1%9C-%EC%9D%B4%EC%96%B4%EC%A7%80%EB%A0%A4%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%A1%B0%EA%B1%B4%EC%9D%B4-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 전세가율 상승이 매매가 상승으로 이어지려면 어떤 조건이 필요한가요?에 대한 직접 링크\" title=\"Q. 전세가율 상승이 매매가 상승으로 이어지려면 어떤 조건이 필요한가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전세가 상승이 단순 공급 부족에 그치지 않고, 임차인의 소득 및 매수 전환 여력이 뒷받침되어야 하며 대출 금리와 공급 물량, 지역 일자리 여건이 함께 개선되어야 매매가 밀어올리기 효과가 나타납니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"함께-읽을-글\">함께 읽을 글<a href=\"https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk#%ED%95%A8%EA%BB%98-%EC%9D%BD%EC%9D%84-%EA%B8%80\" class=\"hash-link\" aria-label=\"함께 읽을 글에 대한 직접 링크\" title=\"함께 읽을 글에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator\">아파트 거래비용 계산: 취득세·양도세·중개보수까지</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">아파트 실거래가 보는 법: 최근 거래 한 건만 믿으면 위험한 이유</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/mortgage-rate-apartment-price\">주택담보대출 금리와 아파트 가격의 상관관계</a></li>\n</ul>\n<blockquote>\n<p>이 글은 부동산 통계와 시장 지표를 해석하기 위한 정보 제공 목적의 아카이브입니다. 특정 지역이나 단지의 매수를 권유하지 않으며 투자 결과에 대한 책임을 지지 않습니다. 실제 거래 전에는 현장 임장과 전문가 상담을 권장합니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/jeonse-ratio-and-gap-investment-risk",
            "title": "전세가율이 높으면 매수하기 좋을까? 갭투자 판단 시 놓치기 쉬운 5가지 함정",
            "summary": "전세가율이 높을 때 무턱대고 매수하거나 갭투자하면 위험한 이유와 매매가 대비 전세가 비율의 착시, 깡통전세 및 역전세 리스크를 객관적으로 분석하는 기준을 정리합니다.",
            "date_modified": "2026-09-13T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "금융·세금",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/presale-right-vs-general-trade-difference",
            "content_html": "\n<p>아파트 실거래가 조회 앱이나 포털을 보다 보면, 신축 입주 예정 단지의 실거래가가 인근 구축 아파트와 비슷하거나 오히려 낮게 찍혀 있는 것을 보고 “신축인데 생각보다 싸다”고 생각하는 경우가 많습니다.</p>\n<p>하지만 국토교통부 실거래가 공개시스템에 올라오는 <strong>기존 아파트 매매 자료와 분양권 전매 자료는 성격이 전혀 다른 데이터</strong>입니다. 표기된 숫자만 그대로 일대일 비교하면 실제 매수자가 지출해야 하는 총비용과 시세를 완전히 오판하게 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"왜-두-데이터는-같은-선상에-놓일-수-없을까\">왜 두 데이터는 같은 선상에 놓일 수 없을까?<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#%EC%99%9C-%EB%91%90-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%8A%94-%EA%B0%99%EC%9D%80-%EC%84%A0%EC%83%81%EC%97%90-%EB%86%93%EC%9D%BC-%EC%88%98-%EC%97%86%EC%9D%84%EA%B9%8C\" class=\"hash-link\" aria-label=\"왜 두 데이터는 같은 선상에 놓일 수 없을까?에 대한 직접 링크\" title=\"왜 두 데이터는 같은 선상에 놓일 수 없을까?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기존 아파트 매매는 이미 건축이 완료되어 등기된 실물 부동산을 거래하는 것이며, 매매가격에 건축비·토지비·내부 인테리어 가치가 모두 녹아 있습니다. 반면 분양권은 **‘미래에 지어질 아파트에 입주할 수 있는 권리’**를 거래하는 계약입니다.</p>\n<p>따라서 계약서에 적히는 금액의 구성 항목 자체가 완전히 다릅니다.</p>\n<table><thead><tr><th style=\"text-align:left\">비교 항목</th><th style=\"text-align:left\">기존 아파트 일반 매매</th><th style=\"text-align:left\">분양권 전매</th></tr></thead><tbody><tr><td style=\"text-align:left\"><strong>거래 대상</strong></td><td style=\"text-align:left\">등기 완료된 실물 주택</td><td style=\"text-align:left\">완공 전 입주 권리</td></tr><tr><td style=\"text-align:left\"><strong>신고 금액 기준</strong></td><td style=\"text-align:left\">실물 매매 총대금</td><td style=\"text-align:left\">기본 분양가 + 프리미엄(P)</td></tr><tr><td style=\"text-align:left\"><strong>추가 부담 항목</strong></td><td style=\"text-align:left\">중개보수, 취득세</td><td style=\"text-align:left\">옵션비, 확장비, 후불 이자, 등기 취득세</td></tr><tr><td style=\"text-align:left\"><strong>취득세 납부 시점</strong></td><td style=\"text-align:left\">잔금 납부 시 (즉시)</td><td style=\"text-align:left\">완공 후 소유권 이전등기 시</td></tr><tr><td style=\"text-align:left\"><strong>입주 가능 시기</strong></td><td style=\"text-align:left\">계약 후 잔금 시점</td><td style=\"text-align:left\">준공 예정일 (통상 2~3년 뒤)</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"분양권-실거래가에-숨겨진-3가지-비용\">분양권 실거래가에 숨겨진 3가지 비용<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#%EB%B6%84%EC%96%91%EA%B6%8C-%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80%EC%97%90-%EC%88%A8%EA%B2%A8%EC%A7%84-3%EA%B0%80%EC%A7%80-%EB%B9%84%EC%9A%A9\" class=\"hash-link\" aria-label=\"분양권 실거래가에 숨겨진 3가지 비용에 대한 직접 링크\" title=\"분양권 실거래가에 숨겨진 3가지 비용에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>국토교통부 실거래가 시스템에 분양권이 8억원으로 신고되었다고 해서 매수자가 8억원만 준비하면 되는 것이 아닙니다. 겉으로 드러나지 않는 세 가지 필수 비용이 숨어 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-발코니-확장비-및-유상-옵션비\">1. 발코니 확장비 및 유상 옵션비<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#1-%EB%B0%9C%EC%BD%94%EB%8B%88-%ED%99%95%EC%9E%A5%EB%B9%84-%EB%B0%8F-%EC%9C%A0%EC%83%81-%EC%98%B5%EC%85%98%EB%B9%84\" class=\"hash-link\" aria-label=\"1. 발코니 확장비 및 유상 옵션비에 대한 직접 링크\" title=\"1. 발코니 확장비 및 유상 옵션비에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>최근 신축 아파트는 발코니 확장을 필수로 전제하고 설계됩니다. 발코니 확장비만 1,500만<del>3,000만원에 달하며, 시스템 에어컨, 중문, 엔지니어드 스톤 등 필수 유상옵션을 합치면 3,000만</del>6,000만원의 추가 비용이 발생합니다. 이 비용은 분양권 실거래가 신고 시 별도 표기되거나 누락되는 경우가 많습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-중도금-대출-이자-후불제\">2. 중도금 대출 이자 후불제<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#2-%EC%A4%91%EB%8F%84%EA%B8%88-%EB%8C%80%EC%B6%9C-%EC%9D%B4%EC%9E%90-%ED%9B%84%EB%B6%88%EC%A0%9C\" class=\"hash-link\" aria-label=\"2. 중도금 대출 이자 후불제에 대한 직접 링크\" title=\"2. 중도금 대출 이자 후불제에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>대다수 분양 단지는 공사 기간 동안 발생하는 중도금 대출 이자를 수분양자가 바로 내지 않고 입주 시점에 일괄 정산하는 ‘이자 후불제’를 적용합니다. 고금리 기조에서는 입주 시 정산해야 할 누적 이자만 2,000만~4,000만원에 이릅니다. 매수자가 이 이자를 승계받는 조건이라면 실질 매수가격은 그만큼 올라갑니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-세금-대납-조건손피-여부\">3. 세금 대납 조건(손피) 여부<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#3-%EC%84%B8%EA%B8%88-%EB%8C%80%EB%82%A9-%EC%A1%B0%EA%B1%B4%EC%86%90%ED%94%BC-%EC%97%AC%EB%B6%80\" class=\"hash-link\" aria-label=\"3. 세금 대납 조건(손피) 여부에 대한 직접 링크\" title=\"3. 세금 대납 조건(손피) 여부에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>분양권 시장에서는 매도자의 양도소득세를 매수자가 대신 부담하는 <a class=\"\" href=\"https://alvin.ing/blog/sonpi-tax-calculator\">손피(손에 남는 프리미엄) 거래</a>가 빈번합니다. 분양권 단기 양도세율은 60<del>70%에 달하기 때문에, 겉으로 신고된 프리미엄이 3,000만원이라도 매수자가 대신 내주는 세금까지 합치면 실제 부담액은 5,000만</del>8,000만원으로 불어납니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"실전-비교-체크리스트-실질-매수가격-계산법\">실전 비교 체크리스트: 실질 매수가격 계산법<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#%EC%8B%A4%EC%A0%84-%EB%B9%84%EA%B5%90-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%8B%A4%EC%A7%88-%EB%A7%A4%EC%88%98%EA%B0%80%EA%B2%A9-%EA%B3%84%EC%82%B0%EB%B2%95\" class=\"hash-link\" aria-label=\"실전 비교 체크리스트: 실질 매수가격 계산법에 대한 직접 링크\" title=\"실전 비교 체크리스트: 실질 매수가격 계산법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>인근 단지와 시세를 올바르게 비교하려면 다음 계산식을 사용해 <strong>실질 총 인수비용</strong>을 먼저 구해야 합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">실질 총 인수비용</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= 분양가 + 프리미엄(P) + 발코니 확장비 + 유상 옵션비 + 중도금 후불이자 + 손피 대납세액</span><br></div></code></pre></div></div>\n<p>이 합계 금액에 향후 완공 시 납부할 취득세(통상 옵션비와 이자를 합산한 총 취득가액 기준 1~3%)를 감안해야만 비로소 기존 아파트 매매가와 공정한 비교가 가능해집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-국토부-실거래가에-표시된-분양권-가격에는-옵션비와-중도금-이자가-포함되어-있나요\">Q. 국토부 실거래가에 표시된 분양권 가격에는 옵션비와 중도금 이자가 포함되어 있나요?<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#q-%EA%B5%AD%ED%86%A0%EB%B6%80-%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80%EC%97%90-%ED%91%9C%EC%8B%9C%EB%90%9C-%EB%B6%84%EC%96%91%EA%B6%8C-%EA%B0%80%EA%B2%A9%EC%97%90%EB%8A%94-%EC%98%B5%EC%85%98%EB%B9%84%EC%99%80-%EC%A4%91%EB%8F%84%EA%B8%88-%EC%9D%B4%EC%9E%90%EA%B0%80-%ED%8F%AC%ED%95%A8%EB%90%98%EC%96%B4-%EC%9E%88%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 국토부 실거래가에 표시된 분양권 가격에는 옵션비와 중도금 이자가 포함되어 있나요?에 대한 직접 링크\" title=\"Q. 국토부 실거래가에 표시된 분양권 가격에는 옵션비와 중도금 이자가 포함되어 있나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>대부분 포함되어 있지 않습니다. 국토부 분양권 실거래가는 통상 공급계약서상 분양가와 프리미엄의 합계액으로 신고되며, 수천만원에 달하는 발코니 확장비, 유상옵션비, 중도금 이자 후불제 비용은 별도로 발생합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-기존-등기-아파트와-분양권의-취득세-납부-시점은-어떻게-다른가요\">Q. 기존 등기 아파트와 분양권의 취득세 납부 시점은 어떻게 다른가요?<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#q-%EA%B8%B0%EC%A1%B4-%EB%93%B1%EA%B8%B0-%EC%95%84%ED%8C%8C%ED%8A%B8%EC%99%80-%EB%B6%84%EC%96%91%EA%B6%8C%EC%9D%98-%EC%B7%A8%EB%93%9D%EC%84%B8-%EB%82%A9%EB%B6%80-%EC%8B%9C%EC%A0%90%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8B%A4%EB%A5%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 기존 등기 아파트와 분양권의 취득세 납부 시점은 어떻게 다른가요?에 대한 직접 링크\" title=\"Q. 기존 등기 아파트와 분양권의 취득세 납부 시점은 어떻게 다른가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>기존 아파트는 잔금 지급일 또는 등기일 중 빠른 날에 취득세를 납부하지만, 분양권은 분양권 자체를 매수할 때는 취득세를 내지 않고 추후 아파트가 완공되어 소유권 이전등기를 할 때 실제 총 취득가액을 기준으로 취득세를 납부합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-인근-구축-아파트와-신축-분양권-가격을-비교할-때-가장-중요한-것은-무엇인가요\">Q. 인근 구축 아파트와 신축 분양권 가격을 비교할 때 가장 중요한 것은 무엇인가요?<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#q-%EC%9D%B8%EA%B7%BC-%EA%B5%AC%EC%B6%95-%EC%95%84%ED%8C%8C%ED%8A%B8%EC%99%80-%EC%8B%A0%EC%B6%95-%EB%B6%84%EC%96%91%EA%B6%8C-%EA%B0%80%EA%B2%A9%EC%9D%84-%EB%B9%84%EA%B5%90%ED%95%A0-%EB%95%8C-%EA%B0%80%EC%9E%A5-%EC%A4%91%EC%9A%94%ED%95%9C-%EA%B2%83%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 인근 구축 아파트와 신축 분양권 가격을 비교할 때 가장 중요한 것은 무엇인가요?에 대한 직접 링크\" title=\"Q. 인근 구축 아파트와 신축 분양권 가격을 비교할 때 가장 중요한 것은 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>분양권 표기 가격에 옵션비, 후불 이자, 등기 시 취득세를 더한 실질 총 매수비용을 산출한 뒤, 완공 시점까지의 금융 기회비용과 연식 차이를 감안해 비교해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"함께-읽을-글\">함께 읽을 글<a href=\"https://alvin.ing/blog/presale-right-vs-general-trade-difference#%ED%95%A8%EA%BB%98-%EC%9D%BD%EC%9D%84-%EA%B8%80\" class=\"hash-link\" aria-label=\"함께 읽을 글에 대한 직접 링크\" title=\"함께 읽을 글에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/sonpi-tax-calculator\">분양권 손피 계산기: 프리미엄 3,000만원이면 실제 부담액은?</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator\">아파트 거래비용 계산: 취득세·양도세·중개보수까지</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">아파트 실거래가 보는 법: 최근 거래 한 건만 믿으면 위험한 이유</a></li>\n</ul>\n<blockquote>\n<p>이 글은 부동산 거래 유형별 데이터 해석 기준을 설명하기 위한 정보 아카이브입니다. 특정 분양권이나 단지의 투자를 권유하지 않으며, 실제 거래 및 계약 전에는 공급계약서와 분양권 매매계약서 특약 사항을 전문가와 면밀히 확인하시기 바랍니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/presale-right-vs-general-trade-difference",
            "title": "일반 매매와 분양권 실거래가를 같은 시세로 합쳐서 보면 안 되는 이유",
            "summary": "국토교통부 실거래가 조회 시 기존 등기 아파트 매매와 분양권 거래를 단순 비교하면 안 되는 이유와 옵션비, 중도금 이자 후불제, 프리미엄의 차이를 정리합니다.",
            "date_modified": "2026-09-13T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터",
                "금융·세금"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-analysis-share-url",
            "content_html": "<p>아파트 분석 결과를 가족이나 함께 집을 보는 사람에게 전달할 때 숫자만 캡처하면, 며칠 뒤에는 어느 단지·평형·기준일의 결과였는지 잃기 쉽습니다. 아파트 인사이트의 공유 URL은 선택한 단지의 가격 흐름과 예상 결과를 한 화면에서 다시 볼 수 있게 전달하는 방법입니다.</p>\n<p>공유는 편리하지만, 링크를 받는 사람이 가운데 예상가만 보고 확정 가격이나 매수 추천으로 오해하지 않도록 맥락을 함께 확인해야 합니다. 이 글은 아파트 분석 공유 URL을 만들고 보내기 전에 점검할 다섯 가지를 정리합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-링크가-가리키는-단지와-평형을-확인합니다\">1. 링크가 가리키는 단지와 평형을 확인합니다<a href=\"https://alvin.ing/blog/apartment-analysis-share-url#1-%EB%A7%81%ED%81%AC%EA%B0%80-%EA%B0%80%EB%A6%AC%ED%82%A4%EB%8A%94-%EB%8B%A8%EC%A7%80%EC%99%80-%ED%8F%89%ED%98%95%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 링크가 가리키는 단지와 평형을 확인합니다에 대한 직접 링크\" title=\"1. 링크가 가리키는 단지와 평형을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공유 전 첫 번째 확인 항목은 단지명과 평형입니다. 같은 단지라도 전용면적과 거래 조건이 다르면 최근 거래와 가격 흐름이 달라질 수 있습니다. 링크를 보내는 메시지에는 최소한 아래 정보를 적어 두세요.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">단지: 가상 단지</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">지역: 가상 시·군·구</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">평형: 전용 84㎡</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">조회일: 2026-09-07</span><br></div></code></pre></div></div>\n<p>이 네 줄이 있으면 링크를 받은 사람이 비슷한 이름의 다른 단지나 다른 평형의 결과로 받아들이는 일을 줄일 수 있습니다. 면적·층·거래 유형에 따라 최근 거래가 달라지는 이유는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a>를 참고하세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-최근-거래와-예상-결과를-같은-숫자로-섞지-않습니다\">2. 최근 거래와 예상 결과를 같은 숫자로 섞지 않습니다<a href=\"https://alvin.ing/blog/apartment-analysis-share-url#2-%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98%EC%99%80-%EC%98%88%EC%83%81-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EA%B0%99%EC%9D%80-%EC%88%AB%EC%9E%90%EB%A1%9C-%EC%84%9E%EC%A7%80-%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 최근 거래와 예상 결과를 같은 숫자로 섞지 않습니다에 대한 직접 링크\" title=\"2. 최근 거래와 예상 결과를 같은 숫자로 섞지 않습니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공유 화면에는 과거 실거래 흐름과 앞으로의 예상 결과가 함께 보일 수 있습니다. 둘은 같은 역할을 하지 않습니다.</p>\n<table><thead><tr><th>항목</th><th>답하는 질문</th><th>전달할 때의 표현</th></tr></thead><tbody><tr><td>최근 거래</td><td>어떤 조건에서 실제 거래가 확인됐는가</td><td>최근 확인된 거래 흐름</td></tr><tr><td>대표 시세</td><td>여러 거래를 비교하기 위한 현재 기준값</td><td>현재 비교 기준</td></tr><tr><td>예상가</td><td>목표 시점에서 비교할 중심 결과</td><td>조건을 둔 참고 결과</td></tr><tr><td>예상 범위</td><td>조건 변화에 따라 가능한 가격의 폭</td><td>확정 가격이 아닌 범위</td></tr></tbody></table>\n<p>메시지에 “내년 가격은 이거야”라고 적기보다 “전용 84㎡ 기준으로 최근 거래와 12개월 예상 범위를 함께 본 결과”처럼 적는 편이 정확합니다. 예상 범위의 아래·가운데·위 값을 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 가격 예측 결과의 아래·가운데·위 값 읽는 법</a>에서 확인할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-기준일과-조회일을-함께-보냅니다\">3. 기준일과 조회일을 함께 보냅니다<a href=\"https://alvin.ing/blog/apartment-analysis-share-url#3-%EA%B8%B0%EC%A4%80%EC%9D%BC%EA%B3%BC-%EC%A1%B0%ED%9A%8C%EC%9D%BC%EC%9D%84-%ED%95%A8%EA%BB%98-%EB%B3%B4%EB%83%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 기준일과 조회일을 함께 보냅니다에 대한 직접 링크\" title=\"3. 기준일과 조회일을 함께 보냅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공유 URL은 생성한 순간의 결과를 전달하는 용도이므로, 링크를 보낸 날짜와 화면 속 자료 기준일을 구분해야 합니다. 특히 실거래는 계약일·신고일·공개일 사이에 시간차가 있을 수 있습니다.</p>\n<p>공유 메시지에 다음 두 날짜를 같이 적어 보세요.</p>\n<ul>\n<li class=\"\"><strong>조회일</strong>: 내가 링크를 만들고 확인한 날짜</li>\n<li class=\"\"><strong>자료 기준일</strong>: 최근 거래와 시장 정보가 어떤 시점까지 반영됐는지 읽는 기준</li>\n</ul>\n<p>며칠 또는 몇 주 뒤에 같은 단지의 결과가 달라졌다면 이전 링크가 틀린 값이 되었다는 뜻은 아닙니다. 새 거래, 평형 변경, 목표 시점 변경, 시장 정보 갱신처럼 비교 조건이 달라졌을 수 있습니다. 기준일과 표본 상태를 확인하는 순서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">아파트 가격 예측 결과에서 기준일·시장 정보·표본 신뢰도 읽는 법</a>에 정리했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-공개-기간과-중지-상태를-확인합니다\">4. 공개 기간과 중지 상태를 확인합니다<a href=\"https://alvin.ing/blog/apartment-analysis-share-url#4-%EA%B3%B5%EA%B0%9C-%EA%B8%B0%EA%B0%84%EA%B3%BC-%EC%A4%91%EC%A7%80-%EC%83%81%ED%83%9C%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 공개 기간과 중지 상태를 확인합니다에 대한 직접 링크\" title=\"4. 공개 기간과 중지 상태를 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공유 주소를 아는 사람은 로그인하지 않고도 결과를 확인할 수 있습니다. 따라서 링크를 만들기 전에 화면에 표시되는 공개 기간을 확인하고, 더 이상 보여 줄 필요가 없으면 공유 설정에서 중지하세요.</p>\n<p>공유하려는 내용도 다시 한 번 살펴봅니다. 공유 화면은 단지와 가격 흐름을 함께 논의하기 위한 것이지, 개인의 대출·현금·거주 계획을 모두 공개하는 공간이 아닙니다. 전달 메시지에 개인 상황을 덧붙여야 한다면 링크와 분리해 필요한 범위만 직접 설명하는 편이 좋습니다.</p>\n<p>공유 설정에서는 공개 중인 링크의 상태를 확인하고, 더 이상 필요하지 않은 주소를 중지할 수 있습니다. 기간과 생성 한도는 계정 상태와 기존 링크에 따라 다를 수 있으므로, 공유하기 직전 화면에 표시된 안내를 기준으로 확인하세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-계약-판단-대신-다음-질문을-남깁니다\">5. 계약 판단 대신 다음 질문을 남깁니다<a href=\"https://alvin.ing/blog/apartment-analysis-share-url#5-%EA%B3%84%EC%95%BD-%ED%8C%90%EB%8B%A8-%EB%8C%80%EC%8B%A0-%EB%8B%A4%EC%9D%8C-%EC%A7%88%EB%AC%B8%EC%9D%84-%EB%82%A8%EA%B9%81%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"5. 계약 판단 대신 다음 질문을 남깁니다에 대한 직접 링크\" title=\"5. 계약 판단 대신 다음 질문을 남깁니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>좋은 공유는 결론을 대신 내리는 링크가 아니라, 함께 확인할 질문을 남깁니다. 아래처럼 전달하면 대화를 시작하기 좋습니다.</p>\n<blockquote>\n<p>전용 84㎡ 기준 결과입니다. 최근 거래와 12개월 예상 범위를 같이 봤고, 계약 전에는 같은 조건의 최신 실거래와 대출·거래비용을 추가로 확인해 보려고 합니다.</p>\n</blockquote>\n<p>링크를 받은 뒤에는 <a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>에서 계약일, 전용면적, 층, 해제·정정 여부를 다시 확인하세요. 가격 전망의 범위는 계약 가능 가격이나 수익을 보장하지 않으며, 개인의 대출 한도·세금·이사 일정까지 대신 판단하지 않습니다.</p>\n<p>아파트 분석을 처음 시작한다면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-insights-start-guide\">지역·단지·이사 시점을 입력하는 순서</a>부터 읽고, 가입 없이 현재 기준과 예상 범위를 확인하려면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a>를 이어서 보세요.</p>\n<blockquote>\n<p>아파트 인사이트의 공유 결과는 공개 데이터와 시장 조건을 바탕으로 한 참고용 분석입니다. 투자 권유나 매수·매도 추천이 아니며, 미래 가격·거래 가능성·수익을 보장하지 않습니다. 주소를 받은 사람이 누구인지와 공유 화면의 공개 상태를 확인하고, 최종 계약 전에는 최신 공식 자료와 개인 조건을 별도로 검토하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-analysis-share-url",
            "title": "아파트 분석 공유 URL을 보내기 전 확인할 5가지",
            "summary": "아파트 실거래 흐름과 가격 전망을 공유 URL로 보낼 때 평형·기준일·예상 범위·공개 기간을 확인하고 오해 없이 설명하는 방법을 정리합니다.",
            "date_modified": "2026-09-07T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-insights-start-guide",
            "content_html": "<p>아파트 가격을 비교하려고 할 때 가장 먼저 필요한 것은 더 많은 숫자가 아니라 <strong>같은 질문을 계속 비교할 수 있는 기준</strong>입니다. 관심 지역이 바뀌고, 단지·평형·이사 시점이 섞이면 실거래가와 예상 범위를 여러 번 봐도 무엇이 달라졌는지 알기 어렵습니다.</p>\n<p>이 글은 아파트 인사이트에서 분석을 시작할 때 지역·단지·평형·이사 시점을 어떤 순서로 정하면 좋은지 안내합니다. 특정 단지의 매수·매도를 권하는 글이 아니라, 공개 실거래와 분석 결과를 같은 조건에서 읽기 위한 준비 과정입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"시작-전에-적어-둘-네-가지\">시작 전에 적어 둘 네 가지<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#%EC%8B%9C%EC%9E%91-%EC%A0%84%EC%97%90-%EC%A0%81%EC%96%B4-%EB%91%98-%EB%84%A4-%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"시작 전에 적어 둘 네 가지에 대한 직접 링크\" title=\"시작 전에 적어 둘 네 가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>입력 화면을 열기 전에 아래 네 가지를 짧게 메모해 두면 검색 결과를 비교하기 쉬워집니다.</p>\n<table><thead><tr><th>항목</th><th>먼저 정할 내용</th><th>필요한 이유</th></tr></thead><tbody><tr><td>지역</td><td>시·도와 시·군·구</td><td>같은 이름의 단지나 비슷한 이름을 구분합니다.</td></tr><tr><td>단지</td><td>공식 단지명과 주소</td><td>검색 결과가 관심 단지와 같은지 대조합니다.</td></tr><tr><td>평형</td><td>전용면적 또는 비교할 평형</td><td>면적이 다른 거래를 한 가격처럼 읽지 않습니다.</td></tr><tr><td>이사 시점</td><td>계약·잔금 또는 이사 목표 월</td><td>현재 거래와 미래 예상의 비교 기간을 고정합니다.</td></tr></tbody></table>\n<p>네 값은 한 번 정하면 바꾸면 안 되는 규칙이 아닙니다. 비교 대상을 바꿨을 때 무엇을 바꿨는지 남기기 위한 기준입니다. 예를 들어 84㎡를 보다가 59㎡로 전환했다면, 가격 차이를 시장 변화로 해석하기 전에 평형이 달라졌다는 사실부터 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-지역부터-고르는-이유\">1. 지역부터 고르는 이유<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#1-%EC%A7%80%EC%97%AD%EB%B6%80%ED%84%B0-%EA%B3%A0%EB%A5%B4%EB%8A%94-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"1. 지역부터 고르는 이유에 대한 직접 링크\" title=\"1. 지역부터 고르는 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지명에 인기 브랜드나 공통 단어가 들어가면 비슷한 결과가 여러 지역에서 나올 수 있습니다. 단지명을 먼저 검색해도 되지만, 지역을 선행하면 검색 결과의 주소와 단지명을 함께 대조할 수 있습니다.</p>\n<p>확인할 내용은 세 가지입니다.</p>\n<ol>\n<li class=\"\">내가 찾는 시·군·구가 맞는지</li>\n<li class=\"\">단지 주소와 생활권이 내가 생각한 곳과 맞는지</li>\n<li class=\"\">같은 이름의 다른 단지를 선택하지 않았는지</li>\n</ol>\n<p>지역을 넓게 잡아 비교할 때도 기준을 따로 둡니다. 예를 들어 “서울 전체”와 “특정 구”의 거래량·매수심리·공급 정보를 같은 성격의 숫자로 보지 않고, 어느 범위의 정보인지 함께 기록합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-단지와-평형을-한-묶음으로-확인하기\">2. 단지와 평형을 한 묶음으로 확인하기<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#2-%EB%8B%A8%EC%A7%80%EC%99%80-%ED%8F%89%ED%98%95%EC%9D%84-%ED%95%9C-%EB%AC%B6%EC%9D%8C%EC%9C%BC%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"2. 단지와 평형을 한 묶음으로 확인하기에 대한 직접 링크\" title=\"2. 단지와 평형을 한 묶음으로 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지 이름만 같아도 전용면적, 동·층, 타입, 거래 시점에 따라 가격은 달라질 수 있습니다. 그래서 분석 결과나 실거래가를 볼 때는 단지명 옆의 평형을 바로 확인하는 습관이 필요합니다.</p>\n<p>다음 순서로 보면 됩니다.</p>\n<ol>\n<li class=\"\">검색 결과의 단지명과 주소를 확인합니다.</li>\n<li class=\"\">화면에서 선택된 전용면적 또는 평형을 확인합니다.</li>\n<li class=\"\">최근 거래가 같은 면적에서 나온 값인지 살펴봅니다.</li>\n<li class=\"\">다른 평형을 비교할 때는 가격을 바로 연결하지 않고 면적 조건이 달라졌다고 표시합니다.</li>\n</ol>\n<p>최근 거래가 한 건뿐이거나 조건이 섞여 있으면 대표 시세처럼 단정하지 않는 것이 좋습니다. 거래 건수와 층·거래 유형을 확인하는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a>에서 더 자세히 다룹니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-이사-시점은-가격-숫자와-분리해서-기록하기\">3. 이사 시점은 가격 숫자와 분리해서 기록하기<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#3-%EC%9D%B4%EC%82%AC-%EC%8B%9C%EC%A0%90%EC%9D%80-%EA%B0%80%EA%B2%A9-%EC%88%AB%EC%9E%90%EC%99%80-%EB%B6%84%EB%A6%AC%ED%95%B4%EC%84%9C-%EA%B8%B0%EB%A1%9D%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"3. 이사 시점은 가격 숫자와 분리해서 기록하기에 대한 직접 링크\" title=\"3. 이사 시점은 가격 숫자와 분리해서 기록하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이사 시점은 “언제 계약할지”, “언제 잔금을 치를지”, “언제 실제로 입주할지” 중 무엇을 뜻하는지에 따라 다르게 적을 수 있습니다. 분석을 시작할 때는 우선 내가 비교하려는 목표 월을 하나 정하고, 그 월이 계약·잔금·입주 중 어디에 가까운지 메모하는 편이 좋습니다.</p>\n<p>이 기준이 있으면 6개월·12개월·18개월 결과도 같은 질문으로 비교할 수 있습니다. 기간이 다르면 예상 범위의 폭과 조건도 달라질 수 있으므로, 결과의 가운데 값만 나란히 놓고 방향을 단정하면 안 됩니다.</p>\n<p><a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 아파트 전망을 비교할 때 확인할 것</a>에서 기간별로 어떤 질문을 해야 하는지 이어서 확인할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-결과-화면에서는-기준일을-먼저-보기\">4. 결과 화면에서는 기준일을 먼저 보기<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#4-%EA%B2%B0%EA%B3%BC-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C%EB%8A%94-%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9D%84-%EB%A8%BC%EC%A0%80-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"4. 결과 화면에서는 기준일을 먼저 보기에 대한 직접 링크\" title=\"4. 결과 화면에서는 기준일을 먼저 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지와 평형, 목표 시점을 정했다면 숫자를 읽기 전에 기준일을 봅니다. 화면을 오늘 열었다고 해서 모든 실거래와 시장 정보가 오늘 기준이라는 뜻은 아닙니다. 실거래는 계약·신고·공개 시점이 다를 수 있고, 시장 정보도 지표별 갱신 주기가 다릅니다.</p>\n<p>아래 네 항목을 한 줄로 기록해 보세요.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">조회일: 화면을 확인한 날짜</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">단지·평형: 비교한 단지와 전용면적</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">최근 거래일: 현재 기준에 포함된 최신 거래 시점</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">목표 시점: 비교하려는 계약·잔금 또는 이사 목표 월</span><br></div></code></pre></div></div>\n<p>결과가 바뀌었을 때 이 기록이 있으면 새 거래가 반영됐는지, 평형이나 기간을 바꿨는지, 시장 정보가 갱신됐는지 순서대로 확인할 수 있습니다. 기준일·시장 정보·표본 상태의 역할은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">아파트 가격 예측 결과에서 기준일·시장 정보·표본 신뢰도 읽는 법</a>에서 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-공식-실거래-자료와-나란히-보기\">5. 공식 실거래 자료와 나란히 보기<a href=\"https://alvin.ing/blog/apartment-insights-start-guide#5-%EA%B3%B5%EC%8B%9D-%EC%8B%A4%EA%B1%B0%EB%9E%98-%EC%9E%90%EB%A3%8C%EC%99%80-%EB%82%98%EB%9E%80%ED%9E%88-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"5. 공식 실거래 자료와 나란히 보기에 대한 직접 링크\" title=\"5. 공식 실거래 자료와 나란히 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>분석 화면은 비교할 항목을 한곳에 모아 보는 출발점입니다. 계약 전에 필요한 거래 조건은 공식 자료에서 다시 확인해야 합니다.</p>\n<ul>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>에서 계약일, 전용면적, 층, 거래금액과 해제·정정 여부를 확인합니다.</li>\n<li class=\"\">같은 단지라도 면적·층·거래 유형이 다른 가격을 한 줄로 합치지 않습니다.</li>\n<li class=\"\">공개 실거래와 분석 결과의 기준일이 다르면 어느 한쪽을 오류로 단정하기 전에 기준일과 표본 조건을 비교합니다.</li>\n</ul>\n<p>아파트 인사이트에서 관심 단지를 비교할 때도 결과를 매수·매도 신호로 바꾸기보다, 다음에 확인할 자료를 정하는 참고값으로 사용하세요. 최근 대표 시세와 예상 범위를 함께 보는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a>에서 이어집니다.</p>\n<blockquote>\n<p>아파트 인사이트의 분석 결과는 공개 데이터와 시장 조건을 바탕으로 비교하는 참고 정보입니다. 미래 가격, 거래 가능성, 수익을 보장하지 않으며 투자 권유나 매수·매도 추천이 아닙니다. 최종 계약 전에는 최신 공식 자료와 개인의 자금·거주 조건을 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-insights-start-guide",
            "title": "아파트 인사이트 처음 시작하기: 지역·단지·이사 시점을 입력하는 순서",
            "summary": "아파트 분석을 시작할 때 지역, 단지, 평형, 이사 시점을 먼저 정하는 이유와 실거래가·예상 범위를 같은 기준으로 비교하는 방법을 정리합니다.",
            "date_modified": "2026-09-07T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-price-forecast-without-signup",
            "content_html": "<p>“우리 아파트의 1년 뒤 가격을 먼저 확인해 보고 싶다”는 질문에 회원가입부터 요구하면, 결과를 보기 전에 사용자가 이탈하기 쉽습니다. 반대로 가입 없이 결과를 볼 수 있다고 해서 숫자 하나만 보여주면 그 숫자가 어떤 거래와 기준일에서 나온 것인지 알기 어렵습니다.</p>\n<p>이 글은 가입 없이 아파트 가격을 확인할 때 실제로 어떤 순서로 검색하고, 결과 화면에서 무엇을 확인해야 하는지 설명합니다. 핵심은 간단합니다. <strong>단지명만 검색하지 말고 지역·평형·최근 거래·기준일을 한 묶음으로 읽어야 합니다.</strong></p>\n<p>아파트 가격 예측은 미래 가격을 확정하는 기능이 아닙니다. 공개된 실거래와 시장 정보를 현재 시점에서 비교하고, 앞으로의 가능한 가격 범위를 살펴보는 참고 도구입니다. 계약금이나 대출 한도를 정하기 전에 사용하는 최종 답안이 아니라, 더 확인해야 할 질문을 찾는 첫 단계에 가깝습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"먼저-알아둘-것-가입-없이-볼-수-있는-것과-없는-것\">먼저 알아둘 것: 가입 없이 볼 수 있는 것과 없는 것<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EB%A8%BC%EC%A0%80-%EC%95%8C%EC%95%84%EB%91%98-%EA%B2%83-%EA%B0%80%EC%9E%85-%EC%97%86%EC%9D%B4-%EB%B3%BC-%EC%88%98-%EC%9E%88%EB%8A%94-%EA%B2%83%EA%B3%BC-%EC%97%86%EB%8A%94-%EA%B2%83\" class=\"hash-link\" aria-label=\"먼저 알아둘 것: 가입 없이 볼 수 있는 것과 없는 것에 대한 직접 링크\" title=\"먼저 알아둘 것: 가입 없이 볼 수 있는 것과 없는 것에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>가입 없이 이용하는 공개 체험은 관심 단지의 기본 상황을 빠르게 확인하는 데 초점을 둡니다. 지역과 단지를 검색하고, 자료가 준비된 경우 최근 대표 시세와 12개월 뒤 예상가, 예상 범위, 표본 신뢰도, 시장 정보 기준일을 확인할 수 있습니다.</p>\n<p>반면 다음 질문은 공개 결과만으로 답하기 어렵습니다.</p>\n<table><thead><tr><th>공개 결과로 확인할 수 있는 내용</th><th>별도로 확인해야 하는 내용</th></tr></thead><tbody><tr><td>최근 대표 시세와 기준 평형</td><td>내 대출 한도와 월 상환액</td></tr><tr><td>12개월 뒤 예상가와 예상 범위</td><td>실제 계약 가능한 가격과 협상 조건</td></tr><tr><td>표본 신뢰도와 시장 정보 기준일</td><td>세금·중개보수·수리비를 포함한 총자금</td></tr><tr><td>단지의 공개 체험 가능 여부</td><td>개인의 거주·이사 일정에 맞는 선택</td></tr></tbody></table>\n<p>이 구분을 먼저 해 두면 “예측값이 나왔으니 매수해도 된다”거나 “범위가 넓으니 아무 의미가 없다”는 식의 극단적인 해석을 피할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가입-없이-아파트-가격을-확인하는-5단계\">가입 없이 아파트 가격을 확인하는 5단계<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B0%80%EC%9E%85-%EC%97%86%EC%9D%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-5%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"가입 없이 아파트 가격을 확인하는 5단계에 대한 직접 링크\" title=\"가입 없이 아파트 가격을 확인하는 5단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-시군구를-먼저-선택합니다\">1. 시군구를 먼저 선택합니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#1-%EC%8B%9C%EA%B5%B0%EA%B5%AC%EB%A5%BC-%EB%A8%BC%EC%A0%80-%EC%84%A0%ED%83%9D%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 시군구를 먼저 선택합니다에 대한 직접 링크\" title=\"1. 시군구를 먼저 선택합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>단지명을 바로 입력하기보다 시군구를 먼저 고르는 편이 정확합니다. 같은 이름의 아파트가 다른 지역에 있을 수 있고, 비슷한 이름의 단지가 여러 곳 검색될 수 있기 때문입니다.</p>\n<p>예를 들어 “센트럴”이나 “자이”처럼 여러 지역에 반복되는 이름은 단지명만으로 구분하기 어렵습니다. 지역을 선택한 뒤 검색하면 결과에서 지역과 단지명을 함께 대조할 수 있어 잘못된 단지를 선택할 가능성이 줄어듭니다.</p>\n<p>검색 전에 다음 세 가지를 메모해 두면 좋습니다.</p>\n<ul>\n<li class=\"\">시·도와 시·군·구</li>\n<li class=\"\">검색하려는 아파트의 공식 단지명</li>\n<li class=\"\">확인하려는 전용면적 또는 평형</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-단지의-자료-상태를-확인합니다\">2. 단지의 자료 상태를 확인합니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#2-%EB%8B%A8%EC%A7%80%EC%9D%98-%EC%9E%90%EB%A3%8C-%EC%83%81%ED%83%9C%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 단지의 자료 상태를 확인합니다에 대한 직접 링크\" title=\"2. 단지의 자료 상태를 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>검색 결과에 단지명이 보인다고 해서 모든 단지의 가격 전망을 즉시 볼 수 있는 것은 아닙니다. 공개 체험에서는 자료가 준비되어 결과를 확인할 수 있는 단지와, 이름은 검색되지만 자료 준비가 더 필요한 단지가 구분될 수 있습니다.</p>\n<p>자료가 준비되지 않은 경우에는 주변 단지의 숫자를 대신 보여주지 않습니다. 해당 단지와 다른 면적·연식·입지의 가격을 복사하면 그럴듯한 숫자는 만들 수 있지만, 실제 관심 단지의 시세라고 부르기 어렵기 때문입니다.</p>\n<p>이때 표시되는 등록 요청은 “요청 즉시 예측이 생성된다”는 뜻이 아닙니다. 단지 정보와 실거래 자료를 확인하고 공개 체험에 사용할 수 있는 상태가 되면 다시 확인하는 흐름입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-자동으로-선택된-평형을-확인합니다\">3. 자동으로 선택된 평형을 확인합니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#3-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%84%A0%ED%83%9D%EB%90%9C-%ED%8F%89%ED%98%95%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 자동으로 선택된 평형을 확인합니다에 대한 직접 링크\" title=\"3. 자동으로 선택된 평형을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>단지를 선택하면 화면은 최근 거래가 확인되는 대표 평형을 자동으로 선택합니다. 사용 가능한 다른 평형에 거래 자료가 있다면 평형을 바꿔 결과를 비교할 수 있습니다.</p>\n<p>여기서 가장 흔한 실수는 “단지 가격”을 하나의 숫자로 생각하는 것입니다. 전용면적이 59㎡인지 84㎡인지, 같은 면적이라도 층과 타입이 어떤지에 따라 비교해야 할 거래가 달라집니다. 결과 화면의 평형 탭을 먼저 확인한 뒤 가격을 읽어야 합니다.</p>\n<p>평형을 바꿀 때는 다음 질문을 함께 적어 보세요.</p>\n<ol>\n<li class=\"\">내가 찾는 면적과 현재 선택된 면적이 같은가?</li>\n<li class=\"\">최근 거래가 해당 면적에서 실제로 확인되는가?</li>\n<li class=\"\">작은 면적의 거래를 큰 면적의 가격처럼 비교하고 있지는 않은가?</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-최근-대표-시세와-예상-범위를-함께-봅니다\">4. 최근 대표 시세와 예상 범위를 함께 봅니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#4-%EC%B5%9C%EA%B7%BC-%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EC%99%80-%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EB%A5%BC-%ED%95%A8%EA%BB%98-%EB%B4%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 최근 대표 시세와 예상 범위를 함께 봅니다에 대한 직접 링크\" title=\"4. 최근 대표 시세와 예상 범위를 함께 봅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>결과 카드에는 보통 다음 정보가 함께 표시됩니다.</p>\n<table><thead><tr><th>표시 항목</th><th>의미</th></tr></thead><tbody><tr><td>최근 대표 시세</td><td>최근 유효 거래를 비교하기 위한 현재 기준값</td></tr><tr><td>12개월 뒤 예상가</td><td>현재 기준에서 1년 뒤를 바라본 중심 결과</td></tr><tr><td>예상 범위</td><td>조건 변화에 따라 달라질 수 있는 가격의 폭</td></tr><tr><td>변화율</td><td>최근 대표 시세와 예상가를 비교한 비율</td></tr></tbody></table>\n<p>가운데 숫자인 예상가만 크게 보는 것보다 대표 시세와 범위를 같이 보는 편이 안전합니다. 예를 들어 예상가가 현재보다 높게 표시되어도 범위의 아래쪽이 현재 가격과 비슷하다면, “반드시 오른다”가 아니라 여러 조건 중 일부에서는 변화가 제한적일 수 있다는 뜻으로 읽어야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-표본-신뢰도와-시장-정보-기준일을-확인합니다\">5. 표본 신뢰도와 시장 정보 기준일을 확인합니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#5-%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84%EC%99%80-%EC%8B%9C%EC%9E%A5-%EC%A0%95%EB%B3%B4-%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"5. 표본 신뢰도와 시장 정보 기준일을 확인합니다에 대한 직접 링크\" title=\"5. 표본 신뢰도와 시장 정보 기준일을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>결과 카드의 아래쪽에는 표본 신뢰도와 시장 정보 기준일이 표시될 수 있습니다. 표본 신뢰도는 예측이 맞을 확률이나 수익률이 아닙니다. 해당 단지의 거래 자료를 얼마나 안정적으로 비교할 수 있는지 판단하는 보조 정보입니다.</p>\n<p>시장 정보에는 금리, 환율, 지역 매수심리처럼 계산 시점에 함께 확인한 정보가 포함될 수 있습니다. 각 값은 같은 날 갱신되지 않을 수 있으므로 정보 옆의 기준일을 같이 봐야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가상의-결과를-읽어-보는-예시\">가상의 결과를 읽어 보는 예시<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B0%80%EC%83%81%EC%9D%98-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EC%9D%BD%EC%96%B4-%EB%B3%B4%EB%8A%94-%EC%98%88%EC%8B%9C\" class=\"hash-link\" aria-label=\"가상의 결과를 읽어 보는 예시에 대한 직접 링크\" title=\"가상의 결과를 읽어 보는 예시에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음은 특정 단지의 실제 결과가 아닌 이해를 위한 가상 예시입니다.</p>\n<table><thead><tr><th>항목</th><th style=\"text-align:right\">가상 표시값</th></tr></thead><tbody><tr><td>선택 평형</td><td style=\"text-align:right\">전용 84㎡</td></tr><tr><td>최근 대표 시세</td><td style=\"text-align:right\">10억 원</td></tr><tr><td>12개월 뒤 예상가</td><td style=\"text-align:right\">10억 4,000만 원</td></tr><tr><td>예상 범위</td><td style=\"text-align:right\">9억 5,000만 원 ~ 11억 2,000만 원</td></tr><tr><td>표본 신뢰도</td><td style=\"text-align:right\">결과 해석용 참고 지표</td></tr></tbody></table>\n<p>이 표를 보고 “1년 뒤 10억 4,000만 원에 거래된다”고 결론 내리면 안 됩니다. 먼저 10억 원이 어떤 평형과 최근 거래를 기준으로 한 값인지 확인하고, 9억 5,000만 원에서 11억 2,000만 원까지 폭이 생긴 이유를 생각해야 합니다.</p>\n<p>또한 이 값은 대출이자, 취득세, 중개보수, 인테리어 비용을 포함하지 않습니다. 내 통장에 필요한 금액을 계산하려면 가격 전망과 별도로 거래비용과 현금흐름을 계산해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공식-실거래-자료와-함께-확인하는-방법\">공식 실거래 자료와 함께 확인하는 방법<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B3%B5%EC%8B%9D-%EC%8B%A4%EA%B1%B0%EB%9E%98-%EC%9E%90%EB%A3%8C%EC%99%80-%ED%95%A8%EA%BB%98-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"공식 실거래 자료와 함께 확인하는 방법에 대한 직접 링크\" title=\"공식 실거래 자료와 함께 확인하는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>예측 화면을 본 뒤에는 공식 자료에서 최근 거래를 다시 확인해 보세요.</p>\n<ol>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>에서 지역과 단지를 찾습니다.</li>\n<li class=\"\">전용면적과 계약일이 같은 거래를 우선 확인합니다.</li>\n<li class=\"\">층, 거래 유형, 해제·정정 여부를 함께 확인합니다.</li>\n<li class=\"\">공개 체험 화면의 대표 시세와 비교하되, 두 값이 다르다고 즉시 오류로 판단하지 않습니다.</li>\n</ol>\n<p>단지별 최근 거래를 평형 단위로 정리해 둔 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a> 페이지를 함께 쓰면 대조가 더 빠릅니다. 예측 결과 화면의 “이 단지 실거래 전체 보기”를 누르면 같은 단지의 실거래 페이지로 이어집니다. 조회 순서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region\">지역별 아파트 실거래가 조회하는 법</a>에 정리했습니다.</p>\n<p>공식 실거래가는 계약일·신고·공개 시점의 차이가 있을 수 있습니다. 따라서 “가장 최근에 보이는 한 건”과 “현재 대표 시세”는 서로 다른 질문에 답할 수 있습니다. 최근 거래 한 건을 해석하는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a>에서 더 자세히 다룹니다.</p>\n<p>예측 결과가 어떤 원리로 범위를 보여주는지 궁금하다면 <a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 미래가격 예측 공식 가이드</a>도 함께 읽어 보세요. 공개 설명과 실제 결과 화면을 이어서 보면 숫자의 역할을 구분하기 쉽습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"앱에서는-로그인-없이-목표-월까지-고를-수-있습니다\">앱에서는 로그인 없이 목표 월까지 고를 수 있습니다<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EC%95%B1%EC%97%90%EC%84%9C%EB%8A%94-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%97%86%EC%9D%B4-%EB%AA%A9%ED%91%9C-%EC%9B%94%EA%B9%8C%EC%A7%80-%EA%B3%A0%EB%A5%BC-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"앱에서는 로그인 없이 목표 월까지 고를 수 있습니다에 대한 직접 링크\" title=\"앱에서는 로그인 없이 목표 월까지 고를 수 있습니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>휴대폰에서 확인한다면 아파트 인사이트 앱도 로그인 없이 시작할 수 있습니다. 앱에서는 아파트 1곳·평형 1개·목표 월 1개를 고르면 해당 시점의 전망과 최근 12개월 실거래, 교통·학군·생활 인프라 같은 단지 정보를 볼 수 있습니다. 선택은 계정 없이 기기에만 저장됩니다.</p>\n<p>웹 체험이 “1년 뒤”라는 고정된 시점을 보여준다면, 앱은 이사·매수 계획에 맞춘 달을 직접 고를 수 있다는 점이 다릅니다. 자세한 흐름은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-app-guest-mode\">로그인 없이 아파트 시세 앱 쓰는 법</a>에서 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"로그인은-언제-필요한가요\">로그인은 언제 필요한가요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EB%A1%9C%EA%B7%B8%EC%9D%B8%EC%9D%80-%EC%96%B8%EC%A0%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"로그인은 언제 필요한가요?에 대한 직접 링크\" title=\"로그인은 언제 필요한가요?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공개 체험은 “일단 이 단지의 현재 자료와 1년 전망을 확인해 보고 싶다”는 상황에 맞습니다. 여러 관심 단지를 저장하거나, 내 이사 시점·보유 조건·금리 조건을 바꿔 비교하거나, 변경 알림을 받아야 한다면 로그인 후 개인화 기능이 필요할 수 있습니다.</p>\n<p>공개 결과를 본 뒤 바로 가입해야 하는 것은 아닙니다. 다음 순서가 자연스럽습니다.</p>\n<ul>\n<li class=\"\">먼저 공개 체험에서 단지와 평형이 맞는지 확인합니다.</li>\n<li class=\"\">결과의 기준일과 범위를 기록합니다.</li>\n<li class=\"\">더 긴 기간이나 개인 조건이 필요할 때 로그인 기능을 검토합니다.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가입-없이-모든-아파트를-조회할-수-있나요\">가입 없이 모든 아파트를 조회할 수 있나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B0%80%EC%9E%85-%EC%97%86%EC%9D%B4-%EB%AA%A8%EB%93%A0-%EC%95%84%ED%8C%8C%ED%8A%B8%EB%A5%BC-%EC%A1%B0%ED%9A%8C%ED%95%A0-%EC%88%98-%EC%9E%88%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"가입 없이 모든 아파트를 조회할 수 있나요?에 대한 직접 링크\" title=\"가입 없이 모든 아파트를 조회할 수 있나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 검색 결과에 표시되는 단지와 즉시 가격 전망을 확인할 수 있는 단지는 다를 수 있습니다. 자료가 준비되지 않은 단지는 등록 요청 안내가 표시될 수 있으며, 다른 단지의 가격을 대신 보여주지 않습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가입-없이-보는-예상가는-확정-가격인가요\">가입 없이 보는 예상가는 확정 가격인가요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B0%80%EC%9E%85-%EC%97%86%EC%9D%B4-%EB%B3%B4%EB%8A%94-%EC%98%88%EC%83%81%EA%B0%80%EB%8A%94-%ED%99%95%EC%A0%95-%EA%B0%80%EA%B2%A9%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"가입 없이 보는 예상가는 확정 가격인가요?에 대한 직접 링크\" title=\"가입 없이 보는 예상가는 확정 가격인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 최근 거래와 시장 정보를 바탕으로 한 참고 결과입니다. 실제 가격은 거래 조건, 금리, 공급, 정책, 지역 수요와 개인 계약 조건에 따라 달라질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"평형을-바꾸면-왜-결과가-달라지나요\">평형을 바꾸면 왜 결과가 달라지나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%ED%8F%89%ED%98%95%EC%9D%84-%EB%B0%94%EA%BE%B8%EB%A9%B4-%EC%99%9C-%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%8B%AC%EB%9D%BC%EC%A7%80%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"평형을 바꾸면 왜 결과가 달라지나요?에 대한 직접 링크\" title=\"평형을 바꾸면 왜 결과가 달라지나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>평형이 달라지면 비교하는 거래 표본과 현재 기준값이 달라지기 때문입니다. 59㎡와 84㎡의 가격을 같은 단지라는 이유만으로 하나의 시세로 합치면 해석이 흔들릴 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과가-나왔는데-표본-신뢰도가-낮으면-어떻게-해야-하나요\">결과가 나왔는데 표본 신뢰도가 낮으면 어떻게 해야 하나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%82%98%EC%99%94%EB%8A%94%EB%8D%B0-%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84%EA%B0%80-%EB%82%AE%EC%9C%BC%EB%A9%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"결과가 나왔는데 표본 신뢰도가 낮으면 어떻게 해야 하나요?에 대한 직접 링크\" title=\"결과가 나왔는데 표본 신뢰도가 낮으면 어떻게 해야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>예상가보다 최근 거래의 수·시점·면적·층 조건을 먼저 확인하세요. 거래가 드문 단지는 새 거래 한 건만 추가되어도 대표 시세와 예상 범위가 달라질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예측이-얼마나-맞는지는-어떻게-알-수-있나요\">예측이 얼마나 맞는지는 어떻게 알 수 있나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EC%98%88%EC%B8%A1%EC%9D%B4-%EC%96%BC%EB%A7%88%EB%82%98-%EB%A7%9E%EB%8A%94%EC%A7%80%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%95%8C-%EC%88%98-%EC%9E%88%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"예측이 얼마나 맞는지는 어떻게 알 수 있나요?에 대한 직접 링크\" title=\"예측이 얼마나 맞는지는 어떻게 알 수 있나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>과거 기준일로 돌아가 다시 예측한 뒤 실제 거래와 비교하는 백테스트 결과를 확인하세요. 평균 오차율·중간 오차율·예상 범위 적중률을 어떻게 읽는지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest\">아파트 가격 예측, 맞았는지 확인하는 법</a>에서 정리했습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트는-매수나-매도를-추천하나요\">아파트 인사이트는 매수나 매도를 추천하나요?<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EB%8A%94-%EB%A7%A4%EC%88%98%EB%82%98-%EB%A7%A4%EB%8F%84%EB%A5%BC-%EC%B6%94%EC%B2%9C%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"아파트 인사이트는 매수나 매도를 추천하나요?에 대한 직접 링크\" title=\"아파트 인사이트는 매수나 매도를 추천하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아니요. 아파트 인사이트는 공개 데이터와 시장 정보를 바탕으로 가격 흐름을 비교하는 참고 도구입니다. 대출, 세금, 거주 필요성, 계약 조건을 포함한 최종 판단은 별도로 해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-직접-확인하기\">아파트 인사이트에서 직접 확인하기<a href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EC%A7%81%EC%A0%91-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 직접 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 직접 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이제 관심 단지를 실제 화면에서 확인해 보세요. <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 가입 없는 공개 예측</a>에서 시군구와 단지명을 검색하면 대표 시세와 1년 뒤 예상 범위를 확인할 수 있습니다. 최근 거래부터 보고 싶다면 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>에서 시군구를 먼저 골라 보세요.</p>\n<p>기간을 바꿔 비교할 때는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 전망 비교</a>, 범위의 폭을 해석할 때는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위 읽는 법</a>, 날짜와 자료 상태를 확인할 때는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">기준일·시장 정보·표본 신뢰도 읽는 법</a>을 이어서 보세요.</p>\n<p>처음부터 가격과 거래 조건을 같은 기준으로 확인하려면 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>에서 전체 체크리스트를 먼저 읽어 보세요.</p>\n<blockquote>\n<p>아파트 인사이트의 공개 예측은 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석입니다. 예측값과 가격 범위는 실제 결과와 다를 수 있으며 가격·거래 가능성·수익을 보장하지 않습니다. 투자 권유나 투자 자문이 아니며, 계약과 최종 판단 전에는 최신 공식 자료와 개인의 자금 조건을 별도로 확인해야 합니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-price-forecast-without-signup",
            "title": "가입 없이 아파트 가격 예측하기: 검색부터 결과 해석까지",
            "summary": "가입 없이 아파트 단지를 검색하고 최근 대표 시세와 1년 뒤 예상 범위를 확인하는 방법을 설명합니다. 웹 체험과 앱의 로그인 없는 이용 방법, 평형·거래 표본·기준일을 함께 읽는 순서도 정리합니다.",
            "date_modified": "2026-09-01T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-forecast-periods",
            "content_html": "<p>아파트 가격 전망에서 “얼마나 오를까요?”만큼 중요한 질문이 있습니다. <strong>언제의 가격을 묻는 것인가요?</strong> 6개월 뒤와 18개월 뒤는 같은 단지라도 전혀 다른 계획을 검토하는 시간입니다.</p>\n<p>기간을 길게 고르면 더 먼 미래를 볼 수 있지만, 그만큼 금리·공급·정책·거래 환경이 바뀔 시간도 길어집니다. 그래서 6개월·12개월·18개월 결과를 순위표처럼 놓고 가장 높은 숫자를 고르는 방식은 적절하지 않습니다. 먼저 각 기간이 내 질문과 맞는지 확인하고, 같은 기준일과 같은 평형에서 예상 범위를 함께 비교해야 합니다.</p>\n<p>이 글에서는 아파트 인사이트의 공개 12개월 체험과 로그인 후 조건 비교에서 볼 수 있는 기간별 결과를 어떤 순서로 읽을지 설명합니다. 기간별 전망은 매수·매도 시점을 알려주는 신호가 아니라, 서로 다른 일정과 가정을 비교하는 도구입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6개월12개월18개월은-서로-다른-질문입니다\">6개월·12개월·18개월은 서로 다른 질문입니다<a href=\"https://alvin.ing/blog/apartment-forecast-periods#6%EA%B0%9C%EC%9B%9412%EA%B0%9C%EC%9B%9418%EA%B0%9C%EC%9B%94%EC%9D%80-%EC%84%9C%EB%A1%9C-%EB%8B%A4%EB%A5%B8-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"6개월·12개월·18개월은 서로 다른 질문입니다에 대한 직접 링크\" title=\"6개월·12개월·18개월은 서로 다른 질문입니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>기간</th><th>어울리는 질문</th><th>가장 먼저 볼 항목</th></tr></thead><tbody><tr><td>6개월</td><td>가까운 이사나 계약 일정까지 현재 환경이 어떻게 이어질까?</td><td>최근 거래, 단기 범위, 자금 부담</td></tr><tr><td>12개월</td><td>다음 1년 동안 가능한 가격 경로는 어느 정도일까?</td><td>현재 대표 시세와 1년 뒤 범위</td></tr><tr><td>18개월</td><td>더 긴 일정에서 가격 범위와 조건 변화는 어떻게 보일까?</td><td>범위 폭, 목표 월, 장기 변수</td></tr></tbody></table>\n<p>6개월은 가까운 일정과 비교하기 쉽지만, 단기 거래 한두 건이나 정책 발표에 결과가 민감하게 보일 수 있습니다. 12개월은 연간 계획을 세울 때 이해하기 쉬운 기본 구간입니다. 18개월은 더 긴 미래를 보므로 계획의 여유를 검토하는 데 도움이 되지만, 그 숫자를 현재 계약 가격처럼 해석해서는 안 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간을-바꾸면-목표-월과-비교-조건이-바뀝니다\">기간을 바꾸면 목표 월과 비교 조건이 바뀝니다<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EC%9D%84-%EB%B0%94%EA%BE%B8%EB%A9%B4-%EB%AA%A9%ED%91%9C-%EC%9B%94%EA%B3%BC-%EB%B9%84%EA%B5%90-%EC%A1%B0%EA%B1%B4%EC%9D%B4-%EB%B0%94%EB%80%9D%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"기간을 바꾸면 목표 월과 비교 조건이 바뀝니다에 대한 직접 링크\" title=\"기간을 바꾸면 목표 월과 비교 조건이 바뀝니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>예측 기간은 단순히 화면에 붙은 숫자가 아닙니다. 조회 기준일에서 몇 개월을 이동해 목표 월을 정하고, 그 시점까지의 시장 조건을 비교합니다.</p>\n<p>예를 들어 2026년 9월 1일에 확인한다면 단순한 달력 계산은 다음처럼 됩니다.</p>\n<table><thead><tr><th>확인 기간</th><th>가상의 목표 시점</th></tr></thead><tbody><tr><td>6개월</td><td>2027년 3월 전후</td></tr><tr><td>12개월</td><td>2027년 9월 전후</td></tr><tr><td>18개월</td><td>2028년 3월 전후</td></tr></tbody></table>\n<p>실제 화면의 기준일과 목표 시점은 자료가 갱신되는 시점에 따라 달라질 수 있으므로 결과 카드의 날짜를 직접 확인해야 합니다. “1년 전망”이라고 써 놓고 다른 날짜의 결과를 비교하면 숫자 차이를 기간 효과로 잘못 이해할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간별-결과를-비교할-때-고정해야-할-5가지\">기간별 결과를 비교할 때 고정해야 할 5가지<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EB%B3%84-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EB%B9%84%EA%B5%90%ED%95%A0-%EB%95%8C-%EA%B3%A0%EC%A0%95%ED%95%B4%EC%95%BC-%ED%95%A0-5%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"기간별 결과를 비교할 때 고정해야 할 5가지에 대한 직접 링크\" title=\"기간별 결과를 비교할 때 고정해야 할 5가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기간만 다르게 하고 나머지 조건은 가능한 한 같게 두어야 합니다.</p>\n<ol>\n<li class=\"\"><strong>계산 기준일</strong>: 모든 결과를 같은 조회 시점에서 시작했는가?</li>\n<li class=\"\"><strong>단지와 평형</strong>: 같은 단지의 같은 전용면적을 보고 있는가?</li>\n<li class=\"\"><strong>대표 시세</strong>: 현재 비교 기준이 같은 거래 자료에서 나왔는가?</li>\n<li class=\"\"><strong>목표 월</strong>: 6개월·12개월·18개월의 끝나는 시점이 정확히 언제인가?</li>\n<li class=\"\"><strong>예상 범위</strong>: 중심값만이 아니라 아래쪽과 위쪽의 폭도 함께 변하는가?</li>\n</ol>\n<p>이 중 평형이 바뀌면 단순한 기간 비교가 아닙니다. 59㎡의 6개월 전망과 84㎡의 12개월 전망을 나란히 놓으면 기간뿐 아니라 주택 크기와 거래 표본까지 달라집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공개-체험의-12개월-전망은-비교의-출발점입니다\">공개 체험의 12개월 전망은 비교의 출발점입니다<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B3%B5%EA%B0%9C-%EC%B2%B4%ED%97%98%EC%9D%98-12%EA%B0%9C%EC%9B%94-%EC%A0%84%EB%A7%9D%EC%9D%80-%EB%B9%84%EA%B5%90%EC%9D%98-%EC%B6%9C%EB%B0%9C%EC%A0%90%EC%9E%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"공개 체험의 12개월 전망은 비교의 출발점입니다에 대한 직접 링크\" title=\"공개 체험의 12개월 전망은 비교의 출발점입니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 가입 없는 공개 예측</a>은 지역과 단지를 검색해 대표 시세와 12개월 뒤 예상 결과를 먼저 확인하는 흐름입니다. 회원가입 전에 데이터 상태와 평형을 확인하고 싶을 때 유용한 입구입니다.</p>\n<p>공개 결과를 본 뒤 더 긴 일정이나 개인 조건을 비교하려면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 웹 서비스</a>에서 관심 단지와 조건을 확인할 수 있습니다. 기간 선택이 제공되더라도 결과는 미래 가격을 확정하는 기능이 아니라, 같은 단지에서 시간축을 바꿔 가능한 경로를 비교하는 기능으로 이해해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가상의-기간별-결과를-읽는-방법\">가상의 기간별 결과를 읽는 방법<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B0%80%EC%83%81%EC%9D%98-%EA%B8%B0%EA%B0%84%EB%B3%84-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EC%9D%BD%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"가상의 기간별 결과를 읽는 방법에 대한 직접 링크\" title=\"가상의 기간별 결과를 읽는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음은 실제 단지의 결과가 아닌 해석 방법을 보여주기 위한 예시입니다. 현재 대표 시세는 10억 원이고, 세 기간을 같은 평형과 같은 기준일에서 비교했다고 가정합니다.</p>\n<table><thead><tr><th>기간</th><th style=\"text-align:right\">중심 예상가</th><th style=\"text-align:right\">예상 범위</th><th>해석의 출발점</th></tr></thead><tbody><tr><td>6개월</td><td style=\"text-align:right\">10억 1,000만 원</td><td style=\"text-align:right\">9억 7,000만 ~ 10억 6,000만 원</td><td>가까운 기간의 거래 흐름</td></tr><tr><td>12개월</td><td style=\"text-align:right\">10억 4,000만 원</td><td style=\"text-align:right\">9억 5,000만 ~ 11억 2,000만 원</td><td>1년 계획과 시장 조건</td></tr><tr><td>18개월</td><td style=\"text-align:right\">10억 7,000만 원</td><td style=\"text-align:right\">9억 2,000만 ~ 11억 8,000만 원</td><td>더 긴 기간의 불확실성</td></tr></tbody></table>\n<p>이 예시에서 18개월의 중심값이 가장 높다는 사실만으로 18개월을 선택할 수는 없습니다. 범위의 폭도 넓어졌고, 그 사이에 금리·공급·정책·거래량이 달라질 시간도 많기 때문입니다.</p>\n<p>반대로 6개월의 범위가 좁다고 실제 가격을 더 정확하게 안다는 뜻도 아닙니다. 짧은 기간은 현재 조건과 가까운 만큼 범위가 작아 보일 수 있지만, 새 거래나 갑작스러운 정책 변화가 생기면 결과가 달라질 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"일정에-따라-읽는-방법이-달라집니다\">일정에 따라 읽는 방법이 달라집니다<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EC%9D%BC%EC%A0%95%EC%97%90-%EB%94%B0%EB%9D%BC-%EC%9D%BD%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%9D%B4-%EB%8B%AC%EB%9D%BC%EC%A7%91%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"일정에 따라 읽는 방법이 달라집니다에 대한 직접 링크\" title=\"일정에 따라 읽는 방법이 달라집니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6개월-뒤-전세-만기나-이사를-앞둔-경우\">6개월 뒤 전세 만기나 이사를 앞둔 경우<a href=\"https://alvin.ing/blog/apartment-forecast-periods#6%EA%B0%9C%EC%9B%94-%EB%92%A4-%EC%A0%84%EC%84%B8-%EB%A7%8C%EA%B8%B0%EB%82%98-%EC%9D%B4%EC%82%AC%EB%A5%BC-%EC%95%9E%EB%91%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"6개월 뒤 전세 만기나 이사를 앞둔 경우에 대한 직접 링크\" title=\"6개월 뒤 전세 만기나 이사를 앞둔 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>6개월 전망은 계약 일정과 가까운 시간축입니다. 이때는 예상가보다 다음 항목이 더 중요할 수 있습니다.</p>\n<ul>\n<li class=\"\">실제 매물과 전세·매매 거래량</li>\n<li class=\"\">대출 실행 가능 여부와 월 상환액</li>\n<li class=\"\">잔금일·입주일·계약갱신 일정</li>\n<li class=\"\">취득세·중개보수·이사비를 포함한 현금 필요액</li>\n</ul>\n<p>6개월 뒤 예상가가 현재보다 높아도 내 자금이 준비되지 않으면 계약 가능성은 별개의 문제가 됩니다. 기간별 전망을 현금흐름 계획으로 바로 바꾸지 말고, 별도 계산표로 나눠 관리하세요.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"12개월-계획을-세우는-경우\">12개월 계획을 세우는 경우<a href=\"https://alvin.ing/blog/apartment-forecast-periods#12%EA%B0%9C%EC%9B%94-%EA%B3%84%ED%9A%8D%EC%9D%84-%EC%84%B8%EC%9A%B0%EB%8A%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"12개월 계획을 세우는 경우에 대한 직접 링크\" title=\"12개월 계획을 세우는 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>1년은 현재와 미래를 비교하기 쉬운 구간입니다. 다만 결과를 본 날짜, 기준 평형, 예상 범위, 시장 정보 기준일을 함께 저장해야 나중에 결과가 갱신되어도 무엇이 달라졌는지 알 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"18개월-이상-장기-계획을-보는-경우\">18개월 이상 장기 계획을 보는 경우<a href=\"https://alvin.ing/blog/apartment-forecast-periods#18%EA%B0%9C%EC%9B%94-%EC%9D%B4%EC%83%81-%EC%9E%A5%EA%B8%B0-%EA%B3%84%ED%9A%8D%EC%9D%84-%EB%B3%B4%EB%8A%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"18개월 이상 장기 계획을 보는 경우에 대한 직접 링크\" title=\"18개월 이상 장기 계획을 보는 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>18개월은 결혼·출산·학군·직장 이동처럼 일정이 긴 경우에 참고할 수 있습니다. 먼 기간일수록 중심값 하나보다 범위 폭, 하락 쪽 여유, 금리와 공급 변화에 대한 민감도를 먼저 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간별-예상가가-서로-반대-방향이면-어떻게-할까요\">기간별 예상가가 서로 반대 방향이면 어떻게 할까요?<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EB%B3%84-%EC%98%88%EC%83%81%EA%B0%80%EA%B0%80-%EC%84%9C%EB%A1%9C-%EB%B0%98%EB%8C%80-%EB%B0%A9%ED%96%A5%EC%9D%B4%EB%A9%B4-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%A0%EA%B9%8C%EC%9A%94\" class=\"hash-link\" aria-label=\"기간별 예상가가 서로 반대 방향이면 어떻게 할까요?에 대한 직접 링크\" title=\"기간별 예상가가 서로 반대 방향이면 어떻게 할까요?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>6개월은 하락하고 18개월은 회복하는 것처럼 기간별 방향이 다르게 보일 수 있습니다. 이때 어느 하나를 “정답”으로 고르기보다 경로를 나누어 읽어야 합니다.</p>\n<ol>\n<li class=\"\">가까운 기간에는 거래와 자금 환경이 어떻게 보이는가?</li>\n<li class=\"\">긴 기간의 회복은 어떤 조건이 유지되어야 가능한가?</li>\n<li class=\"\">중간 구간의 범위가 넓어지는가?</li>\n<li class=\"\">내 일정은 단기 변동을 감당할 수 있는가?</li>\n</ol>\n<p>이런 질문은 특정 시점의 매수·매도를 추천하지 않습니다. 다만 일정과 자금 여유를 숫자 하나가 아닌 여러 조건으로 확인하게 해 줍니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간별-결과를-기록하는-표\">기간별 결과를 기록하는 표<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EB%B3%84-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EA%B8%B0%EB%A1%9D%ED%95%98%EB%8A%94-%ED%91%9C\" class=\"hash-link\" aria-label=\"기간별 결과를 기록하는 표에 대한 직접 링크\" title=\"기간별 결과를 기록하는 표에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>실제로 비교할 때는 아래 표를 복사해 확인일마다 채워 보세요.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">확인일:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">단지·동네:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">전용면적·타입:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">최근 대표 시세:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">6개월 목표 월 / 예상 범위:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">12개월 목표 월 / 예상 범위:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">18개월 목표 월 / 예상 범위:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">시장 정보 기준일:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">표본 신뢰도:</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">그날 확인한 공식 거래 자료:</span><br></div></code></pre></div></div>\n<p>나중에 결과가 바뀌었을 때 이 기록이 있으면, 기간이 바뀐 것인지, 평형이 바뀐 것인지, 새 거래가 들어온 것인지, 시장 정보 기준일이 갱신된 것인지 구분할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예상-범위를-기간별로-읽는-법\">예상 범위를 기간별로 읽는 법<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EB%A5%BC-%EA%B8%B0%EA%B0%84%EB%B3%84%EB%A1%9C-%EC%9D%BD%EB%8A%94-%EB%B2%95\" class=\"hash-link\" aria-label=\"예상 범위를 기간별로 읽는 법에 대한 직접 링크\" title=\"예상 범위를 기간별로 읽는 법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기간별 비교에서 중심값만 보면 장기 결과가 자연스럽게 더 크거나 작아 보입니다. 하지만 아래·가운데·위쪽의 폭이 어떻게 달라지는지 봐야 불확실성의 변화까지 이해할 수 있습니다.</p>\n<ul>\n<li class=\"\">아래쪽이 현재 가격보다 크게 낮아지는가?</li>\n<li class=\"\">위쪽과 아래쪽의 차이가 기간이 길어질수록 커지는가?</li>\n<li class=\"\">범위가 넓어진 이유를 시장 조건과 거래 표본에서 설명할 수 있는가?</li>\n<li class=\"\">범위 안의 값을 계약금·수익 계산의 확정값으로 사용하고 있지는 않은가?</li>\n</ul>\n<p>범위 자체를 해석하는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값을 읽는 법</a>에서 예시와 함께 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"12개월-전망이-가장-표준적인-기간인가요\">12개월 전망이 가장 표준적인 기간인가요?<a href=\"https://alvin.ing/blog/apartment-forecast-periods#12%EA%B0%9C%EC%9B%94-%EC%A0%84%EB%A7%9D%EC%9D%B4-%EA%B0%80%EC%9E%A5-%ED%91%9C%EC%A4%80%EC%A0%81%EC%9D%B8-%EA%B8%B0%EA%B0%84%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"12개월 전망이 가장 표준적인 기간인가요?에 대한 직접 링크\" title=\"12개월 전망이 가장 표준적인 기간인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>12개월은 연간 계획과 비교하기 쉬운 기본 구간이지만, 모든 사람에게 가장 적합한 기간은 아닙니다. 이사일·대출 기간·거주 계획에 맞는 기간을 선택하고, 기간이 길어질수록 범위를 더 보수적으로 읽어야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6개월-전망이-18개월-전망보다-정확한가요\">6개월 전망이 18개월 전망보다 정확한가요?<a href=\"https://alvin.ing/blog/apartment-forecast-periods#6%EA%B0%9C%EC%9B%94-%EC%A0%84%EB%A7%9D%EC%9D%B4-18%EA%B0%9C%EC%9B%94-%EC%A0%84%EB%A7%9D%EB%B3%B4%EB%8B%A4-%EC%A0%95%ED%99%95%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"6개월 전망이 18개월 전망보다 정확한가요?에 대한 직접 링크\" title=\"6개월 전망이 18개월 전망보다 정확한가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>그렇게 단정할 수 없습니다. 6개월은 현재와 가까운 반면 단기 거래나 갑작스러운 변화에 영향을 받을 수 있고, 18개월은 미래 조건의 변화 가능성이 더 큽니다. 정확도 순위보다 각 기간의 질문과 전제를 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간별-예상가가-높으면-그-기간까지-기다려야-하나요\">기간별 예상가가 높으면 그 기간까지 기다려야 하나요?<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EB%B3%84-%EC%98%88%EC%83%81%EA%B0%80%EA%B0%80-%EB%86%92%EC%9C%BC%EB%A9%B4-%EA%B7%B8-%EA%B8%B0%EA%B0%84%EA%B9%8C%EC%A7%80-%EA%B8%B0%EB%8B%A4%EB%A0%A4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"기간별 예상가가 높으면 그 기간까지 기다려야 하나요?에 대한 직접 링크\" title=\"기간별 예상가가 높으면 그 기간까지 기다려야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 예상가는 가능한 경로를 비교하는 참고값입니다. 이사 필요성, 대출과 세금, 계약 조건, 실제 매물 상황이 함께 검토되어야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기간을-바꾸면-평형도-다시-확인해야-하나요\">기간을 바꾸면 평형도 다시 확인해야 하나요?<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EA%B8%B0%EA%B0%84%EC%9D%84-%EB%B0%94%EA%BE%B8%EB%A9%B4-%ED%8F%89%ED%98%95%EB%8F%84-%EB%8B%A4%EC%8B%9C-%ED%99%95%EC%9D%B8%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"기간을 바꾸면 평형도 다시 확인해야 하나요?에 대한 직접 링크\" title=\"기간을 바꾸면 평형도 다시 확인해야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>네. 기간 선택 전에 자동으로 선택된 평형과 대표 시세의 기준을 확인하세요. 평형이 달라지면 기간 외에 거래 표본도 달라집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-기간별-조건-확인하기\">아파트 인사이트에서 기간별 조건 확인하기<a href=\"https://alvin.ing/blog/apartment-forecast-periods#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EA%B8%B0%EA%B0%84%EB%B3%84-%EC%A1%B0%EA%B1%B4-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 기간별 조건 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 기간별 조건 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>먼저 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">가입 없이 아파트 가격 예측하기</a>에서 관심 단지의 12개월 결과와 자료 상태를 확인해 보세요. 이후 개인 일정과 조건을 바꿔 비교해야 한다면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 웹 서비스</a>로 이어갈 수 있습니다.</p>\n<p>관련해서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 결과를 읽는 전체 순서</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">예상 범위의 폭을 해석하는 방법</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">기준일과 표본 신뢰도 확인법</a>을 함께 읽으면 좋습니다.</p>\n<p>아파트 통계를 처음부터 같은 기준으로 읽고 싶다면 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>에서 질문 정의와 비교 조건부터 확인해 보세요.</p>\n<blockquote>\n<p>아파트 전망은 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석입니다. 기간별 예상가와 범위는 실제 결과를 보장하지 않으며, 매수·매도 시점이나 투자 수익을 추천하지 않습니다. 실제 계약 전에는 최신 실거래, 대출 조건, 세금, 현금흐름을 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-forecast-periods",
            "title": "아파트 가격 전망 비교하는 법: 6개월·12개월·18개월 집값 예측 읽기",
            "summary": "아파트 가격 전망에서 6개월·12개월·18개월 기간별 차이와 목표 시점, 예상 범위, 기준일을 맞춰 집값 예측 결과를 객관적으로 비교하는 방법을 정리합니다.",
            "date_modified": "2026-09-01T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-forecast-range-reading",
            "content_html": "<p>아파트 가격 예측 결과 화면에서 가장 눈에 들어오는 숫자는 가운데에 있는 예상가입니다. 하지만 이 글의 질문은 “왜 범위가 필요한가?”보다 <strong>화면에 표시된 아래·가운데·위 값을 어떤 순서로 읽을 것인가</strong>에 가깝습니다. 가운데 숫자만 보고 “1년 뒤 가격은 정확히 이 금액”이라고 해석하면 전망이 가진 불확실성과 조건을 놓치게 됩니다.</p>\n<p>가격 전망에서 범위는 장식이 아닙니다. 현재 확인된 거래와 시장 정보를 바탕으로 여러 조건을 비교했을 때 결과가 어디까지 달라질 수 있는지 보여주는 정보입니다. 아래쪽·가운데·위쪽 모두 확정된 결과가 아니며, <strong>범위의 폭과 그 폭을 만든 기준</strong>을 함께 읽어야 합니다.</p>\n<p>이 글에서는 아파트 인사이트 공개 체험 화면에서 예상 범위를 확인하는 순서, 가상의 숫자를 해석하는 법, 범위가 넓거나 좁을 때 추가로 확인할 내용을 정리합니다. 범위가 필요한 이유와 중심 추정값의 개념부터 살펴보고 싶다면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-range-not-single-number\">미래 아파트 가격을 하나의 숫자로 단정하면 위험한 이유</a>를 먼저 읽어도 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예상-범위가-필요한-이유\">예상 범위가 필요한 이유<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"예상 범위가 필요한 이유에 대한 직접 링크\" title=\"예상 범위가 필요한 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 가격은 기준일의 거래 한 건만으로 결정되지 않습니다. 전용면적, 층, 타입, 최근 거래의 구성, 금리, 공급, 지역의 거래 분위기가 함께 영향을 줄 수 있습니다. 앞으로 시간이 지나면 이 조건들이 달라질 가능성도 있습니다.</p>\n<p>미래를 하나의 숫자로만 표시하면 읽기는 쉽지만 다음 질문에 답하기 어렵습니다.</p>\n<ul>\n<li class=\"\">현재 자료에서 확인할 수 있는 중심은 어디인가?</li>\n<li class=\"\">불리한 조건과 유리한 조건에서 결과가 얼마나 벌어지는가?</li>\n<li class=\"\">거래 표본이 충분해 범위를 해석할 수 있는가?</li>\n<li class=\"\">새 거래나 시장 변화가 생기면 결과가 달라질 수 있는가?</li>\n</ul>\n<p>그래서 예상 범위는 “미래 가격을 맞히는 띠”가 아니라, 현재 정보로 말할 수 있는 폭을 보여주는 참고값으로 보는 편이 정확합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아래쪽가운데위쪽은-각각-어떻게-읽을까\">아래쪽·가운데·위쪽은 각각 어떻게 읽을까<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%95%84%EB%9E%98%EC%AA%BD%EA%B0%80%EC%9A%B4%EB%8D%B0%EC%9C%84%EC%AA%BD%EC%9D%80-%EA%B0%81%EA%B0%81-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9D%BD%EC%9D%84%EA%B9%8C\" class=\"hash-link\" aria-label=\"아래쪽·가운데·위쪽은 각각 어떻게 읽을까에 대한 직접 링크\" title=\"아래쪽·가운데·위쪽은 각각 어떻게 읽을까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>위치</th><th>바른 해석</th><th>피해야 할 해석</th></tr></thead><tbody><tr><td>아래쪽</td><td>불리한 조건이 이어질 때 참고할 수 있는 낮은 경계</td><td>반드시 이 가격까지 하락한다는 뜻</td></tr><tr><td>가운데</td><td>여러 가능성을 비교하기 위한 중심 기준</td><td>반드시 도달하는 확정 가격</td></tr><tr><td>위쪽</td><td>수요와 환경이 유지될 때 참고할 수 있는 높은 경계</td><td>반드시 도달하는 목표 가격</td></tr></tbody></table>\n<p>범위의 위쪽이 높다고 좋은 결과라고 단정할 수도 없습니다. 그 값에 도달하려면 자금 여건, 거래 분위기, 공급과 정책 같은 조건이 특정 방향으로 이어져야 할 수 있습니다. 반대로 아래쪽이 낮다고 반드시 급락한다는 뜻도 아닙니다.</p>\n<p>범위의 세 위치를 읽을 때는 “어느 값이 맞나?”보다 다음 질문을 먼저 던져 보세요.</p>\n<ol>\n<li class=\"\">현재 대표 시세는 어떤 평형과 거래를 기준으로 했는가?</li>\n<li class=\"\">기준일에서 목표 시점까지 얼마나 먼가?</li>\n<li class=\"\">범위의 폭이 거래 표본의 부족 때문인지, 미래 조건의 불확실성 때문인지 구분할 수 있는가?</li>\n<li class=\"\">내 자금 계획은 가운데 값이 아니라 아래쪽 결과에서도 유지되는가?</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가상의-숫자로-계산해-보기\">가상의 숫자로 계산해 보기<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EA%B0%80%EC%83%81%EC%9D%98-%EC%88%AB%EC%9E%90%EB%A1%9C-%EA%B3%84%EC%82%B0%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"가상의 숫자로 계산해 보기에 대한 직접 링크\" title=\"가상의 숫자로 계산해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음 표는 특정 단지의 실제 결과가 아닌 이해를 위한 예시입니다.</p>\n<table><thead><tr><th>항목</th><th style=\"text-align:right\">가상 값</th></tr></thead><tbody><tr><td>최근 대표 시세</td><td style=\"text-align:right\">10억 원</td></tr><tr><td>12개월 뒤 아래쪽</td><td style=\"text-align:right\">9억 5,000만 원</td></tr><tr><td>12개월 뒤 가운데</td><td style=\"text-align:right\">10억 4,000만 원</td></tr><tr><td>12개월 뒤 위쪽</td><td style=\"text-align:right\">11억 2,000만 원</td></tr></tbody></table>\n<p>이 경우 가운데 값의 변화율은 현재 대비 약 4%지만, 아래쪽은 약 5% 낮고 위쪽은 약 12% 높습니다. 중요한 것은 “12개월 뒤에 10억 4,000만 원이 된다”가 아니라, 현재 정보에서 서로 다른 조건을 고려하면 결과의 폭이 이 정도로 벌어질 수 있다는 점입니다.</p>\n<p>만약 매수 계획을 세우면서 가운데 값만 사용하면 취득세·중개보수·대출이자까지 포함한 현금흐름을 과소평가할 수 있습니다. 반대로 아래쪽 값만 사용해 모든 상황을 비관적으로 가정하는 것도 적절하지 않습니다. 가격 범위와 내 자금 계획은 별도 표로 관리해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위의-폭을-비교하는-방법\">범위의 폭을 비교하는 방법<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EB%B2%94%EC%9C%84%EC%9D%98-%ED%8F%AD%EC%9D%84-%EB%B9%84%EA%B5%90%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"범위의 폭을 비교하는 방법에 대한 직접 링크\" title=\"범위의 폭을 비교하는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>범위는 아래쪽과 위쪽의 차이로만 볼 것이 아니라 현재 대표 시세와 비교해 상대적인 폭도 살펴야 합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">범위 폭 = 위쪽 값 - 아래쪽 값</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">상대 범위 폭 = 범위 폭 ÷ 현재 대표 시세</span><br></div></code></pre></div></div>\n<p>예를 들어 현재 대표 시세가 10억 원이고 예상 범위가 9억 5,000만 원에서 11억 2,000만 원이라면 범위 폭은 1억 7,000만 원입니다. 이 수치는 매수·매도 결론이 아니라, 가운데 값 하나로 현금 계획을 고정하기에는 변동 가능성을 더 고려해야 한다는 신호입니다.</p>\n<p>다른 단지와 범위를 비교할 때도 현재 가격 수준과 평형이 같아야 합니다. 6억 원 단지의 1억 원 범위와 20억 원 단지의 1억 원 범위는 같은 의미가 아닐 수 있고, 59㎡와 84㎡를 섞으면 거래 조건 차이가 범위 차이처럼 보일 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위를-보기-전에-확인할-네-가지\">범위를 보기 전에 확인할 네 가지<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EB%B2%94%EC%9C%84%EB%A5%BC-%EB%B3%B4%EA%B8%B0-%EC%A0%84%EC%97%90-%ED%99%95%EC%9D%B8%ED%95%A0-%EB%84%A4-%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"범위를 보기 전에 확인할 네 가지에 대한 직접 링크\" title=\"범위를 보기 전에 확인할 네 가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-기준일\">1. 기준일<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#1-%EA%B8%B0%EC%A4%80%EC%9D%BC\" class=\"hash-link\" aria-label=\"1. 기준일에 대한 직접 링크\" title=\"1. 기준일에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>예상 범위는 언제의 자료를 기준으로 했는지에 따라 달라집니다. 최근 거래가 추가되거나 시장 정보가 갱신되면 같은 단지도 결과를 다시 확인해야 할 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-목표-기간\">2. 목표 기간<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#2-%EB%AA%A9%ED%91%9C-%EA%B8%B0%EA%B0%84\" class=\"hash-link\" aria-label=\"2. 목표 기간에 대한 직접 링크\" title=\"2. 목표 기간에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>6개월·12개월·18개월은 서로 다른 시간축입니다. 기간이 길수록 미래 조건이 바뀔 가능성이 커지므로, 중심값보다 범위 폭을 먼저 비교하는 것이 좋습니다. 기간별 결과를 맞춰 보는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 전망 비교 가이드</a>에서 설명합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-거래-조건\">3. 거래 조건<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#3-%EA%B1%B0%EB%9E%98-%EC%A1%B0%EA%B1%B4\" class=\"hash-link\" aria-label=\"3. 거래 조건에 대한 직접 링크\" title=\"3. 거래 조건에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>같은 단지라도 평형·층·타입이 달라지면 비교할 거래가 달라집니다. 대표 시세와 예상 범위가 어떤 평형을 기준으로 계산되었는지 확인하지 않으면 다른 조건의 숫자를 한 줄에 섞게 됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-표본-신뢰도\">4. 표본 신뢰도<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#4-%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84\" class=\"hash-link\" aria-label=\"4. 표본 신뢰도에 대한 직접 링크\" title=\"4. 표본 신뢰도에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>표본 신뢰도는 결과가 맞을 확률이나 범위 안에 들어갈 확률을 보장하는 숫자가 아닙니다. 거래 표본이 충분한지, 최근 거래가 이어지는지, 비교 조건이 안정적인지 해석하는 참고 정보입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위가-넓으면-분석이-무의미한가요\">범위가 넓으면 분석이 무의미한가요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EB%B2%94%EC%9C%84%EA%B0%80-%EB%84%93%EC%9C%BC%EB%A9%B4-%EB%B6%84%EC%84%9D%EC%9D%B4-%EB%AC%B4%EC%9D%98%EB%AF%B8%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"범위가 넓으면 분석이 무의미한가요?에 대한 직접 링크\" title=\"범위가 넓으면 분석이 무의미한가요?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>그렇지 않습니다. 범위가 넓다는 것은 현재 시점에 확인되지 않은 조건이 많다는 뜻일 수 있습니다. 이 정보는 다음과 같은 계획에 도움을 줍니다.</p>\n<ul>\n<li class=\"\">계약금과 잔금 사이에 필요한 현금 여유를 다시 계산하기</li>\n<li class=\"\">대출 금리 변화가 월 상환액에 미치는 영향을 따로 확인하기</li>\n<li class=\"\">거래가 부족한 단지라면 현장 매물과 추가 실거래를 더 확인하기</li>\n<li class=\"\">정책·공급 변화가 일정에 미칠 가능성을 메모하기</li>\n</ul>\n<p>다만 범위가 넓은 상태에서 가운데 값만 골라 계약금이나 수익을 계산하면 안 됩니다. 가격과 별도로 대출이자, 세금, 중개보수, 수리비, 전세 보증금 등 실제 현금흐름을 계산해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위가-좁으면-안심해도-될까요\">범위가 좁으면 안심해도 될까요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EB%B2%94%EC%9C%84%EA%B0%80-%EC%A2%81%EC%9C%BC%EB%A9%B4-%EC%95%88%EC%8B%AC%ED%95%B4%EB%8F%84-%EB%90%A0%EA%B9%8C%EC%9A%94\" class=\"hash-link\" aria-label=\"범위가 좁으면 안심해도 될까요?에 대한 직접 링크\" title=\"범위가 좁으면 안심해도 될까요?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>범위가 좁다고 실제 가격이 그 안에 반드시 들어간다는 뜻은 아닙니다. 현재 확인된 자료가 비슷한 조건으로 모여 있거나 목표 기간이 짧아 범위가 좁게 보일 수 있지만, 갑작스러운 금리·정책·공급 변화는 별도의 영향을 줄 수 있습니다.</p>\n<p>범위가 좁은 결과를 볼 때도 다음을 확인하세요.</p>\n<ol>\n<li class=\"\">최근 거래의 면적과 층 조건이 일관적인가?</li>\n<li class=\"\">조회 기준일과 거래 계약일 사이의 간격이 큰가?</li>\n<li class=\"\">실거래가 적은데 범위만 좁게 표시된 것은 아닌가?</li>\n<li class=\"\">아래쪽 결과에서도 내 대출과 거주 계획이 유지되는가?</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공개-체험에서-범위를-확인하는-순서\">공개 체험에서 범위를 확인하는 순서<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EA%B3%B5%EA%B0%9C-%EC%B2%B4%ED%97%98%EC%97%90%EC%84%9C-%EB%B2%94%EC%9C%84%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"공개 체험에서 범위를 확인하는 순서에 대한 직접 링크\" title=\"공개 체험에서 범위를 확인하는 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 가입 없는 공개 예측</a>에서 관심 단지를 검색했다면 다음 순서로 결과를 읽어 보세요.</p>\n<ol>\n<li class=\"\">단지명과 지역이 맞는지 확인합니다.</li>\n<li class=\"\">자동 선택된 평형이나 직접 선택한 평형을 확인합니다.</li>\n<li class=\"\">최근 대표 시세의 기준을 확인합니다.</li>\n<li class=\"\">12개월 뒤 예상가와 아래·가운데·위 범위를 함께 봅니다.</li>\n<li class=\"\">표본 신뢰도와 시장 정보별 기준일을 확인합니다.</li>\n<li class=\"\">확인 날짜와 주요 숫자를 기록합니다.</li>\n</ol>\n<p>예상 범위가 만들어지는 공개 개념과 실제 화면의 설명은 <a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 미래가격 예측 공식 가이드</a>에서 이어서 볼 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가격-범위와-현금-계획을-분리하는-표\">가격 범위와 현금 계획을 분리하는 표<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EA%B0%80%EA%B2%A9-%EB%B2%94%EC%9C%84%EC%99%80-%ED%98%84%EA%B8%88-%EA%B3%84%ED%9A%8D%EC%9D%84-%EB%B6%84%EB%A6%AC%ED%95%98%EB%8A%94-%ED%91%9C\" class=\"hash-link\" aria-label=\"가격 범위와 현금 계획을 분리하는 표에 대한 직접 링크\" title=\"가격 범위와 현금 계획을 분리하는 표에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>가격 전망을 봤다면 아래처럼 가격과 비용을 나누어 적어 보세요.</p>\n<table><thead><tr><th>구분</th><th>기록할 내용</th></tr></thead><tbody><tr><td>가격</td><td>현재 대표 시세, 예상 범위, 기준일</td></tr><tr><td>자금</td><td>자기자본, 대출 원금, 예상 금리, 월 상환액</td></tr><tr><td>세금·비용</td><td>취득세, 양도 관련 세금, 중개보수, 수리비</td></tr><tr><td>일정</td><td>계약일, 잔금일, 입주일, 전세 만기</td></tr><tr><td>확인 필요</td><td>공식 실거래, 매물 조건, 세법과 금융기관 안내</td></tr></tbody></table>\n<p>이렇게 나누면 예상가가 올랐다는 사실과 실제로 필요한 현금이 늘었다는 사실을 혼동하지 않을 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예상-범위-안에-실제-가격이-들어갈-확률은-얼마인가요\">예상 범위 안에 실제 가격이 들어갈 확률은 얼마인가요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84-%EC%95%88%EC%97%90-%EC%8B%A4%EC%A0%9C-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EB%93%A4%EC%96%B4%EA%B0%88-%ED%99%95%EB%A5%A0%EC%9D%80-%EC%96%BC%EB%A7%88%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"예상 범위 안에 실제 가격이 들어갈 확률은 얼마인가요?에 대한 직접 링크\" title=\"예상 범위 안에 실제 가격이 들어갈 확률은 얼마인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>예상 범위는 여러 조건을 비교한 참고 구간이며, 실제 가격이 그 안에 들어갈 확률이나 적중을 보장하는 통계적 신뢰구간으로 해석하면 안 됩니다. 실제 결과는 미래의 거래·정책·금리 환경에 따라 달라질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가운데-값이-가장-가능성이-높은-가격인가요\">가운데 값이 가장 가능성이 높은 가격인가요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EA%B0%80%EC%9A%B4%EB%8D%B0-%EA%B0%92%EC%9D%B4-%EA%B0%80%EC%9E%A5-%EA%B0%80%EB%8A%A5%EC%84%B1%EC%9D%B4-%EB%86%92%EC%9D%80-%EA%B0%80%EA%B2%A9%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"가운데 값이 가장 가능성이 높은 가격인가요?에 대한 직접 링크\" title=\"가운데 값이 가장 가능성이 높은 가격인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>가운데 값은 결과를 비교하기 위한 중심 기준입니다. 반드시 가장 가능성이 높거나 실제로 도달하는 가격이라고 단정할 수는 없습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아래쪽-값으로-매수-예산을-잡으면-안전한가요\">아래쪽 값으로 매수 예산을 잡으면 안전한가요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%95%84%EB%9E%98%EC%AA%BD-%EA%B0%92%EC%9C%BC%EB%A1%9C-%EB%A7%A4%EC%88%98-%EC%98%88%EC%82%B0%EC%9D%84-%EC%9E%A1%EC%9C%BC%EB%A9%B4-%EC%95%88%EC%A0%84%ED%95%9C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"아래쪽 값으로 매수 예산을 잡으면 안전한가요?에 대한 직접 링크\" title=\"아래쪽 값으로 매수 예산을 잡으면 안전한가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 아래쪽 값도 미래 가격을 보장하지 않습니다. 대출 승인, 금리, 세금, 중개보수, 생활비를 포함한 개인의 현금흐름을 별도로 검토해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위가-계속-바뀌는-이유는-무엇인가요\">범위가 계속 바뀌는 이유는 무엇인가요?<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EB%B2%94%EC%9C%84%EA%B0%80-%EA%B3%84%EC%86%8D-%EB%B0%94%EB%80%8C%EB%8A%94-%EC%9D%B4%EC%9C%A0%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"범위가 계속 바뀌는 이유는 무엇인가요?에 대한 직접 링크\" title=\"범위가 계속 바뀌는 이유는 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>새로운 실거래가 반영되거나 시장 정보가 갱신되거나, 확인하는 평형·기간이 달라졌을 수 있습니다. 결과가 바뀌면 기준일과 평형부터 다시 확인하세요.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-예상-범위-직접-확인하기\">아파트 인사이트에서 예상 범위 직접 확인하기<a href=\"https://alvin.ing/blog/apartment-forecast-range-reading#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84-%EC%A7%81%EC%A0%91-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 예상 범위 직접 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 예상 범위 직접 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 공개 예측 화면</a>에서 시군구와 단지명을 검색해 보세요. 결과가 나오면 가운데 숫자보다 먼저 기준일, 거래 조건, 범위의 폭을 확인하는 습관을 들이는 것이 좋습니다.</p>\n<p>관련 글로는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격을 확인하는 전체 순서</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건의 한계</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">기준일·시장 정보·표본 신뢰도 읽는 법</a>을 함께 추천합니다.</p>\n<p>아파트 통계의 전체 비교 순서는 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>에서 확인할 수 있습니다.</p>\n<blockquote>\n<p>아파트 예상 범위는 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석입니다. 아래쪽·가운데·위쪽 어느 값도 미래 가격이나 수익을 보장하지 않으며 투자 권유나 투자 자문이 아닙니다. 실제 거래와 계약 전에는 최신 공식 자료와 개인의 자금 조건을 별도로 확인해야 합니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-forecast-range-reading",
            "title": "아파트 시세 예측 범위 읽는 법: 최저가·중간값·최고가의 의미",
            "summary": "아파트 시세 예측 결과 화면의 최저가·중간값·최고가 범위가 의미하는 바와 확정 가격이 아닌 불확실성 구간으로 해석하는 실전 가이드를 정리합니다.",
            "date_modified": "2026-09-01T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-single-trade-limit",
            "content_html": "\n<p>아파트 검색 결과에서 가장 최근 거래 한 건이 눈에 띄면, 그 가격을 곧바로 “현재 시세”라고 생각하기 쉽습니다. 하지만 거래 한 건에는 전용면적, 층, 타입, 거래 시점, 내부 상태, 급매 여부처럼 단지 전체를 대표하지 않는 조건이 함께 들어 있을 수 있습니다.</p>\n<p>최근 실거래 한 건은 중요한 관측값입니다. 다만 <strong>관측값과 대표 시세는 같은 말이 아닙니다.</strong> 대표 시세를 이해하려면 여러 거래가 같은 조건에서 반복되는지, 거래가 얼마나 자주 있었는지, 특수한 거래가 섞이지 않았는지를 함께 봐야 합니다.</p>\n<p>이 글에서는 국토교통부 실거래 자료를 읽는 기본 순서와 아파트 인사이트에서 거래 흐름을 확인할 때 볼 수 있는 항목을 연결해 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최근-거래-한-건이-흔들릴-수-있는-6가지-이유\">최근 거래 한 건이 흔들릴 수 있는 6가지 이유<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98-%ED%95%9C-%EA%B1%B4%EC%9D%B4-%ED%9D%94%EB%93%A4%EB%A6%B4-%EC%88%98-%EC%9E%88%EB%8A%94-6%EA%B0%80%EC%A7%80-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"최근 거래 한 건이 흔들릴 수 있는 6가지 이유에 대한 직접 링크\" title=\"최근 거래 한 건이 흔들릴 수 있는 6가지 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-전용면적이-다릅니다\">1. 전용면적이 다릅니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#1-%EC%A0%84%EC%9A%A9%EB%A9%B4%EC%A0%81%EC%9D%B4-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 전용면적이 다릅니다에 대한 직접 링크\" title=\"1. 전용면적이 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전용 59㎡와 84㎡는 같은 단지에 있어도 수요와 가격이 다릅니다. 공급면적이나 방 개수가 비슷해 보인다는 이유로 다른 전용면적의 거래를 한 줄로 합치면, 면적 차이가 가격 변화처럼 보일 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-층이-다릅니다\">2. 층이 다릅니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#2-%EC%B8%B5%EC%9D%B4-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 층이 다릅니다에 대한 직접 링크\" title=\"2. 층이 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>저층, 일반층, 고층은 조망·소음·일조·사생활 조건이 다를 수 있습니다. 같은 전용면적이라도 층이 다른 거래가 한 건씩만 있다면 층 차이를 시장 가격 변화로 오해하기 쉽습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-타입과-동향이-다릅니다\">3. 타입과 동·향이 다릅니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#3-%ED%83%80%EC%9E%85%EA%B3%BC-%EB%8F%99%ED%96%A5%EC%9D%B4-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 타입과 동·향이 다릅니다에 대한 직접 링크\" title=\"3. 타입과 동·향이 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>판상형·타워형, 남향·동향, 내부 동선과 수납 구조 같은 타입 차이가 있을 수 있습니다. 실거래 공개 화면에서 모든 세부 조건이 같은 수준으로 표시되지 않는 경우도 있으므로, 거래 한 건을 전체 단지의 기준으로 확대하지 않아야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-거래일과-공개일이-다릅니다\">4. 거래일과 공개일이 다릅니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#4-%EA%B1%B0%EB%9E%98%EC%9D%BC%EA%B3%BC-%EA%B3%B5%EA%B0%9C%EC%9D%BC%EC%9D%B4-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 거래일과 공개일이 다릅니다에 대한 직접 링크\" title=\"4. 거래일과 공개일이 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>실거래 자료에는 계약일, 신고일, 공개일 사이의 시간 차이가 생길 수 있습니다. 화면에서 최근에 보이는 거래가 실제로는 몇 주 전 계약일일 수 있으므로, 조회일만 보고 “오늘의 가격”으로 부르면 안 됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-거래-유형이-다릅니다\">5. 거래 유형이 다릅니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#5-%EA%B1%B0%EB%9E%98-%EC%9C%A0%ED%98%95%EC%9D%B4-%EB%8B%A4%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"5. 거래 유형이 다릅니다에 대한 직접 링크\" title=\"5. 거래 유형이 다릅니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>일반 매매와 직거래, 특수한 거래 조건은 같은 방식으로 비교하기 어렵습니다. 거래 유형이 다르거나 정상적인 시장 거래로 보기 어려운 사유가 있는 경우에는 대표 시세 계산에서 분리해 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6-계약이-해제정정될-수-있습니다\">6. 계약이 해제·정정될 수 있습니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#6-%EA%B3%84%EC%95%BD%EC%9D%B4-%ED%95%B4%EC%A0%9C%EC%A0%95%EC%A0%95%EB%90%A0-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"6. 계약이 해제·정정될 수 있습니다에 대한 직접 링크\" title=\"6. 계약이 해제·정정될 수 있습니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>계약 해제나 신고 정정이 뒤늦게 반영될 수 있습니다. 가장 높은 가격이나 가장 낮은 가격을 먼저 찾기보다 거래 상태와 공개 기준을 확인해야 하는 이유입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거래-한-건-대신-함께-볼-항목\">거래 한 건 대신 함께 볼 항목<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EA%B1%B0%EB%9E%98-%ED%95%9C-%EA%B1%B4-%EB%8C%80%EC%8B%A0-%ED%95%A8%EA%BB%98-%EB%B3%BC-%ED%95%AD%EB%AA%A9\" class=\"hash-link\" aria-label=\"거래 한 건 대신 함께 볼 항목에 대한 직접 링크\" title=\"거래 한 건 대신 함께 볼 항목에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>확인 항목</th><th>확인할 질문</th></tr></thead><tbody><tr><td>전용면적</td><td>같은 크기의 거래인가?</td></tr><tr><td>층</td><td>저층·일반층·고층 차이가 있는가?</td></tr><tr><td>타입과 위치</td><td>동·향·구조 차이가 가격에 섞였는가?</td></tr><tr><td>거래일</td><td>실제 계약 시점은 언제인가?</td></tr><tr><td>거래 유형</td><td>일반 매매와 직거래가 섞였는가?</td></tr><tr><td>거래 빈도</td><td>최근 여러 달 동안 거래가 이어졌는가?</td></tr><tr><td>거래 상태</td><td>해제·정정 거래를 포함하고 있지 않은가?</td></tr></tbody></table>\n<p>이 표의 질문에 답하지 않은 채 최근 가격만 복사하면 숫자는 빠르게 얻을 수 있지만, 비교 기준은 약해집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"평균보다-먼저-중앙값과-분포를-보는-이유\">평균보다 먼저 중앙값과 분포를 보는 이유<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%ED%8F%89%EA%B7%A0%EB%B3%B4%EB%8B%A4-%EB%A8%BC%EC%A0%80-%EC%A4%91%EC%95%99%EA%B0%92%EA%B3%BC-%EB%B6%84%ED%8F%AC%EB%A5%BC-%EB%B3%B4%EB%8A%94-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"평균보다 먼저 중앙값과 분포를 보는 이유에 대한 직접 링크\" title=\"평균보다 먼저 중앙값과 분포를 보는 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>거래가 몇 건뿐인 달에 비정상적으로 높거나 낮은 거래가 하나 들어오면 평균은 크게 움직일 수 있습니다. 중앙값은 거래를 가격순으로 놓았을 때 가운데에 있는 값이라 특이한 한 건의 영향이 평균보다 작을 수 있습니다.</p>\n<p>다만 중앙값도 만능은 아닙니다. 거래가 두 건뿐이거나 면적과 층이 섞여 있다면 가운데 값이 생겨도 비교 조건은 여전히 불안정합니다. 따라서 가격 하나보다 다음 세 가지를 같이 보는 것이 좋습니다.</p>\n<ul>\n<li class=\"\">같은 조건의 거래가 반복되는지</li>\n<li class=\"\">가격이 어느 구간에 모여 있는지</li>\n<li class=\"\">해당 기간에 거래가 실제로 얼마나 있었는지</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거래가-적은-단지에서는-거래-빈도-자체가-정보입니다\">거래가 적은 단지에서는 거래 빈도 자체가 정보입니다<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EA%B1%B0%EB%9E%98%EA%B0%80-%EC%A0%81%EC%9D%80-%EB%8B%A8%EC%A7%80%EC%97%90%EC%84%9C%EB%8A%94-%EA%B1%B0%EB%9E%98-%EB%B9%88%EB%8F%84-%EC%9E%90%EC%B2%B4%EA%B0%80-%EC%A0%95%EB%B3%B4%EC%9E%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"거래가 적은 단지에서는 거래 빈도 자체가 정보입니다에 대한 직접 링크\" title=\"거래가 적은 단지에서는 거래 빈도 자체가 정보입니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>거래가 적은 단지의 최근 한 건은 가격을 알려주는 동시에 “현재 관측이 부족하다”는 사실도 알려줍니다. 거래가 적은데 최근 최고가만 강조하면 가격 상승처럼 보일 수 있고, 최근 최저가만 강조하면 급락처럼 보일 수 있습니다.</p>\n<p>거래가 드문 단지를 확인할 때는 다음을 따로 기록해 보세요.</p>\n<ol>\n<li class=\"\">최근 거래가 발생한 달</li>\n<li class=\"\">해당 달의 거래 건수</li>\n<li class=\"\">같은 전용면적의 거래 건수</li>\n<li class=\"\">층과 타입이 같은 거래인지</li>\n<li class=\"\">직전 거래와의 시간 간격</li>\n</ol>\n<p>이 기록은 가격 방향을 예언하기 위한 것이 아니라, 현재 자료로 어느 정도까지 말할 수 있는지 정하기 위한 것입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-거래-흐름을-보는-방법\">아파트 인사이트에서 거래 흐름을 보는 방법<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EA%B1%B0%EB%9E%98-%ED%9D%90%EB%A6%84%EC%9D%84-%EB%B3%B4%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 거래 흐름을 보는 방법에 대한 직접 링크\" title=\"아파트 인사이트에서 거래 흐름을 보는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 인사이트의 단지 분석 화면에서는 최근 거래 한 건 외에 거래 흐름을 여러 각도에서 확인할 수 있습니다. 화면과 제공 범위에 따라 다음 항목을 살펴볼 수 있습니다.</p>\n<table><thead><tr><th>화면에서 볼 항목</th><th>의미</th></tr></thead><tbody><tr><td>면적별·층별 분포</td><td>거래가 특정 면적이나 층에 몰려 있는지 확인</td></tr><tr><td>거래 회전율</td><td>단지 규모에 비해 거래가 얼마나 있었는지 보는 참고값</td></tr><tr><td>월별 거래 빈도</td><td>한 달의 우연한 거래인지 반복 흐름인지 확인</td></tr><tr><td>직거래 비중</td><td>일반 중개 거래와 다른 유형이 얼마나 섞였는지 확인</td></tr><tr><td>층·거래 유형 필터</td><td>저층·일반층, 거래 유형을 나누어 비교</td></tr><tr><td>같은 조건의 중앙값</td><td>비교 조건을 맞춘 가격 기준을 확인</td></tr></tbody></table>\n<p>이 정보는 “한 건을 제거해서 보기 좋은 가격을 만드는 기능”이 아닙니다. 거래를 어떤 조건으로 묶었는지 이해하고, 서로 다른 거래를 무심코 섞지 않도록 돕는 확인 화면입니다.</p>\n<p><a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 웹 서비스</a>에서 관심 단지를 선택했다면, 가격 카드만 보지 말고 거래 분석 영역에서 면적·층·거래 유형을 바꿔 보세요. 필터를 바꾼 뒤 같은 조건의 중앙값과 거래 건수가 어떻게 달라지는지 확인하면 최근 한 건의 위치를 더 잘 이해할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가상의-거래-세-건을-비교해-보기\">가상의 거래 세 건을 비교해 보기<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EA%B0%80%EC%83%81%EC%9D%98-%EA%B1%B0%EB%9E%98-%EC%84%B8-%EA%B1%B4%EC%9D%84-%EB%B9%84%EA%B5%90%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"가상의 거래 세 건을 비교해 보기에 대한 직접 링크\" title=\"가상의 거래 세 건을 비교해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음은 실제 단지의 값이 아닌 해석을 위한 가상 예시입니다.</p>\n<table><thead><tr><th>거래</th><th style=\"text-align:right\">전용면적</th><th style=\"text-align:right\">층</th><th>거래 유형</th><th style=\"text-align:right\">가격</th></tr></thead><tbody><tr><td>A</td><td style=\"text-align:right\">84㎡</td><td style=\"text-align:right\">고층</td><td>일반 매매</td><td style=\"text-align:right\">10억 8,000만 원</td></tr><tr><td>B</td><td style=\"text-align:right\">84㎡</td><td style=\"text-align:right\">일반층</td><td>일반 매매</td><td style=\"text-align:right\">10억 1,000만 원</td></tr><tr><td>C</td><td style=\"text-align:right\">84㎡</td><td style=\"text-align:right\">저층</td><td>직거래</td><td style=\"text-align:right\">9억 6,000만 원</td></tr></tbody></table>\n<p>A만 보면 “현재 시세는 10억 8,000만 원”처럼 보이고, C만 보면 “9억 6,000만 원이면 살 수 있다”고 생각할 수 있습니다. 하지만 세 거래는 층과 거래 유형이 다릅니다. 이럴 때는 같은 조건의 거래를 더 확보하고, 필터를 나누어 중앙값과 분포를 비교해야 합니다.</p>\n<p>또한 B가 최근 거래라는 이유만으로 단지 전체의 시세가 10억 1,000만 원이라고 단정할 수도 없습니다. 동·향·내부 상태와 계약 시점이 다를 수 있기 때문입니다. 예시는 최근 거래 하나를 버리자는 뜻이 아니라, 하나의 숫자에 설명을 더 붙이자는 뜻입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공식-실거래-자료와-분석-결과를-대조하는-순서\">공식 실거래 자료와 분석 결과를 대조하는 순서<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EA%B3%B5%EC%8B%9D-%EC%8B%A4%EA%B1%B0%EB%9E%98-%EC%9E%90%EB%A3%8C%EC%99%80-%EB%B6%84%EC%84%9D-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EB%8C%80%EC%A1%B0%ED%95%98%EB%8A%94-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"공식 실거래 자료와 분석 결과를 대조하는 순서에 대한 직접 링크\" title=\"공식 실거래 자료와 분석 결과를 대조하는 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-국토교통부-자료에서-거래-조건-확인\">1. 국토교통부 자료에서 거래 조건 확인<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#1-%EA%B5%AD%ED%86%A0%EA%B5%90%ED%86%B5%EB%B6%80-%EC%9E%90%EB%A3%8C%EC%97%90%EC%84%9C-%EA%B1%B0%EB%9E%98-%EC%A1%B0%EA%B1%B4-%ED%99%95%EC%9D%B8\" class=\"hash-link\" aria-label=\"1. 국토교통부 자료에서 거래 조건 확인에 대한 직접 링크\" title=\"1. 국토교통부 자료에서 거래 조건 확인에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p><a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>에서 지역과 단지를 검색하고 계약일, 전용면적, 층, 거래금액을 확인합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-해제정정-여부-확인\">2. 해제·정정 여부 확인<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#2-%ED%95%B4%EC%A0%9C%EC%A0%95%EC%A0%95-%EC%97%AC%EB%B6%80-%ED%99%95%EC%9D%B8\" class=\"hash-link\" aria-label=\"2. 해제·정정 여부 확인에 대한 직접 링크\" title=\"2. 해제·정정 여부 확인에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>거래가 현재 유효한지, 정정이나 해제 표시가 있는지 확인합니다. 공개 시점에 따라 표시가 달라질 수 있으므로 조회 날짜도 함께 기록합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-같은-조건만-먼저-묶기\">3. 같은 조건만 먼저 묶기<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#3-%EA%B0%99%EC%9D%80-%EC%A1%B0%EA%B1%B4%EB%A7%8C-%EB%A8%BC%EC%A0%80-%EB%AC%B6%EA%B8%B0\" class=\"hash-link\" aria-label=\"3. 같은 조건만 먼저 묶기에 대한 직접 링크\" title=\"3. 같은 조건만 먼저 묶기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>면적과 층을 맞춘 뒤 거래 유형을 나눕니다. 조건을 맞춘 거래가 너무 적다면 “대표 시세를 계산하기 어렵다”는 결과도 유효한 결론입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-대표-시세와-예상-범위를-함께-보기\">4. 대표 시세와 예상 범위를 함께 보기<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#4-%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EC%99%80-%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EB%A5%BC-%ED%95%A8%EA%BB%98-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"4. 대표 시세와 예상 범위를 함께 보기에 대한 직접 링크\" title=\"4. 대표 시세와 예상 범위를 함께 보기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아파트 인사이트 공개 체험의 대표 시세는 최근 여러 유효 거래를 비교하기 위한 기준값입니다. 가장 최근 거래와 다를 수 있으며, 그 차이가 곧 오류라는 뜻은 아닙니다. 대표 시세의 기준 평형과 예상 범위는 함께 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최근-거래와-예상-범위를-연결해서-읽기\">최근 거래와 예상 범위를 연결해서 읽기<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98%EC%99%80-%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EB%A5%BC-%EC%97%B0%EA%B2%B0%ED%95%B4%EC%84%9C-%EC%9D%BD%EA%B8%B0\" class=\"hash-link\" aria-label=\"최근 거래와 예상 범위를 연결해서 읽기에 대한 직접 링크\" title=\"최근 거래와 예상 범위를 연결해서 읽기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>최근 거래 한 건을 확인했다면 바로 미래 가격을 계산하기보다 다음 순서를 지켜 보세요.</p>\n<ol>\n<li class=\"\">최근 거래가 어느 조건의 거래인지 확인합니다.</li>\n<li class=\"\">같은 조건의 거래가 최근 여러 달에도 있었는지 봅니다.</li>\n<li class=\"\">거래 빈도와 직거래 비중을 확인합니다.</li>\n<li class=\"\">대표 시세가 어느 조건을 기준으로 하는지 확인합니다.</li>\n<li class=\"\">12개월 뒤 예상가와 예상 범위를 중심값 하나로 단정하지 않습니다.</li>\n</ol>\n<p>예상 범위를 읽는 법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값을 해석하는 법</a>, 결과 카드의 기준일과 표본 신뢰도는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">아파트 가격 예측 결과의 기준일 읽는 법</a>에서 이어집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최근-거래가-한-건뿐이면-그-가격을-사용하면-안-되나요\">최근 거래가 한 건뿐이면 그 가격을 사용하면 안 되나요?<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98%EA%B0%80-%ED%95%9C-%EA%B1%B4%EB%BF%90%EC%9D%B4%EB%A9%B4-%EA%B7%B8-%EA%B0%80%EA%B2%A9%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-%EC%95%88-%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"최근 거래가 한 건뿐이면 그 가격을 사용하면 안 되나요?에 대한 직접 링크\" title=\"최근 거래가 한 건뿐이면 그 가격을 사용하면 안 되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>사용할 수는 있지만 “최근 확인된 한 건”이라고 표현해야 합니다. 단지 전체의 대표 시세로 확대하기 전에 면적·층·타입·거래 유형과 추가 자료를 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최신-거래가-가장-중요한-것-아닌가요\">최신 거래가 가장 중요한 것 아닌가요?<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%B5%9C%EC%8B%A0-%EA%B1%B0%EB%9E%98%EA%B0%80-%EA%B0%80%EC%9E%A5-%EC%A4%91%EC%9A%94%ED%95%9C-%EA%B2%83-%EC%95%84%EB%8B%8C%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"최신 거래가 가장 중요한 것 아닌가요?에 대한 직접 링크\" title=\"최신 거래가 가장 중요한 것 아닌가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>최신성은 중요하지만 조건과 자료 상태를 함께 봐야 합니다. 최신 거래가 특수한 층·면적·거래 유형에 해당하면 단지 전체의 기준으로 쓰기 어려울 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"직거래는-무조건-제외해야-하나요\">직거래는 무조건 제외해야 하나요?<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%A7%81%EA%B1%B0%EB%9E%98%EB%8A%94-%EB%AC%B4%EC%A1%B0%EA%B1%B4-%EC%A0%9C%EC%99%B8%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"직거래는 무조건 제외해야 하나요?에 대한 직접 링크\" title=\"직거래는 무조건 제외해야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>무조건 제외한다고 단정하기보다 일반 매매와 분리해서 비교하는 것이 좋습니다. 거래 유형이 다르면 가격 형성 과정과 비용 구조가 다를 수 있기 때문입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거래-회전율이-높으면-가격이-오른다는-뜻인가요\">거래 회전율이 높으면 가격이 오른다는 뜻인가요?<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EA%B1%B0%EB%9E%98-%ED%9A%8C%EC%A0%84%EC%9C%A8%EC%9D%B4-%EB%86%92%EC%9C%BC%EB%A9%B4-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%98%A4%EB%A5%B8%EB%8B%A4%EB%8A%94-%EB%9C%BB%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"거래 회전율이 높으면 가격이 오른다는 뜻인가요?에 대한 직접 링크\" title=\"거래 회전율이 높으면 가격이 오른다는 뜻인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 거래 회전율은 거래 활발함을 보는 참고값이지, 가격 방향이나 상승률을 보장하는 지표가 아닙니다. 가격·거래량·기간을 함께 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-같은-조건으로-확인하기\">아파트 인사이트에서 같은 조건으로 확인하기<a href=\"https://alvin.ing/blog/apartment-single-trade-limit#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EA%B0%99%EC%9D%80-%EC%A1%B0%EA%B1%B4%EC%9C%BC%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 같은 조건으로 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 같은 조건으로 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>단지의 최근 거래 목록과 최근 1년 거래 범위는 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>에서 평형별로 바로 확인할 수 있습니다. 1년 뒤 흐름까지 보려면 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">가입 없이 아파트 가격 예측</a>에서 지역과 단지를 검색하고, 자동 선택된 평형과 최근 대표 시세를 확인해 보세요. 거래 분포와 필터를 더 자세히 비교하려면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 웹 서비스</a>에서 관심 단지의 분석 화면으로 이어갈 수 있습니다.</p>\n<p>관련 글로는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 결과를 확인하는 5단계</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">기간별 전망 비교</a>, <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">표본 신뢰도와 기준일 읽기</a>를 추천합니다.</p>\n<p>통계의 정의와 비교 조건부터 정리하려면 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>를 함께 읽어 보세요.</p>\n<blockquote>\n<p>실거래 자료와 공개 예측은 시점·면적·층·타입·거래 상태에 따라 다르게 해석될 수 있습니다. 이 글은 특정 아파트의 매수·매도 판단을 권하지 않으며 가격·거래 가능성·수익을 보장하지 않습니다. 계약 전에는 최신 공식 자료와 실제 거래 조건을 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-single-trade-limit",
            "title": "아파트 실거래가 보는 법: 최근 거래 한 건만 믿으면 위험한 이유",
            "summary": "최근 실거래 한 건이 아파트 전체 시세를 대표하지 않는 이유와 면적·층·타입·직거래 여부 등 아파트 실거래가를 제대로 보는 6가지 기준을 정리합니다.",
            "date_modified": "2026-09-01T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-forecast-metadata",
            "content_html": "<p>아파트 가격 예측 결과에서 예상가만 확인하면, 그 숫자가 언제 계산되었고 어떤 자료를 함께 봤는지 알기 어렵습니다. 같은 단지라도 새 거래가 추가되거나 시장 정보가 갱신되면 결과가 달라질 수 있습니다.</p>\n<p>그래서 가격 카드 주변에 표시되는 <strong>기준일</strong>, <strong>시장 정보</strong>, <strong>표본 신뢰도</strong>를 함께 봐야 합니다. 이 세 항목은 숫자를 더 그럴듯하게 꾸미는 장식이 아니라, 결과를 어느 정도까지 믿고 어떤 자료를 추가로 확인할지 알려주는 맥락입니다.</p>\n<p>이 글에서는 아파트 인사이트 공개 체험에서 결과를 확인한 뒤 날짜와 자료 상태를 기록하는 방법을 설명합니다. 예측값의 정확도를 보장하는 방법이 아니라, 숫자의 출처와 한계를 놓치지 않는 읽기 방법입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-기준일-언제까지의-정보인가\">1. 기준일: “언제까지의 정보인가”<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#1-%EA%B8%B0%EC%A4%80%EC%9D%BC-%EC%96%B8%EC%A0%9C%EA%B9%8C%EC%A7%80%EC%9D%98-%EC%A0%95%EB%B3%B4%EC%9D%B8%EA%B0%80\" class=\"hash-link\" aria-label=\"1. 기준일: “언제까지의 정보인가”에 대한 직접 링크\" title=\"1. 기준일: “언제까지의 정보인가”에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기준일은 예측이 어떤 시점의 자료를 바탕으로 했는지 이해하기 위한 날짜입니다. 예측을 화면에서 본 날짜와 항상 같은 뜻은 아닙니다.</p>\n<p>실거래에는 계약일·신고일·공개일 사이의 차이가 생길 수 있습니다. 시장 정보도 금리, 환율, 지역 매수심리처럼 지표마다 갱신 주기가 다릅니다. 따라서 “오늘 화면을 열었다”는 사실만으로 모든 값이 오늘의 정보라고 생각하면 안 됩니다.</p>\n<p>결과를 기록할 때는 적어도 다음 날짜를 나누어 적는 것이 좋습니다.</p>\n<table><thead><tr><th>날짜</th><th>확인할 내용</th></tr></thead><tbody><tr><td>조회일</td><td>내가 화면을 본 날짜와 시간</td></tr><tr><td>가격 기준일</td><td>최근 대표 시세를 해석할 기준일</td></tr><tr><td>최근 거래일</td><td>가격 기준에 포함된 최신 계약일</td></tr><tr><td>목표 시점</td><td>6개월·12개월·18개월 뒤의 예상 시점</td></tr><tr><td>시장 정보 기준일</td><td>금리·환율·지역 정보 각각의 날짜</td></tr></tbody></table>\n<p>이 날짜를 구분해 두면 며칠 뒤 결과가 바뀌었을 때 새 거래 때문인지, 시장 정보 갱신 때문인지, 기간이나 평형이 달라졌기 때문인지 추적할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-시장-정보-가격의-단독-원인이-아닌-맥락\">2. 시장 정보: 가격의 단독 원인이 아닌 맥락<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#2-%EC%8B%9C%EC%9E%A5-%EC%A0%95%EB%B3%B4-%EA%B0%80%EA%B2%A9%EC%9D%98-%EB%8B%A8%EB%8F%85-%EC%9B%90%EC%9D%B8%EC%9D%B4-%EC%95%84%EB%8B%8C-%EB%A7%A5%EB%9D%BD\" class=\"hash-link\" aria-label=\"2. 시장 정보: 가격의 단독 원인이 아닌 맥락에 대한 직접 링크\" title=\"2. 시장 정보: 가격의 단독 원인이 아닌 맥락에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>공개 예측 결과에는 계산 시점에 함께 확인한 시장 참고 정보가 표시될 수 있습니다. 예를 들어 금리, 환율, 지역 매수심리 같은 값과 각각의 기준일이 함께 제시될 수 있습니다.</p>\n<p>이 정보는 “금리가 올랐으니 아파트 가격이 반드시 내린다”처럼 단독 원인을 선언하기 위한 것이 아닙니다. 아파트 가격은 공급, 거래량, 자금 부담, 지역 수요, 단지의 거래 조건이 함께 작용할 수 있습니다.</p>\n<table><thead><tr><th>표시 정보</th><th>이렇게 읽기</th><th>이렇게 읽지 않기</th></tr></thead><tbody><tr><td>금리</td><td>대출과 자금 부담을 살피는 시장 조건</td><td>금리 하나로 가격 방향 확정</td></tr><tr><td>환율·대외 환경</td><td>국내 시장에 영향을 줄 수 있는 주변 조건</td><td>환율 변화만으로 단지 가격 계산</td></tr><tr><td>지역 매수심리</td><td>해당 지역의 거래 분위기를 보는 참고값</td><td>특정 단지의 매수 의사로 단정</td></tr><tr><td>기준일</td><td>자료가 어느 시점에 갱신됐는지 확인</td><td>화면 조회일과 항상 같다고 가정</td></tr></tbody></table>\n<p>시장 정보는 가격을 해석하는 배경입니다. 실제 거래가 추가되거나 지역 분위기가 달라지면 같은 단지의 결과가 이전과 달라질 수 있으므로, 값 자체보다 날짜와 함께 봐야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-표본-신뢰도-정확도-보증이-아닌-자료-상태\">3. 표본 신뢰도: 정확도 보증이 아닌 자료 상태<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#3-%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84-%EC%A0%95%ED%99%95%EB%8F%84-%EB%B3%B4%EC%A6%9D%EC%9D%B4-%EC%95%84%EB%8B%8C-%EC%9E%90%EB%A3%8C-%EC%83%81%ED%83%9C\" class=\"hash-link\" aria-label=\"3. 표본 신뢰도: 정확도 보증이 아닌 자료 상태에 대한 직접 링크\" title=\"3. 표본 신뢰도: 정확도 보증이 아닌 자료 상태에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>표본 신뢰도는 예측이 맞을 확률이나 수익률을 의미하지 않습니다. 해당 단지의 거래 표본이 얼마나 안정적으로 비교되는지 판단하기 위한 참고 지표입니다.</p>\n<p>표본 신뢰도가 높게 표시되어도 실제 가격이 반드시 예상 범위 안에 들어간다는 뜻은 아닙니다. 반대로 낮게 표시된다고 해서 결과가 반드시 틀린다는 뜻도 아닙니다. 다만 거래가 적거나 최근 거래가 드문 경우에는 결과를 더 보수적으로 읽고 최신 공식 자료를 추가로 확인해야 한다는 신호입니다.</p>\n<p>표본 신뢰도를 볼 때는 숫자만 보지 말고 다음 질문을 함께 확인하세요.</p>\n<ol>\n<li class=\"\">대표 시세와 예상 범위가 같은 평형을 기준으로 하는가?</li>\n<li class=\"\">최근 거래가 같은 면적과 비슷한 조건에서 반복되는가?</li>\n<li class=\"\">거래일과 기준일 사이에 긴 공백이 있는가?</li>\n<li class=\"\">저층·고층, 타입, 직거래처럼 비교를 나눠야 할 조건이 섞였는가?</li>\n</ol>\n<p>표본 신뢰도는 “이 결과를 믿어도 되는가?”라는 이분법적 답이 아니라, “이 결과와 함께 어떤 자료를 더 봐야 하는가?”에 가까운 안내입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과가-바뀌었을-때-원인을-찾는-순서\">결과가 바뀌었을 때 원인을 찾는 순서<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B0%94%EB%80%8C%EC%97%88%EC%9D%84-%EB%95%8C-%EC%9B%90%EC%9D%B8%EC%9D%84-%EC%B0%BE%EB%8A%94-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"결과가 바뀌었을 때 원인을 찾는 순서에 대한 직접 링크\" title=\"결과가 바뀌었을 때 원인을 찾는 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>어제 본 결과와 오늘 본 결과가 다르면 곧바로 분석 오류라고 결론 내리지 마세요. 아래 순서로 조건을 맞춰 보세요.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"첫째-단지와-평형을-확인합니다\">첫째, 단지와 평형을 확인합니다<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%B2%AB%EC%A7%B8-%EB%8B%A8%EC%A7%80%EC%99%80-%ED%8F%89%ED%98%95%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"첫째, 단지와 평형을 확인합니다에 대한 직접 링크\" title=\"첫째, 단지와 평형을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>자동으로 선택된 대표 평형이 달라졌거나 사용자가 다른 평형을 선택했을 수 있습니다. 같은 단지라도 전용면적이 달라지면 비교 거래와 현재 기준값이 달라집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"둘째-최근-거래의-추가-여부를-확인합니다\">둘째, 최근 거래의 추가 여부를 확인합니다<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EB%91%98%EC%A7%B8-%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98%EC%9D%98-%EC%B6%94%EA%B0%80-%EC%97%AC%EB%B6%80%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"둘째, 최근 거래의 추가 여부를 확인합니다에 대한 직접 링크\" title=\"둘째, 최근 거래의 추가 여부를 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>새 거래가 공개되면 최근 대표 시세가 달라질 수 있습니다. 특히 거래가 드문 단지는 한 건의 추가 거래가 결과에 더 크게 보일 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"셋째-시장-정보-기준일을-비교합니다\">셋째, 시장 정보 기준일을 비교합니다<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%85%8B%EC%A7%B8-%EC%8B%9C%EC%9E%A5-%EC%A0%95%EB%B3%B4-%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9D%84-%EB%B9%84%EA%B5%90%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"셋째, 시장 정보 기준일을 비교합니다에 대한 직접 링크\" title=\"셋째, 시장 정보 기준일을 비교합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>금리·환율·지역 매수심리의 기준일이 갱신됐는지 확인합니다. 모든 정보가 같은 날짜에 갱신되지 않으므로 항목별 날짜를 따로 봐야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"넷째-전망-기간을-맞춥니다\">넷째, 전망 기간을 맞춥니다<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EB%84%B7%EC%A7%B8-%EC%A0%84%EB%A7%9D-%EA%B8%B0%EA%B0%84%EC%9D%84-%EB%A7%9E%EC%B6%A5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"넷째, 전망 기간을 맞춥니다에 대한 직접 링크\" title=\"넷째, 전망 기간을 맞춥니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>6개월·12개월·18개월처럼 목표 기간이 달라지면 목표 시점과 불확실성의 폭도 달라집니다. 기간 비교 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 아파트 전망을 비교하는 방법</a>에서 설명합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"다섯째-범위의-폭을-확인합니다\">다섯째, 범위의 폭을 확인합니다<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EB%8B%A4%EC%84%AF%EC%A7%B8-%EB%B2%94%EC%9C%84%EC%9D%98-%ED%8F%AD%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"다섯째, 범위의 폭을 확인합니다에 대한 직접 링크\" title=\"다섯째, 범위의 폭을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>중심 예상가가 비슷해도 아래쪽·위쪽 범위가 넓어졌을 수 있습니다. 결과가 바뀌었는지 확인할 때는 중심값 하나가 아니라 범위 전체를 비교해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과-카드-읽기-실제-확인-순서\">결과 카드 읽기: 실제 확인 순서<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B2%B0%EA%B3%BC-%EC%B9%B4%EB%93%9C-%EC%9D%BD%EA%B8%B0-%EC%8B%A4%EC%A0%9C-%ED%99%95%EC%9D%B8-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"결과 카드 읽기: 실제 확인 순서에 대한 직접 링크\" title=\"결과 카드 읽기: 실제 확인 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 가입 없는 공개 예측</a>에서 아파트를 검색했다면 다음 순서로 카드를 읽어 보세요.</p>\n<ol>\n<li class=\"\">지역과 단지명이 내가 찾는 곳과 맞는지 확인합니다.</li>\n<li class=\"\">자동 선택 또는 직접 선택한 평형을 확인합니다.</li>\n<li class=\"\">최근 대표 시세와 최근 거래일을 확인합니다.</li>\n<li class=\"\">12개월 뒤 예상가와 아래·가운데·위 예상 범위를 함께 봅니다.</li>\n<li class=\"\">표본 신뢰도의 의미를 확인하고 정확도 보증으로 사용하지 않습니다.</li>\n<li class=\"\">시장 정보별 값과 기준일을 확인합니다.</li>\n<li class=\"\">조회일·평형·범위를 메모합니다.</li>\n</ol>\n<p>이 순서를 지키면 숫자만 캡처해 두었다가 나중에 의미를 잃는 일을 줄일 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"가상의-기록-예시\">가상의 기록 예시<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B0%80%EC%83%81%EC%9D%98-%EA%B8%B0%EB%A1%9D-%EC%98%88%EC%8B%9C\" class=\"hash-link\" aria-label=\"가상의 기록 예시에 대한 직접 링크\" title=\"가상의 기록 예시에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음은 특정 단지의 실제 결과가 아닌 기록 방법을 보여주는 예시입니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">조회일: 2026-09-01</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">단지·지역: 가상 단지 / 가상 시군구</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">평형: 전용 84㎡</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">최근 대표 시세: 10억 원</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">최근 거래일: 2026-08-20</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">12개월 뒤 예상가: 10억 4,000만 원</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">예상 범위: 9억 5,000만 ~ 11억 2,000만 원</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">표본 신뢰도: 화면 표시값을 참고용으로 기록</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">금리 기준일: 2026-08-29</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">환율 기준일: 2026-08-29</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">지역 매수심리 기준일: 2026-08-26</span><br></div></code></pre></div></div>\n<p>다음에 결과를 다시 확인했을 때 예상가가 10억 2,000만 원으로 바뀌었다면, 먼저 최근 거래일과 시장 정보 기준일을 비교합니다. 평형이 같고 새 거래가 들어왔다면 가격 기준이 달라진 것일 수 있고, 기간을 바꿨다면 목표 시점이 달라진 것입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공식-자료를-함께-확인해야-하는-이유\">공식 자료를 함께 확인해야 하는 이유<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B3%B5%EC%8B%9D-%EC%9E%90%EB%A3%8C%EB%A5%BC-%ED%95%A8%EA%BB%98-%ED%99%95%EC%9D%B8%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"공식 자료를 함께 확인해야 하는 이유에 대한 직접 링크\" title=\"공식 자료를 함께 확인해야 하는 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>예측 화면은 자료를 한 번에 비교하기 좋은 도구지만, 계약에 필요한 모든 정보를 대신하지는 않습니다. 다음 공식 자료를 함께 확인하세요.</p>\n<ul>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>: 계약일·면적·층·거래금액 확인</li>\n<li class=\"\"><a href=\"https://www.reb.or.kr/r-one/portal/main/indexPage.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국부동산원 R-ONE</a>: 주택가격지수와 거래 현황 확인</li>\n<li class=\"\"><a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 미래가격 예측 공식 가이드</a>: 예측 결과와 범위를 읽는 공개 설명</li>\n</ul>\n<p>공식 자료의 최신성과 공개 체험의 기준일이 다를 수 있으므로, 두 숫자를 억지로 하나로 맞추기보다 차이가 생긴 이유를 기록하는 편이 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예상-범위와-표본-신뢰도를-함께-읽는-방법\">예상 범위와 표본 신뢰도를 함께 읽는 방법<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%98%88%EC%83%81-%EB%B2%94%EC%9C%84%EC%99%80-%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84%EB%A5%BC-%ED%95%A8%EA%BB%98-%EC%9D%BD%EB%8A%94-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"예상 범위와 표본 신뢰도를 함께 읽는 방법에 대한 직접 링크\" title=\"예상 범위와 표본 신뢰도를 함께 읽는 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>표본 신뢰도가 낮고 예상 범위도 넓다면, 가운데 값만 보고 계획을 고정하기보다 추가 거래와 현금흐름을 먼저 확인하세요. 표본 신뢰도가 높고 범위가 좁더라도 미래의 정책·공급·금리 변화까지 사라지는 것은 아닙니다.</p>\n<p>아래 표처럼 두 항목을 조합해 읽을 수 있습니다.</p>\n<table><thead><tr><th>표본 신뢰도</th><th>예상 범위</th><th>읽는 방법</th></tr></thead><tbody><tr><td>높음</td><td>좁음</td><td>비교 조건과 기준일을 확인한 뒤 추적 관찰</td></tr><tr><td>높음</td><td>넓음</td><td>자료는 비교적 안정적이지만 미래 조건의 변화를 크게 봄</td></tr><tr><td>낮음</td><td>좁음</td><td>숫자가 정밀해 보여도 거래 표본을 먼저 재확인</td></tr><tr><td>낮음</td><td>넓음</td><td>추가 실거래·매물·공식 통계를 확인하고 보수적으로 해석</td></tr></tbody></table>\n<p>이 표는 좋고 나쁨을 판정하는 등급표가 아닙니다. 결과를 어떤 강도로 사용할지 정하기 위한 질문표입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기준일이-오늘-날짜와-다르면-결과가-오래된-건가요\">기준일이 오늘 날짜와 다르면 결과가 오래된 건가요?<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9D%B4-%EC%98%A4%EB%8A%98-%EB%82%A0%EC%A7%9C%EC%99%80-%EB%8B%A4%EB%A5%B4%EB%A9%B4-%EA%B2%B0%EA%B3%BC%EA%B0%80-%EC%98%A4%EB%9E%98%EB%90%9C-%EA%B1%B4%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"기준일이 오늘 날짜와 다르면 결과가 오래된 건가요?에 대한 직접 링크\" title=\"기준일이 오늘 날짜와 다르면 결과가 오래된 건가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>반드시 그렇지는 않습니다. 실거래와 시장 정보는 계약·신고·공개·갱신 시점이 다를 수 있습니다. 어떤 항목의 기준일인지 확인하고, 최근 거래일과 함께 판단해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"표본-신뢰도가-높으면-예측이-맞나요\">표본 신뢰도가 높으면 예측이 맞나요?<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%ED%91%9C%EB%B3%B8-%EC%8B%A0%EB%A2%B0%EB%8F%84%EA%B0%80-%EB%86%92%EC%9C%BC%EB%A9%B4-%EC%98%88%EC%B8%A1%EC%9D%B4-%EB%A7%9E%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"표본 신뢰도가 높으면 예측이 맞나요?에 대한 직접 링크\" title=\"표본 신뢰도가 높으면 예측이 맞나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 표본 신뢰도는 거래 자료를 비교하는 상태를 알려주는 참고 지표입니다. 실제 가격과 거래 가능성, 수익을 보장하지 않습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"시장-정보가-좋아지면-아파트-가격도-반드시-오르나요\">시장 정보가 좋아지면 아파트 가격도 반드시 오르나요?<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%8B%9C%EC%9E%A5-%EC%A0%95%EB%B3%B4%EA%B0%80-%EC%A2%8B%EC%95%84%EC%A7%80%EB%A9%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EB%8F%84-%EB%B0%98%EB%93%9C%EC%8B%9C-%EC%98%A4%EB%A5%B4%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"시장 정보가 좋아지면 아파트 가격도 반드시 오르나요?에 대한 직접 링크\" title=\"시장 정보가 좋아지면 아파트 가격도 반드시 오르나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 금리·환율·지역 매수심리는 여러 참고 정보 중 일부입니다. 공급, 거래량, 단지 조건과 개인의 자금 여건을 함께 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과가-바뀌면-어느-값이-맞는-건가요\">결과가 바뀌면 어느 값이 맞는 건가요?<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B0%94%EB%80%8C%EB%A9%B4-%EC%96%B4%EB%8A%90-%EA%B0%92%EC%9D%B4-%EB%A7%9E%EB%8A%94-%EA%B1%B4%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"결과가 바뀌면 어느 값이 맞는 건가요?에 대한 직접 링크\" title=\"결과가 바뀌면 어느 값이 맞는 건가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저 평형, 기준일, 최근 거래, 목표 기간, 시장 정보 기준일을 맞춰 보세요. 조건이 달라진 결과는 서로 다른 시점의 참고값일 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-기준일과-범위-확인하기\">아파트 인사이트에서 기준일과 범위 확인하기<a href=\"https://alvin.ing/blog/apartment-forecast-metadata#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EA%B8%B0%EC%A4%80%EC%9D%BC%EA%B3%BC-%EB%B2%94%EC%9C%84-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 기준일과 범위 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 기준일과 범위 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트의 가입 없는 공개 예측</a>에서 관심 단지를 검색하고, 결과를 확인한 날짜와 평형을 함께 기록해 보세요. 예측 범위의 아래·가운데·위 값을 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위 해석 가이드</a>, 검색부터 결과 확인까지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하는 방법</a>에서 이어서 볼 수 있습니다.</p>\n<p>더 긴 기간을 비교하려면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">기간별 전망 비교</a>, 거래 한 건의 한계를 확인하려면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건으로 시세를 판단하면 안 되는 이유</a>를 참고하세요.</p>\n<p>가격·거래량·기간·지역을 어떤 순서로 비교할지 먼저 정리하려면 <a class=\"\" href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order\">부동산과 아파트 통계를 처음 읽는 순서</a>에서 기본 체크리스트를 확인할 수 있습니다.</p>\n<blockquote>\n<p>아파트 인사이트의 가격 예측과 시장 정보는 공개 데이터와 경제 시나리오를 바탕으로 한 참고용 분석입니다. 화면의 요약과 표본 신뢰도는 정확도·적중률·수익을 보장하지 않으며, 투자 권유나 투자 자문이 아닙니다. 계약과 최종 판단 전에는 최신 공식 자료와 개인의 자금 조건을 별도로 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-forecast-metadata",
            "title": "아파트 가격 예측 결과에서 기준일·시장 정보·표본 신뢰도 읽는 법",
            "summary": "아파트 가격 예측 결과의 기준일, 시장 참고 정보, 표본 신뢰도가 각각 무엇을 뜻하는지 설명합니다. 결과가 바뀌었을 때 원인을 추적하는 기록법도 정리합니다.",
            "date_modified": "2026-09-01T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-transaction-cost-calculator",
            "content_html": "\n<p>아파트 매매를 검토할 때 가장 먼저 보는 숫자는 매매가격입니다. 하지만 실제로 준비해야 하는 돈은 매매가격과 다를 수 있습니다. 매수할 때는 취득세와 중개보수 같은 비용이 더해지고, 매도할 때는 양도소득세와 중개보수 등이 빠지기 때문입니다.</p>\n<p>그래서 같은 아파트의 같은 가격을 보더라도 질문은 두 가지로 나누어야 합니다.</p>\n<ul>\n<li class=\"\"><strong>매수한다면 현금이 얼마나 더 필요한가</strong></li>\n<li class=\"\"><strong>매도한다면 최종적으로 얼마를 받을 수 있는가</strong></li>\n</ul>\n<p>이 글에서는 이 두 질문을 분리해서 거래비용을 계산하는 방법과, 아파트 인사이트의 거래비용 계산기가 어떤 방식으로 결과를 보여주는지 정리합니다. 세율과 감면 요건은 거래일·자산 상태·가구 조건에 따라 달라질 수 있으므로, 특정 금액을 확정하기보다 계산 결과를 자금 계획을 위한 참고값으로 읽는 데 초점을 둡니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거래비용은-가격-예측과-다른-숫자다\">거래비용은 가격 예측과 다른 숫자다<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EA%B1%B0%EB%9E%98%EB%B9%84%EC%9A%A9%EC%9D%80-%EA%B0%80%EA%B2%A9-%EC%98%88%EC%B8%A1%EA%B3%BC-%EB%8B%A4%EB%A5%B8-%EC%88%AB%EC%9E%90%EB%8B%A4\" class=\"hash-link\" aria-label=\"거래비용은 가격 예측과 다른 숫자다에 대한 직접 링크\" title=\"거래비용은 가격 예측과 다른 숫자다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>가격 예측은 앞으로의 가격 경로를 추정하는 일이고, 거래비용 계산은 그 가격으로 실제 거래할 때 발생할 현금흐름을 가늠하는 일입니다. 둘을 한 숫자로 섞으면 “가격이 올랐다”와 “필요한 현금이 늘었다”를 혼동하기 쉽습니다.</p>\n<p>거래 방향에 따라 결과의 의미도 달라집니다.</p>\n<table><thead><tr><th>거래 방향</th><th>계산에 더하거나 빼는 항목</th><th>결과를 읽는 기준</th></tr></thead><tbody><tr><td>매수</td><td>취득 관련 세금, 중개보수, 선택한 기타 비용</td><td><strong>총 필요자금</strong></td></tr><tr><td>매도</td><td>양도소득세, 지방소득세, 중개보수, 선택한 기타 비용</td><td><strong>예상 순수령액</strong></td></tr></tbody></table>\n<p>시뮬레이션에서는 거래비용을 A안·B안의 최종 금액에 반영합니다. 매수의 <code>+</code> 보정은 예측가격이 상승했다는 뜻이 아니라, 거래를 위해 준비할 현금이 늘었다는 뜻입니다. 반대로 매도 결과의 음수 보정은 세금과 비용을 차감한 뒤 예상 순수령액이 줄어드는 구조를 나타냅니다.</p>\n<p>다만 모든 화면이 같은 기준을 쓰는 것은 아닙니다. 현재 가격과 비교하는 카드는 가격 자체의 변화를 보여주는 자리이므로 거래비용을 제외한 가격 기준을 유지하고, 확률 분포 역시 거래비용 반영 전 예측으로 표시합니다. 이 범위를 분리해야 가격 전망과 현금 계획을 서로 다른 질문으로 읽을 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기능은-어디에서-시작할까\">기능은 어디에서 시작할까<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EA%B8%B0%EB%8A%A5%EC%9D%80-%EC%96%B4%EB%94%94%EC%97%90%EC%84%9C-%EC%8B%9C%EC%9E%91%ED%95%A0%EA%B9%8C\" class=\"hash-link\" aria-label=\"기능은 어디에서 시작할까에 대한 직접 링크\" title=\"기능은 어디에서 시작할까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>시뮬레이션의 가중 팩터 모델 영역에서 <code>거래비용</code> 버튼을 누르면 매수 또는 매도 한 방향을 선택해 조건을 입력할 수 있습니다. 적용 후에는 A안·B안 각각에 맞춘 거래비용 보정 카드가 추가됩니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"시뮬레이션 화면에서 거래비용 버튼과 매수 조건이 반영된 결과를 보여주는 예시\" src=\"https://alvin.ing/assets/images/transaction-cost-overview-0b55cb867077b454ef43442a57822b61.png\" width=\"2676\" height=\"2002\" class=\"img_ev3q\"></p>\n<p>화면의 보정 카드에서 확인할 수 있는 핵심은 세 가지입니다.</p>\n<ol>\n<li class=\"\">거래 방향이 매수인지 매도인지</li>\n<li class=\"\">비용이 가격 예측이 아니라 총 필요자금 또는 예상 순수령액 기준인지</li>\n<li class=\"\">어떤 정책 기준일과 입력 조건으로 계산했는지</li>\n</ol>\n<p>거래비용 계산은 현재 시뮬레이션 화면의 조건을 바탕으로 동작합니다. 계산 결과가 과거 예측 이력이나 공유 결과에 그대로 저장되는 방식이 아니므로, 다른 조건을 비교할 때는 해당 조건을 다시 입력해 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"매수-예측가에-비용을-더해-총-필요자금-보기\">매수: 예측가에 비용을 더해 총 필요자금 보기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EB%A7%A4%EC%88%98-%EC%98%88%EC%B8%A1%EA%B0%80%EC%97%90-%EB%B9%84%EC%9A%A9%EC%9D%84-%EB%8D%94%ED%95%B4-%EC%B4%9D-%ED%95%84%EC%9A%94%EC%9E%90%EA%B8%88-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"매수: 예측가에 비용을 더해 총 필요자금 보기에 대한 직접 링크\" title=\"매수: 예측가에 비용을 더해 총 필요자금 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>매수 쪽 계산은 다음과 같은 구조로 이해하면 쉽습니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">총 필요자금</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= 매수 기준금액</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 취득세 관련 비용</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 중개보수</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 선택한 기타 비용</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"취득-관련-비용\">취득 관련 비용<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%B7%A8%EB%93%9D-%EA%B4%80%EB%A0%A8-%EB%B9%84%EC%9A%A9\" class=\"hash-link\" aria-label=\"취득 관련 비용에 대한 직접 링크\" title=\"취득 관련 비용에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>주택 매수에서는 취득세를 중심으로 지방교육세와 농어촌특별세가 함께 검토될 수 있습니다. 실제 적용 여부와 금액은 취득가액, 주택 보유 수, 조정대상지역 여부, 주택의 전용면적, 거래 형태 등에 따라 달라집니다.</p>\n<p>계산기에서는 일반 아파트 매매와 분양권 거래 조건을 구분하고, 주택 보유 수가 여러 채인 경우에는 중과 적용 여부를 별도로 확인합니다. 필요한 조건을 선택하지 않은 상태에서 임의의 세율을 적용하지 않고 <code>계산 보류</code>로 두는 이유도 여기에 있습니다.</p>\n<p>전용면적은 농어촌특별세 적용 여부를 판단하는 입력으로 사용됩니다. 단지 대표 면적을 참고값으로 채우더라도 사용자가 실제 계약 면적으로 수정할 수 있어야 하며, 면적이 표시되었다고 해서 다른 세금 요건까지 자동으로 확정되는 것은 아닙니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"중개보수와-기타-비용\">중개보수와 기타 비용<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%A4%91%EA%B0%9C%EB%B3%B4%EC%88%98%EC%99%80-%EA%B8%B0%ED%83%80-%EB%B9%84%EC%9A%A9\" class=\"hash-link\" aria-label=\"중개보수와 기타 비용에 대한 직접 링크\" title=\"중개보수와 기타 비용에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>중개보수는 법정 상한요율을 기준으로 한 참고값입니다. 실제 보수는 지역 조례와 거래금액 구간, 중개의뢰인과 중개사 사이의 협의에 따라 달라질 수 있고 부가가치세가 별도로 붙을 수 있습니다. 따라서 계산기에서 중개보수를 포함하더라도 계약 전에는 중개사에게 실제 협의 금액을 확인해야 합니다.</p>\n<p>기타 비용은 법정 비용으로 단정하지 않고 사용자가 직접 입력하는 참고 항목으로 보는 편이 안전합니다. 법무사 비용, 인지대, 이사비, 대출 관련 비용처럼 거래 구조에 따라 달라지는 항목은 계약 조건과 금융기관 안내를 따로 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"매도-세금과-비용을-빼고-예상-순수령액-보기\">매도: 세금과 비용을 빼고 예상 순수령액 보기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EB%A7%A4%EB%8F%84-%EC%84%B8%EA%B8%88%EA%B3%BC-%EB%B9%84%EC%9A%A9%EC%9D%84-%EB%B9%BC%EA%B3%A0-%EC%98%88%EC%83%81-%EC%88%9C%EC%88%98%EB%A0%B9%EC%95%A1-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"매도: 세금과 비용을 빼고 예상 순수령액 보기에 대한 직접 링크\" title=\"매도: 세금과 비용을 빼고 예상 순수령액 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>매도 쪽은 매수와 반대 방향으로 계산합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">예상 순수령액</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= 매도 기준금액</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">- 양도소득세</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">- 지방소득세</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">- 중개보수</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">- 선택한 기타 비용</span><br></div></code></pre></div></div>\n<p>양도소득세는 단순히 “현재 가격과 미래 가격의 차이”만으로 결정되지 않습니다. 취득가액과 필요경비, 취득일과 양도일, 보유기간, 거주기간, 자산 상태, 주택 보유 수, 비과세·중과 요건 등을 함께 봐야 합니다.</p>\n<p>특히 A안과 B안의 목표 시점이 서로 다르면 보유개월과 거주기간도 달라집니다. 한 시나리오에서는 장기 보유 요건을 충족하고 다른 시나리오에서는 단기 세율이 적용되는 것처럼, 두 안의 세율 체계가 달라질 수 있습니다. 이럴 때 두 결과에 같은 비율을 적용하면 계산은 간단해 보여도 조건을 제대로 반영하지 못합니다.</p>\n<p>양도차손처럼 과세할 양도소득이 없는 경우에는 납부 세액이 0원으로 표시될 수 있습니다. 0원이 표시되었다고 해서 모든 신고 의무나 계약 관련 비용이 사라지는 것은 아니므로, 실제 신고와 비용 확인은 별도로 진행해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"입력-다이얼로그에서는-무엇을-확인할까\">입력 다이얼로그에서는 무엇을 확인할까<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%9E%85%EB%A0%A5-%EB%8B%A4%EC%9D%B4%EC%96%BC%EB%A1%9C%EA%B7%B8%EC%97%90%EC%84%9C%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A0%EA%B9%8C\" class=\"hash-link\" aria-label=\"입력 다이얼로그에서는 무엇을 확인할까에 대한 직접 링크\" title=\"입력 다이얼로그에서는 무엇을 확인할까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"거래비용 계산 다이얼로그에서 매수 조건과 부대비용을 입력하는 예시\" src=\"https://alvin.ing/assets/images/transaction-cost-dialog-bc3a775ccdf18bca55b7483f35f63dd0.png\" width=\"2666\" height=\"1994\" class=\"img_ev3q\"></p>\n<p>입력 화면은 항목을 많이 채우는 것보다 <strong>계산 기준이 무엇인지 확인하는 것</strong>이 중요합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-매수와-매도-방향을-먼저-고르기\">1. 매수와 매도 방향을 먼저 고르기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#1-%EB%A7%A4%EC%88%98%EC%99%80-%EB%A7%A4%EB%8F%84-%EB%B0%A9%ED%96%A5%EC%9D%84-%EB%A8%BC%EC%A0%80-%EA%B3%A0%EB%A5%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"1. 매수와 매도 방향을 먼저 고르기에 대한 직접 링크\" title=\"1. 매수와 매도 방향을 먼저 고르기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>매수와 매도 비용은 서로 다른 세금과 결과 표현을 사용합니다. 한 방향을 적용한 뒤 반대 방향으로 바꾸면 이전 거래비용 상태를 이어 붙이지 않고 새 조건으로 다시 계산하는 흐름이 안전합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-기준일과-금액을-실제-계약-조건에-맞추기\">2. 기준일과 금액을 실제 계약 조건에 맞추기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#2-%EA%B8%B0%EC%A4%80%EC%9D%BC%EA%B3%BC-%EA%B8%88%EC%95%A1%EC%9D%84-%EC%8B%A4%EC%A0%9C-%EA%B3%84%EC%95%BD-%EC%A1%B0%EA%B1%B4%EC%97%90-%EB%A7%9E%EC%B6%94%EA%B8%B0\" class=\"hash-link\" aria-label=\"2. 기준일과 금액을 실제 계약 조건에 맞추기에 대한 직접 링크\" title=\"2. 기준일과 금액을 실제 계약 조건에 맞추기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>취득가액, 취득일, 양도 예정일, 매수 예정일, 주택 보유 수 같은 입력은 세율 체계와 기간 요건에 영향을 줍니다. 빈 값을 0원이나 임의의 날짜로 채워 계산하는 것보다, 필요한 값이 없으면 계산을 멈추고 추가 입력을 요청하는 편이 낫습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-포함할-부대비용을-선택하기\">3. 포함할 부대비용을 선택하기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#3-%ED%8F%AC%ED%95%A8%ED%95%A0-%EB%B6%80%EB%8C%80%EB%B9%84%EC%9A%A9%EC%9D%84-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"3. 포함할 부대비용을 선택하기에 대한 직접 링크\" title=\"3. 포함할 부대비용을 선택하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>중개보수와 기타 비용은 체크한 항목만 합계에 들어갑니다. 포함 여부를 바꾸면 A안·B안의 보정값도 함께 달라지므로, 결과를 저장하거나 공유하기 전에 체크 상태를 다시 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-계산-보류-메시지를-무시하지-않기\">4. 계산 보류 메시지를 무시하지 않기<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#4-%EA%B3%84%EC%82%B0-%EB%B3%B4%EB%A5%98-%EB%A9%94%EC%8B%9C%EC%A7%80%EB%A5%BC-%EB%AC%B4%EC%8B%9C%ED%95%98%EC%A7%80-%EC%95%8A%EA%B8%B0\" class=\"hash-link\" aria-label=\"4. 계산 보류 메시지를 무시하지 않기에 대한 직접 링크\" title=\"4. 계산 보류 메시지를 무시하지 않기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>다주택 중과 여부를 선택하지 않았거나, 필요한 취득가·취득일이 없거나, 지원하지 않는 감면 특례를 주장하는 경우에는 정확한 금액 대신 <code>계산 보류</code>가 표시될 수 있습니다. 이것은 오류라기보다 근거가 부족한 숫자를 확정값처럼 보여주지 않기 위한 안전장치입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"분양권은-일반-아파트-매매와-따로-봐야-한다\">분양권은 일반 아파트 매매와 따로 봐야 한다<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EB%B6%84%EC%96%91%EA%B6%8C%EC%9D%80-%EC%9D%BC%EB%B0%98-%EC%95%84%ED%8C%8C%ED%8A%B8-%EB%A7%A4%EB%A7%A4%EC%99%80-%EB%94%B0%EB%A1%9C-%EB%B4%90%EC%95%BC-%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"분양권은 일반 아파트 매매와 따로 봐야 한다에 대한 직접 링크\" title=\"분양권은 일반 아파트 매매와 따로 봐야 한다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>분양권 거래에서는 분양가와 현재 거래금액이 같은 의미가 아닙니다. 기준 분양가에 기납부금, 옵션비, 프리미엄 또는 마이너스 프리미엄을 반영해 실제 거래금액을 구성해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"마피와-플러스피\">마피와 플러스피<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EB%A7%88%ED%94%BC%EC%99%80-%ED%94%8C%EB%9F%AC%EC%8A%A4%ED%94%BC\" class=\"hash-link\" aria-label=\"마피와 플러스피에 대한 직접 링크\" title=\"마피와 플러스피에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>마이너스 피는 기준 분양가에서 프리미엄을 차감하는 구조이고, 플러스 피는 프리미엄을 더하는 구조입니다. 다만 마피 차감액만으로 매수 총액이 완성되는 것은 아닙니다. 중도금 미납분, 이자후불제 승계, 옵션·확장비 등은 별도로 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"손피는-별도-계산이-필요하다\">손피는 별도 계산이 필요하다<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%86%90%ED%94%BC%EB%8A%94-%EB%B3%84%EB%8F%84-%EA%B3%84%EC%82%B0%EC%9D%B4-%ED%95%84%EC%9A%94%ED%95%98%EB%8B%A4\" class=\"hash-link\" aria-label=\"손피는 별도 계산이 필요하다에 대한 직접 링크\" title=\"손피는 별도 계산이 필요하다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>손피는 매도자가 세후 프리미엄을 확보하고 매수자가 양도소득세와 지방소득세를 대신 부담하는 특수한 계약 조건입니다. 일반 거래비용 계산에 손피 세액을 섞으면 프리미엄·양도세·취득세의 기준금액이 혼동될 수 있습니다.</p>\n<p>1년 미만 70%, 1년 이상 60%의 단기보유 세율과 대납세액 재산입을 포함한 계산은 별도 글에서 자세히 설명하고 있습니다. <a class=\"\" href=\"https://alvin.ing/blog/sonpi-tax-calculator/\">분양권 손피 계산기: 프리미엄 3,000만원이면 실제 부담액은?</a></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"왜-모든-조건을-계산해-주지-않을까\">왜 모든 조건을 계산해 주지 않을까<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%99%9C-%EB%AA%A8%EB%93%A0-%EC%A1%B0%EA%B1%B4%EC%9D%84-%EA%B3%84%EC%82%B0%ED%95%B4-%EC%A3%BC%EC%A7%80-%EC%95%8A%EC%9D%84%EA%B9%8C\" class=\"hash-link\" aria-label=\"왜 모든 조건을 계산해 주지 않을까에 대한 직접 링크\" title=\"왜 모든 조건을 계산해 주지 않을까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>거래비용 계산기에서 일부 입력은 금액이 나오지 않고 보류됩니다. 대표적인 이유는 다음과 같습니다.</p>\n<ul>\n<li class=\"\">생애 최초·지방 미분양·인구감소지역 등 취득세 감면 특례의 적용 여부가 개인 조건과 법령 해석에 따라 달라지는 경우</li>\n<li class=\"\">다주택 중과와 중과 유예 중 어느 기준을 적용할지 선택하지 않은 경우</li>\n<li class=\"\">취득일이 양도일보다 늦거나, 기준 분양가처럼 핵심 금액이 없는 경우</li>\n<li class=\"\">분양권의 전매제한 해제일과 매수 예정일 관계를 공식 근거로 확인하지 못한 경우</li>\n</ul>\n<p>세금 계산에서 가장 위험한 것은 빈칸을 그럴듯한 기본값으로 채워 정확해 보이는 금액을 보여주는 것입니다. 계산 보류는 사용자가 계약 조건과 공식 근거를 먼저 확인하도록 만드는 경계선입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"거래비용을-적용한-결과를-읽는-순서\">거래비용을 적용한 결과를 읽는 순서<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EA%B1%B0%EB%9E%98%EB%B9%84%EC%9A%A9%EC%9D%84-%EC%A0%81%EC%9A%A9%ED%95%9C-%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EC%9D%BD%EB%8A%94-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"거래비용을 적용한 결과를 읽는 순서에 대한 직접 링크\" title=\"거래비용을 적용한 결과를 읽는 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>실제 화면에서는 다음 순서로 읽으면 혼동이 적습니다.</p>\n<ol>\n<li class=\"\"><strong>기준 예측</strong>: 거래비용을 적용하기 전 A안·B안 가격 확인</li>\n<li class=\"\"><strong>가격 조건 보정</strong>: 시나리오·보유세 등 가격 자체에 영향을 주는 조건 확인</li>\n<li class=\"\"><strong>거래비용 계산</strong>: 매수 총 필요자금 또는 매도 예상 순수령액 계산</li>\n<li class=\"\"><strong>최종 카드 확인</strong>: A안·B안별 세금·중개보수·기타 비용과 최종 금액 확인</li>\n<li class=\"\"><strong>범위 안내 확인</strong>: 현재 대비 카드와 확률 분포는 거래비용을 반영하기 전 가격 기준인지 확인</li>\n</ol>\n<p>이 순서를 지키면 “예상가격이 올랐는데 왜 현금 부담도 늘었나”와 같은 질문을 분리해서 볼 수 있습니다. 가격 비교는 가격대로, 자금 계획은 거래비용을 포함한 현금흐름대로 확인하는 것입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산-전에-준비할-체크리스트\">계산 전에 준비할 체크리스트<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EA%B3%84%EC%82%B0-%EC%A0%84%EC%97%90-%EC%A4%80%EB%B9%84%ED%95%A0-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"계산 전에 준비할 체크리스트에 대한 직접 링크\" title=\"계산 전에 준비할 체크리스트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">거래 방향: 매수인지 매도인지</li>\n<li class=\"\">기준 금액: 취득가액·양도가액·분양가·프리미엄·기납부금</li>\n<li class=\"\">날짜: 취득일·양도 예정일·매수 예정일·전매제한 해제일</li>\n<li class=\"\">보유 조건: 세대의 주택 수, 보유기간, 거주기간</li>\n<li class=\"\">자산 상태: 등기 후 주택인지 분양권인지</li>\n<li class=\"\">중개보수: 지역 상한요율과 실제 협의 금액</li>\n<li class=\"\">감면·중과 조건: 공식 근거와 전문가 확인 여부</li>\n<li class=\"\">계산 기준일: 세법과 조례가 언제 기준인지</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-아파트-매수-시-발생하는-주요-거래비용은-무엇인가요\">Q. 아파트 매수 시 발생하는 주요 거래비용은 무엇인가요?<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#q-%EC%95%84%ED%8C%8C%ED%8A%B8-%EB%A7%A4%EC%88%98-%EC%8B%9C-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%A3%BC%EC%9A%94-%EA%B1%B0%EB%9E%98%EB%B9%84%EC%9A%A9%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 아파트 매수 시 발생하는 주요 거래비용은 무엇인가요?에 대한 직접 링크\" title=\"Q. 아파트 매수 시 발생하는 주요 거래비용은 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>매매가격 외에 취득세(지방교육세 및 농어촌특별세 포함), 부동산 중개보수, 국민주택채권 매입/할인비용, 등기 수수료(법무사 보수) 등이 추가로 발생합니다. 주택 수와 취득가액에 따라 취득세율이 1%~12%까지 달라집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-아파트-매도-후-실제로-받는-돈순수령액은-어떻게-계산하나요\">Q. 아파트 매도 후 실제로 받는 돈(순수령액)은 어떻게 계산하나요?<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#q-%EC%95%84%ED%8C%8C%ED%8A%B8-%EB%A7%A4%EB%8F%84-%ED%9B%84-%EC%8B%A4%EC%A0%9C%EB%A1%9C-%EB%B0%9B%EB%8A%94-%EB%8F%88%EC%88%9C%EC%88%98%EB%A0%B9%EC%95%A1%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EA%B3%84%EC%82%B0%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 아파트 매도 후 실제로 받는 돈(순수령액)은 어떻게 계산하나요?에 대한 직접 링크\" title=\"Q. 아파트 매도 후 실제로 받는 돈(순수령액)은 어떻게 계산하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>매도가격에서 기존 취득가액과 필요경비를 차감한 양도차익에 장기보유특별공제와 기본공제(250만원)를 적용한 과세표준을 구하고, 해당 세율을 곱한 양도소득세(지방소득세 포함)와 중개보수를 제외하면 실제 순수령액이 됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-아파트-거래비용-계산기와-시세-예측의-차이점은-무엇인가요\">Q. 아파트 거래비용 계산기와 시세 예측의 차이점은 무엇인가요?<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#q-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B1%B0%EB%9E%98%EB%B9%84%EC%9A%A9-%EA%B3%84%EC%82%B0%EA%B8%B0%EC%99%80-%EC%8B%9C%EC%84%B8-%EC%98%88%EC%B8%A1%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 아파트 거래비용 계산기와 시세 예측의 차이점은 무엇인가요?에 대한 직접 링크\" title=\"Q. 아파트 거래비용 계산기와 시세 예측의 차이점은 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>시세 예측은 해당 아파트의 미래 가격 범위를 추정하는 지표이며, 거래비용 계산기는 해당 가격으로 실제 계약할 때 필요한 추가 현금(매수 총 필요자금) 또는 세후 입금액(매도 순수령액)을 파악하는 도구입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고할-공식-자료\">참고할 공식 자료<a href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator#%EC%B0%B8%EA%B3%A0%ED%95%A0-%EA%B3%B5%EC%8B%9D-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고할 공식 자료에 대한 직접 링크\" title=\"참고할 공식 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.nts.go.kr/nts/cm/cntnts/cntntsView.do?cntntsId=7666&amp;mi=2308\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 양도소득세 개요</a>: 양도소득세의 과세 구조와 기본 개념을 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://i.nts.go.kr/nts/cm/cntnts/cntntsView.do?cntntsId=7711&amp;mi=2312\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 양도소득세 세율 안내</a>: 과세표준별 기본세율과 세율 변동 자료를 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://www.law.go.kr/%EB%B2%95%EB%A0%B9/%EC%A7%80%EB%B0%A9%EC%84%B8%EB%B2%95\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국가법령정보센터 지방세법</a>: 취득세를 포함한 지방세 관련 현행 법령을 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://land.seoul.go.kr/land/broker/brokerageCommission.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">서울특별시 부동산 중개보수 요율표</a>: 주택·분양권 중개보수의 상한요율과 적용 기준을 확인할 수 있습니다.</li>\n</ul>\n<p>공식 자료의 세율과 요건은 개정될 수 있습니다. 따라서 계산기에서 표시하는 정책 기준일을 확인하고, 실제 계약·신고 단계에서는 관할 지방자치단체, 국세청, 중개사, 세무 전문가의 최신 안내를 다시 확인하는 것이 좋습니다.</p>\n<p>거래비용 계산은 가격 전망과 별도로 실제 현금흐름을 확인하기 위한 참고 과정입니다. 취득세·양도소득세·중개보수의 기준금액과 적용 조건을 나누어 확인하면, 같은 가격이라도 매수에 필요한 자금과 매도 후 순수령액이 왜 달라지는지 더 정확하게 비교할 수 있습니다.</p>\n<blockquote>\n<p>이 글과 계산 결과는 공개된 정책 기준과 입력 조건에 따른 참고용 정보입니다. 실제 세액·중개보수·신고금액·거래 가능 여부를 보장하지 않으며, 투자 권유나 매수·매도 추천이 아닙니다. 최종 계약과 신고 전에는 최신 공식 자료와 전문가 의견을 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-transaction-cost-calculator",
            "title": "아파트 거래비용 계산: 취득세·양도세·중개보수까지",
            "summary": "아파트 매수·매도 때 필요한 실제 자금을 취득세·양도소득세·중개보수로 나눠 계산하고, 거래비용 계산기 결과를 읽는 방법을 정리합니다.",
            "date_modified": "2026-08-07T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "금융·세금"
            ]
        },
        {
            "id": "https://alvin.ing/blog/sonpi-tax-calculator",
            "content_html": "\n<p>분양권 거래에서 “프리미엄 3,000만원”이라는 말만 보고 매수자 부담액을 판단하면 실제 준비해야 할 금액을 놓치기 쉽습니다. 손피 계약에서는 매도자가 손에 남길 프리미엄을 정하고, 매수자가 매도자의 양도소득세와 지방소득세를 대신 부담하기 때문입니다.</p>\n<p>이 글에서는 손피가 일반적인 프리미엄 거래와 어떻게 다른지 설명하고, 1년 미만·1년 이상 보유기간과 세금 재산입을 반영한 계산기를 함께 제공합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"손피-계산기부터-확인하기\">손피 계산기부터 확인하기<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%86%90%ED%94%BC-%EA%B3%84%EC%82%B0%EA%B8%B0%EB%B6%80%ED%84%B0-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"손피 계산기부터 확인하기에 대한 직접 링크\" title=\"손피 계산기부터 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>매도자 취득원가와 손에 남길 프리미엄, 인정 필요경비를 입력한 뒤 보유기간을 바꿔보세요. 기본값은 프리미엄 3,000만원·분양권 보유 1년 미만입니다.</p>\n<section class=\"calculator_ZhRa\" aria-label=\"손피 양도세 대납액 계산기\"><div class=\"calculatorHeader_FCW_\"><div><p class=\"kicker_MpXm\">SONPI TAX CALCULATOR</p><h2>손에 남길 프리미엄을 입력해보세요</h2><p>매도자의 양도세를 매수자가 대신 내는 경우, 대납세액을 다시 양도가액에 넣어 반복 계산합니다.</p></div><div class=\"statusBadge_PvE1\"><span aria-hidden=\"true\"></span>고정점 계산</div></div><div class=\"presetRow_DgEh\" aria-label=\"예시 불러오기\"><span>빠른 예시</span><button type=\"button\">프리미엄 3,000만원</button><button type=\"button\">국세청 12억 → 17억</button></div><div class=\"calculatorGrid_cHtQ\"><div class=\"formPanel_dW3L\"><div class=\"fieldGroup_N7XE\"><div class=\"fieldHeading_HUX7\"><label for=\"sonpi-acquisition-price\">매도자 취득원가</label><span>분양가·기납부금 등</span></div><div class=\"inputWithUnit_a6fb\"><input id=\"sonpi-acquisition-price\" type=\"number\" min=\"0\" step=\"0.1\" inputmode=\"decimal\" value=\"12\"><span>억원</span></div></div><div class=\"fieldGroup_N7XE\"><div class=\"fieldHeading_HUX7\"><label for=\"sonpi-premium\">손에 남길 프리미엄</label><span>세금 대납 전 기준</span></div><div class=\"inputWithUnit_a6fb\"><input id=\"sonpi-premium\" type=\"number\" min=\"0\" step=\"100\" inputmode=\"numeric\" value=\"3000\"><span>만원</span></div><p class=\"helperText_kQJT\">이 데모에서는 세금 대납 전 양도가액을 ‘취득원가 + 프리미엄’으로 단순화합니다.</p></div><div class=\"fieldGroup_N7XE\"><div class=\"fieldHeading_HUX7\"><label>분양권 보유기간</label><span>양도일 기준</span></div><div class=\"segmentedControl_c0CB\" role=\"group\" aria-label=\"분양권 보유기간\"><button type=\"button\" class=\"segmentActive_fMQt\"><strong>1년 미만</strong><small>양도소득세 70%</small></button><button type=\"button\" class=\"\"><strong>1년 이상</strong><small>양도소득세 60%</small></button></div></div><div class=\"fieldGroup_N7XE\"><div class=\"fieldHeading_HUX7\"><label for=\"sonpi-expenses\">인정 필요경비</label><span>계약서·증빙 확인</span></div><div class=\"inputWithUnit_a6fb\"><input id=\"sonpi-expenses\" type=\"number\" min=\"0\" step=\"10\" inputmode=\"numeric\" value=\"0\"><span>만원</span></div><p class=\"helperText_kQJT\">기본공제 250만원은 자동 반영합니다.</p></div><div class=\"fieldGroup_N7XE\"><div class=\"fieldHeading_HUX7\"><label for=\"sonpi-interim-interest\">매수자 부담 중도금 이자</label><span>계약상 확정 정산액</span></div><div class=\"inputWithUnit_a6fb\"><input id=\"sonpi-interim-interest\" type=\"number\" min=\"0\" step=\"10\" inputmode=\"numeric\" value=\"0\"><span>만원</span></div><p class=\"helperText_kQJT\">손피 세금에는 포함하지 않고, 매수자 필요자금에서 차감합니다.</p></div></div><div class=\"resultPanel_FcBj\" aria-live=\"polite\"><div class=\"resultEyebrow_oKdF\">매수자가 준비할 프리미엄 관련 순자금</div><div class=\"heroResult_zyfz\">1억 2,207만원</div><p class=\"resultCaption_r8TK\">프리미엄 <!-- -->3,000만원<!-- --> + 대납세액<!-- --> <!-- -->9,207만원<!-- --> + 중도금 이자<!-- --> <!-- -->0만원</p><div class=\"statGrid_ej5A\"><div class=\"statCard_pazX\"><span>결합 세율</span><strong>77%</strong><small>국세 <!-- -->70%<!-- --> + 지방소득세<!-- --> <!-- -->7%</small></div><div class=\"statCard_pazX\"><span>1차 계산</span><strong>2,118만원</strong><small>대납세액을 아직 재산입하지 않은 값</small></div><div class=\"statCard_pazX\"><span>반복 횟수</span><strong>64<!-- -->회</strong><small>1원 이내로 수렴</small></div></div><div class=\"breakdown_ZFaw\"><div class=\"breakdownHeading_fxyk\">계산 결과</div><div class=\"breakdownRow_tjgv\"><span>세금 대납 전 신고금액</span><strong>12억 3,000만원</strong></div><div class=\"breakdownRow_tjgv\"><span>양도소득세</span><strong>8,370만원</strong></div><div class=\"breakdownRow_tjgv\"><span>지방소득세</span><strong>837만원</strong></div><div class=\"breakdownRow_tjgv totalRow_L5YY\"><span>매수자 대납세액</span><strong>9,207만원</strong></div><div class=\"breakdownRow_tjgv\"><span>매수자 부담 중도금 이자</span><strong>0만원</strong></div><div class=\"breakdownRow_tjgv\"><span>매수자 프리미엄 관련 필요자금</span><strong>1억 2,207만원</strong></div><div class=\"breakdownRow_tjgv\"><span>대납세액 포함 신고금액</span><strong>13억 2,207만원</strong></div></div><details class=\"details_YaSn\"><summary>왜 이렇게 계산되나요?</summary><p>92,065,209원<!-- -->를 양도가액에 더한 뒤 다시 계산하고, 직전 결과와 1원 이내로 같아질 때까지 반복했습니다.</p></details></div></div><p class=\"disclaimer_DOzQ\">분양권의 실제 세율·필요경비·신고금액은 거래일, 자산 상태, 계약 내용과 법령 해석에 따라 달라질 수 있습니다. 이 데모는 손피의 고정점 구조를 이해하기 위한 참고 계산입니다.</p></section>\n<p>이 데모는 세금 대납 전 양도가액을 <code>매도자 취득원가 + 프리미엄</code>으로 단순화합니다. 실제 계약에서는 취득일·양도일·기납부금·옵션비·필요경비·자산 상태를 별도로 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산기에-입력하는-금액의-의미\">계산기에 입력하는 금액의 의미<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EA%B3%84%EC%82%B0%EA%B8%B0%EC%97%90-%EC%9E%85%EB%A0%A5%ED%95%98%EB%8A%94-%EA%B8%88%EC%95%A1%EC%9D%98-%EC%9D%98%EB%AF%B8\" class=\"hash-link\" aria-label=\"계산기에 입력하는 금액의 의미에 대한 직접 링크\" title=\"계산기에 입력하는 금액의 의미에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>손피 계산에서 가장 자주 섞이는 숫자는 분양가, 양도가액, 프리미엄입니다. 계산기는 다음처럼 역할을 나누어 사용합니다.</p>\n<table><thead><tr><th>입력값</th><th>계산에서의 의미</th><th>확인할 자료</th></tr></thead><tbody><tr><td>매도자 취득원가</td><td>매도자가 분양권을 취득하는 데 실제로 부담한 기준금액</td><td>분양계약서, 납부내역, 옵션·확장 계약서</td></tr><tr><td>손에 남길 프리미엄</td><td>세금을 납부한 뒤 매도자에게 남기려는 금액</td><td>매매계약서 특약, 협의한 프리미엄</td></tr><tr><td>인정 필요경비</td><td>양도차익에서 차감할 수 있다고 확인된 비용</td><td>영수증, 세금계산서, 계약 관련 증빙</td></tr><tr><td>보유기간</td><td>매도자의 취득일과 양도일 사이의 실제 경과기간</td><td>취득일·양도일 증빙</td></tr><tr><td>매수자 부담 중도금 이자</td><td>손피 세금과 별도로 매수자 필요자금에 더하는 금액</td><td>이자후불제 약정, 정산서, 계약 특약</td></tr></tbody></table>\n<p>이 글의 데모에서는 <code>세금 대납 전 양도가액 = 매도자 취득원가 + 손에 남길 프리미엄</code>으로 계산합니다. 따라서 취득원가를 바꾸면 세금 대납 전 신고금액은 달라지지만, 취득원가와 양도가액을 같은 폭으로 바꾼다는 단순화 가정에서는 프리미엄에 대한 양도차익 자체는 그대로입니다.</p>\n<p>취득원가에 포함되는 금액은 거래마다 달라질 수 있습니다. 기납부금·옵션비·확장비·중도금 이자·승계금액을 분양가와 같은 숫자로 묶으면 실제 양도차익과 신고금액이 어긋날 수 있으므로, 계약서와 납부내역을 나누어 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"손피란-무엇인가\">손피란 무엇인가<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%86%90%ED%94%BC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80\" class=\"hash-link\" aria-label=\"손피란 무엇인가에 대한 직접 링크\" title=\"손피란 무엇인가에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>손피는 ‘손에 남는 프리미엄’이라는 뜻입니다. 매도자가 세금을 납부한 뒤에도 약속한 프리미엄을 확보하도록 매수자가 매도자의 양도소득세와 지방소득세를 대신 부담하는 계약 조건을 가리킵니다.</p>\n<p>일반적인 분양권 거래라면 프리미엄과 세금을 따로 보면 되지만, 손피에서는 매수자가 대신 낸 세금이 매도자에게 귀속되는 양도가액의 일부로 다시 계산될 수 있습니다. 그래서 <code>프리미엄 × 세율</code> 한 번으로 끝나지 않습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1년-미만이면-왜-금액이-급격히-커질까\">1년 미만이면 왜 금액이 급격히 커질까<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#1%EB%85%84-%EB%AF%B8%EB%A7%8C%EC%9D%B4%EB%A9%B4-%EC%99%9C-%EA%B8%88%EC%95%A1%EC%9D%B4-%EA%B8%89%EA%B2%A9%ED%9E%88-%EC%BB%A4%EC%A7%88%EA%B9%8C\" class=\"hash-link\" aria-label=\"1년 미만이면 왜 금액이 급격히 커질까에 대한 직접 링크\" title=\"1년 미만이면 왜 금액이 급격히 커질까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>분양권은 보유기간에 따라 단기보유 세율을 적용합니다. **1년 미만 70%, 1년 이상 60%**라는 구분은 다주택 중과 가산세율이 아니라 분양권의 단기보유 세율입니다. 관련 세율 구조는 <a href=\"https://www.law.go.kr/lsLinkCommonInfo.do?lsJoLnkSeq=1026638199\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">소득세법 제104조 현행 조문</a>에서 확인할 수 있습니다.</p>\n<p>계산기에서는 양도소득세에 지방소득세를 함께 반영합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">분양권 1년 미만: 양도소득세 70% + 지방소득세(양도소득세의 10%) = 과세표준의 약 77%</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">분양권 1년 이상: 양도소득세 60% + 지방소득세(양도소득세의 10%) = 과세표준의 약 66%</span><br></div></code></pre></div></div>\n<p>이 비율은 프리미엄 전체에 바로 곱하는 값이 아닙니다. 인정 필요경비와 기본공제 250만원을 차감한 과세표준에 적용하며, 실제 계산에서는 원 단위 절사와 양도일 기준 보유기간 판정이 함께 들어갑니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1년-경계는-하루-단위로-확인해야-한다\">1년 경계는 하루 단위로 확인해야 한다<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#1%EB%85%84-%EA%B2%BD%EA%B3%84%EB%8A%94-%ED%95%98%EB%A3%A8-%EB%8B%A8%EC%9C%84%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%B4%EC%95%BC-%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"1년 경계는 하루 단위로 확인해야 한다에 대한 직접 링크\" title=\"1년 경계는 하루 단위로 확인해야 한다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>“1년 정도 보유했다”는 표현만으로는 세율을 정할 수 없습니다. 예를 들어 취득일이 2026년 1월 15일이라면 다음처럼 달라집니다.</p>\n<table><thead><tr><th>취득일</th><th>양도일</th><th style=\"text-align:right\">완전 경과기간</th><th>적용 구분</th></tr></thead><tbody><tr><td>2026-01-15</td><td>2027-01-14</td><td style=\"text-align:right\">12개월 미만</td><td>1년 미만, 70%</td></tr><tr><td>2026-01-15</td><td>2027-01-15</td><td style=\"text-align:right\">12개월</td><td>1년 이상, 60%</td></tr></tbody></table>\n<p>계약일과 잔금일, 명의변경일 중 어느 날짜가 세법상 취득일·양도일이 되는지는 거래 구조에 따라 확인이 필요합니다. 계산기에서 날짜를 임의로 1년 뒤로 입력하기보다 실제 증빙에 맞춰 입력해야 하는 이유입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"세금-위에-다시-세금이-붙는-구조\">세금 위에 다시 세금이 붙는 구조<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%84%B8%EA%B8%88-%EC%9C%84%EC%97%90-%EB%8B%A4%EC%8B%9C-%EC%84%B8%EA%B8%88%EC%9D%B4-%EB%B6%99%EB%8A%94-%EA%B5%AC%EC%A1%B0\" class=\"hash-link\" aria-label=\"세금 위에 다시 세금이 붙는 구조에 대한 직접 링크\" title=\"세금 위에 다시 세금이 붙는 구조에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>손피의 핵심은 매수자가 대신 낸 세액을 양도가액에 다시 넣는 것입니다. 국세청도 2024년 11월 손피거래 관련 보도자료에서 매수자가 부담한 양도소득세 전액을 양도가액에 합산해 재계산하는 해석을 안내했습니다. <a href=\"https://www.nts.go.kr/nts/na/ntt/selectNttInfo.do?bbsId=1028&amp;mi=2201&amp;nttSn=1338305\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 손피거래·다운거래 보도자료</a></p>\n<p>대납세액을 <code>T</code>라고 하면 단순화한 고정점 식은 다음과 같습니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">T = 적용세율 × (실질 양도가액 + T - 매도자 취득원가 - 인정 필요경비 - 기본공제)</span><br></div></code></pre></div></div>\n<p>우변에 다시 <code>T</code>가 들어 있으므로 계산기는 다음 순서로 반복합니다.</p>\n<ol>\n<li class=\"\">대납세액을 0원으로 두고 1차 세액을 계산합니다.</li>\n<li class=\"\">1차 세액을 양도가액에 더해 다시 세액을 계산합니다.</li>\n<li class=\"\">직전 결과와 1원 이내로 같아질 때까지 반복합니다.</li>\n</ol>\n<p>세율 구간을 오르내리거나 필수 입력이 없으면 숫자를 임의로 확정하지 않고 계산 보류로 두는 편이 안전합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"반복-계산은-이렇게-진행된다\">반복 계산은 이렇게 진행된다<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EB%B0%98%EB%B3%B5-%EA%B3%84%EC%82%B0%EC%9D%80-%EC%9D%B4%EB%A0%87%EA%B2%8C-%EC%A7%84%ED%96%89%EB%90%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"반복 계산은 이렇게 진행된다에 대한 직접 링크\" title=\"반복 계산은 이렇게 진행된다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>프리미엄 3,000만원, 필요경비 0원, 기본공제 250만원, 1년 미만을 단순화하면 결합세율은 약 77%입니다. 첫 계산 이후의 대납세액을 다시 양도가액에 넣으면 다음과 같은 흐름이 됩니다.</p>\n<table><thead><tr><th>반복 단계</th><th style=\"text-align:right\">직전 대납세액</th><th style=\"text-align:right\">다시 계산한 대납세액</th></tr></thead><tbody><tr><td>1차</td><td style=\"text-align:right\">0원</td><td style=\"text-align:right\">약 2,117만5,000원</td></tr><tr><td>2차</td><td style=\"text-align:right\">약 2,117만5,000원</td><td style=\"text-align:right\">약 3,748만원</td></tr><tr><td>3차</td><td style=\"text-align:right\">약 3,748만원</td><td style=\"text-align:right\">약 5,003만원</td></tr><tr><td>수렴</td><td style=\"text-align:right\">직전 세액을 계속 재산입</td><td style=\"text-align:right\">약 9,207만원</td></tr></tbody></table>\n<p>이 표의 1차·2차·3차 숫자는 설명을 위한 반올림값입니다. 실제 계산기는 원 단위 절사 후 직전 결과와 1원 이내로 같아지는 시점까지 반복합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프리미엄-3000만원이면-실제로-얼마인가\">프리미엄 3,000만원이면 실제로 얼마인가<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%ED%94%84%EB%A6%AC%EB%AF%B8%EC%97%84-3000%EB%A7%8C%EC%9B%90%EC%9D%B4%EB%A9%B4-%EC%8B%A4%EC%A0%9C%EB%A1%9C-%EC%96%BC%EB%A7%88%EC%9D%B8%EA%B0%80\" class=\"hash-link\" aria-label=\"프리미엄 3,000만원이면 실제로 얼마인가에 대한 직접 링크\" title=\"프리미엄 3,000만원이면 실제로 얼마인가에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다음 조건을 가정해보겠습니다.</p>\n<ul>\n<li class=\"\">손에 남길 프리미엄: 3,000만원</li>\n<li class=\"\">보유기간: 1년 미만</li>\n<li class=\"\">인정 필요경비: 0원</li>\n<li class=\"\">기본공제: 250만원</li>\n<li class=\"\">다른 감면·중과·신고 이슈는 제외</li>\n</ul>\n<p>1차 계산에서는 과세표준이 <code>3,000만원 - 250만원 = 2,750만원</code>입니다. 양도소득세와 지방소득세를 합치면 약 2,117만5,000원이고, 프리미엄과 합친 금액은 약 5,117만5,000원입니다.</p>\n<p>하지만 이 2,117만5,000원을 다시 양도가액에 넣으면 세액은 더 커집니다. 반복 계산이 수렴하면 대납세액은 약 9,207만원, 프리미엄과 합친 매수자 부담액은 약 1억 2,207만원 수준이 됩니다.</p>\n<p>1년 이상 보유로 바꾸면 결합세율이 약 66%가 되어 같은 단순화 조건의 대납세액은 약 5,338만원, 프리미엄과 합친 금액은 약 8,338만원 수준으로 내려갑니다. 따라서 1년 경계는 단순히 세율 10%포인트 차이가 아니라, 대납세액이 다시 과세표준에 들어가는 반복 구조 전체를 바꾸는 기준입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"분양권과-등기-후-주택은-같은-계산기로-보면-안-된다\">분양권과 등기 후 주택은 같은 계산기로 보면 안 된다<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EB%B6%84%EC%96%91%EA%B6%8C%EA%B3%BC-%EB%93%B1%EA%B8%B0-%ED%9B%84-%EC%A3%BC%ED%83%9D%EC%9D%80-%EA%B0%99%EC%9D%80-%EA%B3%84%EC%82%B0%EA%B8%B0%EB%A1%9C-%EB%B3%B4%EB%A9%B4-%EC%95%88-%EB%90%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"분양권과 등기 후 주택은 같은 계산기로 보면 안 된다에 대한 직접 링크\" title=\"분양권과 등기 후 주택은 같은 계산기로 보면 안 된다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이 글의 핵심 예시는 분양권입니다. 분양권은 보유기간에 따른 단기세율을 중심으로 계산하고, 일반적인 1세대 1주택 비과세나 장기보유특별공제를 그대로 적용하지 않습니다.</p>\n<p>반면 등기 후 주택은 보유기간 외에도 세대의 주택 수, 조정대상지역 여부, 다주택 중과 적용 여부, 거주기간과 비과세 요건이 함께 들어갑니다. 등기 후 주택을 손피로 거래한다면 분양권용 70%·60%만 대입해서는 안 되고, 별도의 양도소득세 조건을 다시 확인해야 합니다.</p>\n<p>아파트 인사이트의 거래비용 계산기에서도 자산 상태에 따라 필요한 입력과 계산 보류 조건을 다르게 둡니다. 이 글의 계산기는 분양권 손피 구조를 이해하기 위한 전용 참고값으로 보는 것이 안전합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"국세청의-12억-취득17억-양도-예시\">국세청의 12억 취득·17억 양도 예시<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EA%B5%AD%EC%84%B8%EC%B2%AD%EC%9D%98-12%EC%96%B5-%EC%B7%A8%EB%93%9D17%EC%96%B5-%EC%96%91%EB%8F%84-%EC%98%88%EC%8B%9C\" class=\"hash-link\" aria-label=\"국세청의 12억 취득·17억 양도 예시에 대한 직접 링크\" title=\"국세청의 12억 취득·17억 양도 예시에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>국세청이 공개한 예시는 분양권을 12억원에 취득해 17억원에 양도하는 상황입니다. 1년 이상 보유한 분양권의 일반 양도에서는 양도차익 5억원에서 기본공제를 뺀 금액에 60%와 지방소득세를 반영해 약 3억2,800만원의 세금이 계산됩니다.</p>\n<p>손피로 매수자가 이 세금을 부담하면 대납액이 양도가액에 들어가고, 다시 계산된 세금도 양도가액에 포함됩니다. 이 과정을 전액 부담 기준으로 반복하면 매수자가 부담할 양도소득세와 지방소득세가 약 9억6,600만원까지 커질 수 있습니다. 이 사례는 모든 손피 거래의 견적이 아니라, 대납세액 재산입이 누적될 때 금액이 얼마나 커질 수 있는지를 보여주는 공식 예시입니다.</p>\n<p>계산기 상단의 <code>국세청 12억 → 17억</code> 버튼을 누르면 이 구조를 직접 확인할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"손피-세액과-취득세중개보수는-별도다\">손피 세액과 취득세·중개보수는 별도다<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%86%90%ED%94%BC-%EC%84%B8%EC%95%A1%EA%B3%BC-%EC%B7%A8%EB%93%9D%EC%84%B8%EC%A4%91%EA%B0%9C%EB%B3%B4%EC%88%98%EB%8A%94-%EB%B3%84%EB%8F%84%EB%8B%A4\" class=\"hash-link\" aria-label=\"손피 세액과 취득세·중개보수는 별도다에 대한 직접 링크\" title=\"손피 세액과 취득세·중개보수는 별도다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>손피 대납세액은 매도자 양도소득세와 지방소득세를 매수자가 대신 부담하는 금액입니다. 취득세, 지방교육세, 농어촌특별세, 중개보수, 중도금 이자, 옵션·확장비까지 자동으로 포함한 총액이 아닙니다.</p>\n<p>아파트 인사이트의 거래비용 계산기에서는 분양가와 프리미엄을 기준으로 취득 관련 비용과 중개보수를 별도로 계산하고, 손피 대납세액을 별도 항목으로 더해 보여주는 흐름을 사용합니다. 대납세액을 취득세 과세표준에 다시 넣을지는 거래 형태와 해석에 따라 확인이 필요한 영역이므로, 계산기에서 확인되지 않은 비용을 임의로 중복하지 않습니다.</p>\n<p>중도금 이자는 일반적인 손피 계약에서 매수자가 함께 부담하는 경우가 많습니다. 그래서 이 글의 계산기에서는 중도금 이자를 손피 양도세 고정점에는 넣지 않고, 대납세액과 별도의 매수자 필요자금으로 더합니다. 이자후불제 약정, 이미 납부한 이자, 앞으로 승계할 이자, 매도자와의 정산액을 구분해서 입력해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문\">자주 묻는 질문<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8\" class=\"hash-link\" aria-label=\"자주 묻는 질문에 대한 직접 링크\" title=\"자주 묻는 질문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프리미엄-3000만원이면-5000만원만-준비하면-되나요\">프리미엄 3,000만원이면 5,000만원만 준비하면 되나요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%ED%94%84%EB%A6%AC%EB%AF%B8%EC%97%84-3000%EB%A7%8C%EC%9B%90%EC%9D%B4%EB%A9%B4-5000%EB%A7%8C%EC%9B%90%EB%A7%8C-%EC%A4%80%EB%B9%84%ED%95%98%EB%A9%B4-%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"프리미엄 3,000만원이면 5,000만원만 준비하면 되나요?에 대한 직접 링크\" title=\"프리미엄 3,000만원이면 5,000만원만 준비하면 되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>1차 세액만 더하면 약 5,118만원이지만, 손피의 대납세액 재산입까지 반영하면 단순화한 예시에서는 약 1억 2,207만원까지 올라갑니다. 5,000만원대는 최종 수렴값이 아니라 첫 번째 계산에 가깝습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"중도금-이자는-손피-세금에-합산하나요\">중도금 이자는 손피 세금에 합산하나요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%A4%91%EB%8F%84%EA%B8%88-%EC%9D%B4%EC%9E%90%EB%8A%94-%EC%86%90%ED%94%BC-%EC%84%B8%EA%B8%88%EC%97%90-%ED%95%A9%EC%82%B0%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"중도금 이자는 손피 세금에 합산하나요?에 대한 직접 링크\" title=\"중도금 이자는 손피 세금에 합산하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 매수자가 부담하는 중도금 이자는 매도자 양도세의 과세표준에 다시 넣는 손피 대납세액과 별개의 현금 지출입니다. 계산기에서는 대납세액을 먼저 고정점으로 계산한 뒤, 중도금 이자를 매수자 필요자금에 더합니다. 매도자가 이자를 부담하기로 한 경우에는 별도 정산액으로 차감하는 방식으로 계약 내용을 다시 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"70는-다주택자-중과세율인가요\">70%는 다주택자 중과세율인가요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#70%EB%8A%94-%EB%8B%A4%EC%A3%BC%ED%83%9D%EC%9E%90-%EC%A4%91%EA%B3%BC%EC%84%B8%EC%9C%A8%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"70%는 다주택자 중과세율인가요?에 대한 직접 링크\" title=\"70%는 다주택자 중과세율인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아닙니다. 이 글에서 설명하는 70%는 보유기간 1년 미만 분양권에 적용되는 단기보유 세율입니다. 다주택 중과는 주택의 자산 상태와 조정대상지역, 세대의 주택 수 등 별도 요건을 검토합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"마이너스-피도-같은-방식으로-계산하나요\">마이너스 피도 같은 방식으로 계산하나요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EB%A7%88%EC%9D%B4%EB%84%88%EC%8A%A4-%ED%94%BC%EB%8F%84-%EA%B0%99%EC%9D%80-%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C-%EA%B3%84%EC%82%B0%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"마이너스 피도 같은 방식으로 계산하나요?에 대한 직접 링크\" title=\"마이너스 피도 같은 방식으로 계산하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>마이너스 피는 손에 남길 양도차익이 발생하는 플러스 프리미엄과 구조가 다릅니다. 매수자가 매도자의 양도세를 대납하는 손피 고정점 계산의 대상인지 먼저 확인하고, 기준 분양가에서 차감되는 거래금액·미납금·이자·옵션비를 별도로 정리해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산기-결과가-보류되면-무엇을-확인해야-하나요\">계산기 결과가 보류되면 무엇을 확인해야 하나요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EA%B3%84%EC%82%B0%EA%B8%B0-%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B3%B4%EB%A5%98%EB%90%98%EB%A9%B4-%EB%AC%B4%EC%97%87%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%B4%EC%95%BC-%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"계산기 결과가 보류되면 무엇을 확인해야 하나요?에 대한 직접 링크\" title=\"계산기 결과가 보류되면 무엇을 확인해야 하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>매도자 취득원가, 취득일, 양도일, 전매제한 해제일, 실제 거래 가능 여부처럼 결과를 바꾸는 핵심 근거가 빠졌는지 확인합니다. 전매제한이 확인되지 않은 상태에서 세액만 계산하면 거래가 불가능한 계약을 숫자로 포장할 수 있으므로, 계산 보류가 정상적인 안내일 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계약-전에-따로-확인할-것\">계약 전에 따로 확인할 것<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EA%B3%84%EC%95%BD-%EC%A0%84%EC%97%90-%EB%94%B0%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%A0-%EA%B2%83\" class=\"hash-link\" aria-label=\"계약 전에 따로 확인할 것에 대한 직접 링크\" title=\"계약 전에 따로 확인할 것에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>손피 계산기 결과만으로 계약을 진행해서는 안 됩니다. 다음 항목은 계산기 입력과 별도로 확인해야 합니다.</p>\n<ul>\n<li class=\"\">기준 분양가와 프리미엄을 합한 세금 대납 전 실제 거래금액</li>\n<li class=\"\">매도자의 실제 취득원가와 증빙 가능한 필요경비</li>\n<li class=\"\">매도자 취득일과 거래 예정일</li>\n<li class=\"\">분양권인지 등기 후 주택인지에 대한 자산 상태</li>\n<li class=\"\">양도세를 매수자가 부담한다는 계약 특약</li>\n<li class=\"\">전매제한 해제일과 실제 거래 가능 여부</li>\n<li class=\"\">대납세액을 포함한 계약서·실거래 신고금액</li>\n</ul>\n<p>손피 자체를 단순히 불법이라고 단정할 수는 없지만, 대납 세액을 제외한 금액으로 실거래를 신고하면 다운계약 문제가 생길 수 있습니다. 실제 계약과 신고 전에는 최신 공식 자료와 세무 전문가의 확인이 필요합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-인사이트에서-실제-조건으로-확인하기\">아파트 인사이트에서 실제 조건으로 확인하기<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%9D%B8%EC%82%AC%EC%9D%B4%ED%8A%B8%EC%97%90%EC%84%9C-%EC%8B%A4%EC%A0%9C-%EC%A1%B0%EA%B1%B4%EC%9C%BC%EB%A1%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"아파트 인사이트에서 실제 조건으로 확인하기에 대한 직접 링크\" title=\"아파트 인사이트에서 실제 조건으로 확인하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 인사이트에서는 단지 시뮬레이션의 거래비용 계산기에서 분양권 거래 조건을 따로 입력할 수 있습니다. 현재 분양권 전매가 가능한 신축 아파트처럼 전매제한 해제일과 매수 예정일을 확인할 수 있는 경우에는 거래비용 계산기에서 <strong>분양권 계산기</strong>가 활성화되어 기준 분양가·프리미엄·손피 대납세액을 함께 검토할 수 있습니다.</p>\n<p>전매제한 해제일이 확인되지 않거나 매수 예정일이 제한기간 안이면 금액을 억지로 확정하지 않고 거래 가능 여부 확인이 필요한 상태로 표시합니다. 계산기에서 분양권 조건을 먼저 확인한 뒤, 이 글의 손피 계산기로 대납세액이 어떻게 누적되는지 이어서 비교하면 됩니다.</p>\n<p>이 글은 먼저 발행한 <a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator/\">아파트 매수·매도 거래비용 계산 가이드</a>의 분양권·손피 내용을 분리해 확장한 글입니다. 전체 거래비용의 구조는 이전 글에서, 손피의 고정점 계산은 이 글에서 확인할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공신력-있는-참고자료\">공신력 있는 참고자료<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EA%B3%B5%EC%8B%A0%EB%A0%A5-%EC%9E%88%EB%8A%94-%EC%B0%B8%EA%B3%A0%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"공신력 있는 참고자료에 대한 직접 링크\" title=\"공신력 있는 참고자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>세율과 신고 기준은 개정될 수 있으므로, 아래 원문을 기준으로 거래일에 적용되는 내용을 다시 확인해야 합니다.</p>\n<ul>\n<li class=\"\"><a href=\"https://www.law.go.kr/lsLinkCommonInfo.do?lsJoLnkSeq=1026638199\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국가법령정보센터 소득세법 제104조</a>: 분양권의 1년 미만 70%, 1년 이상 60% 세율 근거</li>\n<li class=\"\"><a href=\"https://www.nts.go.kr/nts/na/ntt/selectNttInfo.do?bbsId=1028&amp;mi=2201&amp;nttSn=1338305\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 손피거래·다운거래 관련 보도자료</a>: 대납세액을 양도가액에 포함하는 해석과 실제 거래금액 신고 안내</li>\n<li class=\"\"><a href=\"https://www.nts.go.kr/nts/cm/cntnts/cntntsView.do?cntntsId=7666&amp;mi=2308\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 양도소득세 개요</a>: 양도소득세의 과세 구조와 신고 기본 안내</li>\n<li class=\"\"><a href=\"https://www.nts.go.kr/upload/ti_tax/01/%EC%96%91%EB%8F%84%EC%86%8C%EB%93%9D%EC%84%B8%EC%9C%A8.pdf\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국세청 양도소득세율 안내 PDF</a>: 자산 종류·보유기간별 세율표</li>\n<li class=\"\"><a href=\"https://www.law.go.kr/%EB%B2%95%EB%A0%B9/%EC%A7%80%EB%B0%A9%EC%84%B8%EB%B2%95\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국가법령정보센터 지방세법</a>: 지방소득세와 취득 관련 지방세 법령 확인</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-분양권-손피손에-남는-프리미엄-거래란-무엇인가요\">Q. 분양권 손피(손에 남는 프리미엄) 거래란 무엇인가요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#q-%EB%B6%84%EC%96%91%EA%B6%8C-%EC%86%90%ED%94%BC%EC%86%90%EC%97%90-%EB%82%A8%EB%8A%94-%ED%94%84%EB%A6%AC%EB%AF%B8%EC%97%84-%EA%B1%B0%EB%9E%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 분양권 손피(손에 남는 프리미엄) 거래란 무엇인가요?에 대한 직접 링크\" title=\"Q. 분양권 손피(손에 남는 프리미엄) 거래란 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>손피 거래란 매도자가 양도소득세 등을 납부한 뒤 온전히 손에 쥐는 프리미엄 금액을 확정하고, 매도자가 부담해야 할 양도소득세와 지방소득세를 매수자가 대신 납부(대납)해 주는 분양권 거래 방식입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-분양권-단기-양도소득세율은-얼마인가요\">Q. 분양권 단기 양도소득세율은 얼마인가요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#q-%EB%B6%84%EC%96%91%EA%B6%8C-%EB%8B%A8%EA%B8%B0-%EC%96%91%EB%8F%84%EC%86%8C%EB%93%9D%EC%84%B8%EC%9C%A8%EC%9D%80-%EC%96%BC%EB%A7%88%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 분양권 단기 양도소득세율은 얼마인가요?에 대한 직접 링크\" title=\"Q. 분양권 단기 양도소득세율은 얼마인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>현행 세법상 분양권의 양도소득세율은 보유기간 1년 미만 시 70%(지방소득세 포함 약 77%), 1년 이상 보유 시 60%(지방소득세 포함 약 66%)의 중과 단일세율이 적용됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-손피-계산-시-매수자가-대납한-세금을-왜-다시-양도가액에-합산재산입하나요\">Q. 손피 계산 시 매수자가 대납한 세금을 왜 다시 양도가액에 합산(재산입)하나요?<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#q-%EC%86%90%ED%94%BC-%EA%B3%84%EC%82%B0-%EC%8B%9C-%EB%A7%A4%EC%88%98%EC%9E%90%EA%B0%80-%EB%8C%80%EB%82%A9%ED%95%9C-%EC%84%B8%EA%B8%88%EC%9D%84-%EC%99%9C-%EB%8B%A4%EC%8B%9C-%EC%96%91%EB%8F%84%EA%B0%80%EC%95%A1%EC%97%90-%ED%95%A9%EC%82%B0%EC%9E%AC%EC%82%B0%EC%9E%85%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 손피 계산 시 매수자가 대납한 세금을 왜 다시 양도가액에 합산(재산입)하나요?에 대한 직접 링크\" title=\"Q. 손피 계산 시 매수자가 대납한 세금을 왜 다시 양도가액에 합산(재산입)하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>세법상 매수자가 매도자의 양도소득세를 대신 부담하기로 약정한 경우, 대신 낸 1차 세금 또한 매도자의 실질적인 양도가액(경제적 이익)으로 보아 양도차익에 재산입되어 2차 세금이 계산되기 때문입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"함께-읽을-글\">함께 읽을 글<a href=\"https://alvin.ing/blog/sonpi-tax-calculator#%ED%95%A8%EA%BB%98-%EC%9D%BD%EC%9D%84-%EA%B8%80\" class=\"hash-link\" aria-label=\"함께 읽을 글에 대한 직접 링크\" title=\"함께 읽을 글에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-transaction-cost-calculator/\">아파트 매수·매도 거래비용 계산 가이드</a></li>\n</ul>\n<blockquote>\n<p>이 글과 계산 결과는 공개된 정책 기준과 입력 조건에 따른 참고용 정보입니다. 실제 세액·신고금액·거래 가능 여부를 보장하지 않으며, 투자 권유나 매수·매도 추천이 아닙니다. 최종 계약과 신고 전에는 최신 공식 자료와 전문가 의견을 확인하세요.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/sonpi-tax-calculator",
            "title": "분양권 손피 계산기: 프리미엄 3,000만원이면 실제 부담액은?",
            "summary": "분양권 손피 거래의 실제 매수자 부담액을 1년 미만 70%·1년 이상 60% 세율, 대납세액 재산입, 중도금 이자까지 반영해 계산하는 방법을 정리합니다.",
            "date_modified": "2026-08-07T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "금융·세금"
            ]
        },
        {
            "id": "https://alvin.ing/blog/83-real-estate-tax-reform-calculator",
            "content_html": "\n<p>2026년 8월 3일 발표된 부동산 세제개편안은 같은 아파트를 보유하더라도 <strong>실거주인지, 여러 채를 보유하는지, 공시가격이 어느 구간인지</strong>에 따라 결과가 달라지도록 설계되어 있습니다.</p>\n<p>그래서 이번 글은 정책 요약만 하지 않습니다. 공시가격과 보유 조건을 직접 입력해 현행 세법, 2027년 중간 단계, 2028년 본격 시행안을 비교해볼 수 있는 계산기를 함께 준비했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"먼저-계산해보기\">먼저 계산해보기<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EB%A8%BC%EC%A0%80-%EA%B3%84%EC%82%B0%ED%95%B4%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"먼저 계산해보기에 대한 직접 링크\" title=\"먼저 계산해보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아래 계산기는 시세나 호가가 아니라 세금 계산의 출발점인 <strong>공시가격</strong>을 입력받습니다. 결과는 정책안의 구조를 이해하기 위한 연간 추정치이며, 실제 고지서의 확정 세액을 대신하지 않습니다.</p>\n<section class=\"calculator_kGk6\" aria-label=\"8.3 부동산 세제개편안 보유세 계산기\"><div class=\"calculatorHeader_HcKH\"><div><p class=\"kicker_jiAu\">PUBLIC POLICY CALCULATOR</p><h2>내 조건으로 보유세 차이를 비교해보세요</h2><p>공시가격과 보유 조건을 입력하면 2026년 현행 기준과 8.3 정부안 기준의 연간 보유세를 같은 조건에서 비교합니다.</p></div><div class=\"statusBadge_S3E3\"><span aria-hidden=\"true\"></span>8.3 정부안</div></div><div class=\"calculatorGrid_OFr2\"><div class=\"formPanel_Yc1v\"><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label>계산 기준</label><span>현재안과 단계별 정부안을 비교</span></div><div class=\"segmentedControl_THLK\" role=\"group\" aria-label=\"계산 기준\"><button type=\"button\" class=\"\"><strong>현행 세법</strong><small>2026년 기준</small></button><button type=\"button\" class=\"\"><strong>2027년 정부안</strong><small>중간 단계</small></button><button type=\"button\" class=\"segmentActive_mBla\"><strong>2028년 정부안</strong><small>본격 시행안</small></button></div></div><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label for=\"target-assessed-price\">대상 아파트 공시가격</label><span>시세가 아닌 공시가격 기준</span></div><div class=\"inputWithUnit_FKEa\"><input id=\"target-assessed-price\" type=\"number\" min=\"0\" step=\"0.1\" inputmode=\"decimal\" value=\"20\"><span>억원</span></div><p class=\"helperText_MqXT\">국토부 실거래가나 호가가 아니라, 세금 계산에 쓰이는 공시가격을 입력하세요.</p></div><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label>보유 주택 수</label><span>대상 아파트를 포함해 입력</span></div><div class=\"choiceGrid_QYc8\" role=\"group\" aria-label=\"보유 주택 수\"><button type=\"button\" class=\"choiceActive_dzJ1\"><strong>1주택</strong><small>대상 아파트 1채</small></button><button type=\"button\" class=\"\"><strong>2주택</strong><small>대상 포함 2채</small></button><button type=\"button\" class=\"\"><strong>3채 이상</strong><small>입력한 주택 합산</small></button></div></div><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label>명의 형태</label><span>부부 공동명의 세액 최적 판정</span></div><div class=\"segmentedControl_THLK\" role=\"group\" aria-label=\"명의 형태\"><button type=\"button\" class=\"segmentActive_mBla\"><strong>단독 명의</strong><small>1주택 기본</small></button><button type=\"button\" class=\"\"><strong>부부 공동명의</strong><small>지분 50:50</small></button></div><p class=\"helperText_MqXT\">부부 공동명의는 인별 9억 공제(총 18억)와 1주택 특례 중 세액이 작은 최적안을 자동 산출합니다.</p></div><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label for=\"resident-house\">실거주 주택</label><span>거주기간 공제와 주택 비중에 반영</span></div><select id=\"resident-house\" class=\"select_GWro\"><option value=\"target\" selected=\"\">대상 아파트에 거주</option><option value=\"none\">보유 주택에 거주하지 않음</option></select></div><div class=\"twoColumnFields_rVjj\"><div class=\"fieldGroup_hVqT\"><label for=\"age\">만 나이</label><div class=\"inputWithUnit_FKEa\"><input id=\"age\" type=\"number\" min=\"0\" max=\"120\" value=\"\"><span>세</span></div></div><div class=\"fieldGroup_hVqT\"><label for=\"holding-years\">보유기간</label><div class=\"inputWithUnit_FKEa\"><input id=\"holding-years\" type=\"number\" min=\"0\" step=\"1\" value=\"\"><span>년</span></div></div><div class=\"fieldGroup_hVqT\"><label for=\"residence-years\">거주기간</label><div class=\"inputWithUnit_FKEa\"><input id=\"residence-years\" type=\"number\" min=\"0\" step=\"1\" value=\"\"><span>년</span></div></div></div><div class=\"optionalFields_B03F\"><label class=\"checkRow_hHWf\"><input type=\"checkbox\" checked=\"\"><span><strong>도시지역분 포함</strong><small>기본값은 포함입니다.</small></span></label><div class=\"fieldGroup_hVqT\"><div class=\"fieldHeading_vs2S\"><label for=\"previous-tax\">전년도 보유세</label><span>세부담 상한을 적용할 때만 입력</span></div><div class=\"inputWithUnit_FKEa\"><input id=\"previous-tax\" type=\"number\" min=\"0\" step=\"1\" inputmode=\"numeric\" placeholder=\"선택 입력\" value=\"\"><span>만원</span></div></div></div></div><div class=\"resultPanel_T5Vs\"><div class=\"resultTopline_mD1f\"><div><p class=\"kicker_jiAu\">ESTIMATE RESULT</p><p class=\"resultLabel_GTNF\">2028년 정부안 본격 시행</p></div><span class=\"resultDate_O9tn\">연간 추정</span></div><div class=\"totalResult_m2NQ\"><span>예상 연간 보유세</span><strong>672만원</strong><small>재산세·종합부동산세·부가세 포함 추정치</small></div><div class=\"compareBox_SC1s\"><div><span>현행 세법 기준</span><strong>710만원</strong></div><div class=\"deltaDown_a8hd\"><span>선택 기준과의 차이</span><strong>−37만원</strong></div></div><div class=\"breakdown_BSAG\"><div class=\"breakdownHeader_CMT0\"><strong>세목별 구성</strong><span>20억원<!-- --> 합산</span></div><div class=\"breakdownRow_SXfo\"><span>재산세</span><strong>297만원</strong></div><div class=\"breakdownRow_SXfo\"><span>도시지역분</span><strong>126만원</strong></div><div class=\"breakdownRow_SXfo\"><span>지방교육세</span><strong>59만원</strong></div><div class=\"breakdownRow_SXfo\"><span>종합부동산세</span><strong>158만원</strong></div><div class=\"breakdownRow_SXfo\"><span>농어촌특별세</span><strong>32만원</strong></div></div><div class=\"formulaBox_CoHS\"><div class=\"formulaHeader_h6n0\"><strong>이번 결과가 만들어진 과정</strong><span>공개 정책 기준</span></div><ol><li><span>01</span><p>합산 공시가격 <!-- -->20억원<!-- -->에서 기본공제 <!-- -->14억원<!-- -->를 뺍니다.</p></li><li><span>02</span><p>남은 금액에 공정시장가액비율 <!-- -->70%<!-- -->을 적용해 과세표준 <!-- -->4.2억원<!-- -->을 구합니다.</p></li><li><span>03</span><p>과세표준에 누진 세율을 적용하고 재산세 공제·세액공제를 반영합니다.</p></li><li><span>04</span><p>전년도 세액을 입력했다면 세부담 상한을 적용합니다.</p></li></ol></div></div></div><div class=\"disclaimer_XYGA\"><strong>계산 결과를 읽는 법</strong><p>이 계산기는 공개된 정부안과 일반적인 세목 구조를 바탕으로 한 콘텐츠용 추정치입니다. 공동명의, 특례주택, 지방세 감면, 실제 공시가격 확정값과 고지 방식에 따라 실제 세액은 달라질 수 있습니다. 정부안은 국회 심의와 하위법령 과정에서 바뀔 수 있으므로 계약·신고 전에는 원문과 세무 전문가의 확인이 필요합니다.</p></div></section>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"83-개편안에서-가장-중요한-변화는-누구에게-적용되는가입니다\">8.3 개편안에서 가장 중요한 변화는 ‘누구에게 적용되는가’입니다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#83-%EA%B0%9C%ED%8E%B8%EC%95%88%EC%97%90%EC%84%9C-%EA%B0%80%EC%9E%A5-%EC%A4%91%EC%9A%94%ED%95%9C-%EB%B3%80%ED%99%94%EB%8A%94-%EB%88%84%EA%B5%AC%EC%97%90%EA%B2%8C-%EC%A0%81%EC%9A%A9%EB%90%98%EB%8A%94%EA%B0%80%EC%9E%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"8.3 개편안에서 가장 중요한 변화는 ‘누구에게 적용되는가’입니다에 대한 직접 링크\" title=\"8.3 개편안에서 가장 중요한 변화는 ‘누구에게 적용되는가’입니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이번 개편안을 단순히 “세금이 오른다” 또는 “세금이 내려간다”로 요약하면 실제 조건을 놓치게 됩니다. 정부의 공식 FAQ는 크게 네 가지 대상을 나눠 설명합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-거주하는-1주택은-최대한-보호\">1. 거주하는 1주택은 최대한 보호<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#1-%EA%B1%B0%EC%A3%BC%ED%95%98%EB%8A%94-1%EC%A3%BC%ED%83%9D%EC%9D%80-%EC%B5%9C%EB%8C%80%ED%95%9C-%EB%B3%B4%ED%98%B8\" class=\"hash-link\" aria-label=\"1. 거주하는 1주택은 최대한 보호에 대한 직접 링크\" title=\"1. 거주하는 1주택은 최대한 보호에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>거주용 1주택은 공시가격 14억 원까지 종합부동산세 과세 대상에서 제외하는 방향입니다. 공식 문답에서는 시가 약 20억 원 수준을 공시가격 14억 원 수준으로 환산해 설명하고 있습니다.</p>\n<p>다만 “1주택이면 언제나 같은 혜택”이라는 뜻은 아닙니다. 일정 금액을 넘는 고가 주택은 별도의 세액공제 한도와 주택가액 기준을 적용하고, 실제 거주기간과 고령 여부 같은 조건도 결과에 영향을 줍니다.</p>\n<p>계산기에서 만 나이·보유기간·거주기간을 따로 입력하게 한 이유가 여기에 있습니다. 같은 공시가격이라도 어떤 조건을 입력하느냐에 따라 적용되는 공제가 달라질 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-비거주-1주택은-거주용-1주택과-분리\">2. 비거주 1주택은 거주용 1주택과 분리<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#2-%EB%B9%84%EA%B1%B0%EC%A3%BC-1%EC%A3%BC%ED%83%9D%EC%9D%80-%EA%B1%B0%EC%A3%BC%EC%9A%A9-1%EC%A3%BC%ED%83%9D%EA%B3%BC-%EB%B6%84%EB%A6%AC\" class=\"hash-link\" aria-label=\"2. 비거주 1주택은 거주용 1주택과 분리에 대한 직접 링크\" title=\"2. 비거주 1주택은 거주용 1주택과 분리에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>보유하고 있지만 거주하지 않는 주택은 거주용 1주택과 동일한 방식으로 볼 수 없습니다. 정부안은 비거주 1주택에 대해 기본공제를 9억 원으로 두는 방향을 제시하고 있습니다.</p>\n<p>이 차이는 계산의 첫 단계에서 생깁니다. 세율을 적용하기 전, 공시가격에서 빼는 기본공제가 달라지기 때문입니다. 아래의 간단한 식을 보면 왜 공시가격이 과세표준으로 바로 이어지지 않는지 알 수 있습니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">과세표준</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= (주택별 공시가격 합계 - 조건별 기본공제) × 공정시장가액비율</span><br></div></code></pre></div></div>\n<p>계산기 결과의 “이번 결과가 만들어진 과정”에서 이 값들을 단계별로 확인할 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-다주택은-주택-수와-거주-주택의-비중을-함께-봄\">3. 다주택은 주택 수와 거주 주택의 비중을 함께 봄<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#3-%EB%8B%A4%EC%A3%BC%ED%83%9D%EC%9D%80-%EC%A3%BC%ED%83%9D-%EC%88%98%EC%99%80-%EA%B1%B0%EC%A3%BC-%EC%A3%BC%ED%83%9D%EC%9D%98-%EB%B9%84%EC%A4%91%EC%9D%84-%ED%95%A8%EA%BB%98-%EB%B4%84\" class=\"hash-link\" aria-label=\"3. 다주택은 주택 수와 거주 주택의 비중을 함께 봄에 대한 직접 링크\" title=\"3. 다주택은 주택 수와 거주 주택의 비중을 함께 봄에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>다주택자 계산에서는 단순히 공시가격을 모두 더하는 것만으로 충분하지 않습니다. 정부안은 다주택의 기본공제를 4억 원에 거주 주택의 공시가격 비중을 반영하는 방식으로 설계하고 있습니다.</p>\n<p>예를 들어 여러 주택 중 한 채에 거주한다면, 그 주택이 전체 공시가격에서 차지하는 비중이 계산에 들어갑니다. 그래서 계산기에서 “실거주 주택”을 대상 아파트 또는 다른 주택 중 하나로 선택하도록 했습니다.</p>\n<p>또 2028년 본격 시행 기준에서는 3채 이상 보유하거나 조정대상지역 주택이 포함되는지에 따라 공정시장가액비율이 달라질 수 있습니다. 이 조건을 모르면 같은 주택 수와 같은 합산 가격을 입력해도 결과를 잘못 읽을 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-바로-한-번에-바뀌지-않고-단계적으로-적용\">4. 바로 한 번에 바뀌지 않고 단계적으로 적용<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#4-%EB%B0%94%EB%A1%9C-%ED%95%9C-%EB%B2%88%EC%97%90-%EB%B0%94%EB%80%8C%EC%A7%80-%EC%95%8A%EA%B3%A0-%EB%8B%A8%EA%B3%84%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%A0%81%EC%9A%A9\" class=\"hash-link\" aria-label=\"4. 바로 한 번에 바뀌지 않고 단계적으로 적용에 대한 직접 링크\" title=\"4. 바로 한 번에 바뀌지 않고 단계적으로 적용에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>정부안은 시장과 납세자의 적응을 고려해 종합부동산세를 2년에 걸쳐 단계적으로 개편하는 방향입니다. 계산기에서는 다음 세 시점을 분리했습니다.</p>\n<ul>\n<li class=\"\"><strong>2026년 현행 세법 기준</strong>: 현재 적용 중인 기준과 비교하는 기준선</li>\n<li class=\"\"><strong>2027년 정부안 중간 단계</strong>: 개편이 시작되는 중간 단계</li>\n<li class=\"\"><strong>2028년 정부안 본격 시행</strong>: 정부안이 제시한 본격 시행 단계</li>\n</ul>\n<p>따라서 2028년 결과만 보고 “내년부터 바로 이 금액을 낸다”고 해석하면 안 됩니다. 개정 법률안은 입법예고와 국회 심의, 하위법령 확정 과정을 거치며 내용이 바뀔 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산식은-왜-여러-단계로-나뉠까\">계산식은 왜 여러 단계로 나뉠까<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EA%B3%84%EC%82%B0%EC%8B%9D%EC%9D%80-%EC%99%9C-%EC%97%AC%EB%9F%AC-%EB%8B%A8%EA%B3%84%EB%A1%9C-%EB%82%98%EB%89%A0%EA%B9%8C\" class=\"hash-link\" aria-label=\"계산식은 왜 여러 단계로 나뉠까에 대한 직접 링크\" title=\"계산식은 왜 여러 단계로 나뉠까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>보유세는 하나의 세율을 공시가격에 곱하는 계산이 아닙니다. 이 계산기는 앱의 보유세 추정 흐름과 같은 순서로 다음 요소를 누적합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-공시가격을-합산\">1. 공시가격을 합산<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#1-%EA%B3%B5%EC%8B%9C%EA%B0%80%EA%B2%A9%EC%9D%84-%ED%95%A9%EC%82%B0\" class=\"hash-link\" aria-label=\"1. 공시가격을 합산에 대한 직접 링크\" title=\"1. 공시가격을 합산에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>대상 아파트와 다른 주택의 공시가격을 합산합니다. 세금 계산에서 사용하는 가격은 실거래가·호가와 다를 수 있으므로, 화면에 표시된 기준연도와 공시가격을 확인해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-조건에-맞는-기본공제-적용\">2. 조건에 맞는 기본공제 적용<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#2-%EC%A1%B0%EA%B1%B4%EC%97%90-%EB%A7%9E%EB%8A%94-%EA%B8%B0%EB%B3%B8%EA%B3%B5%EC%A0%9C-%EC%A0%81%EC%9A%A9\" class=\"hash-link\" aria-label=\"2. 조건에 맞는 기본공제 적용에 대한 직접 링크\" title=\"2. 조건에 맞는 기본공제 적용에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>1주택인지, 거주 중인지, 여러 채를 보유하는지에 따라 기본공제가 달라집니다. 이 단계에서 과세 대상 여부가 갈립니다. 합산 공시가격이 과세 기준에 미치지 않으면 종합부동산세 과세표준은 0원이 될 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-공정시장가액비율로-과세표준-계산\">3. 공정시장가액비율로 과세표준 계산<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#3-%EA%B3%B5%EC%A0%95%EC%8B%9C%EC%9E%A5%EA%B0%80%EC%95%A1%EB%B9%84%EC%9C%A8%EB%A1%9C-%EA%B3%BC%EC%84%B8%ED%91%9C%EC%A4%80-%EA%B3%84%EC%82%B0\" class=\"hash-link\" aria-label=\"3. 공정시장가액비율로 과세표준 계산에 대한 직접 링크\" title=\"3. 공정시장가액비율로 과세표준 계산에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>기본공제를 뺀 금액에 공정시장가액비율을 적용합니다. 이 값이 실제 세율을 곱하는 과세표준입니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">과세표준 = max(0, 공시가격 합계 - 기본공제) × 공정시장가액비율</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-누진세율과-재산세-공제-적용\">4. 누진세율과 재산세 공제 적용<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#4-%EB%88%84%EC%A7%84%EC%84%B8%EC%9C%A8%EA%B3%BC-%EC%9E%AC%EC%82%B0%EC%84%B8-%EA%B3%B5%EC%A0%9C-%EC%A0%81%EC%9A%A9\" class=\"hash-link\" aria-label=\"4. 누진세율과 재산세 공제 적용에 대한 직접 링크\" title=\"4. 누진세율과 재산세 공제 적용에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>과세표준이 계산되면 구간별 누진세율을 적용합니다. 이후 종합부동산세 계산에서 이미 반영된 재산세 부분을 조정하고, 대상이 되는 경우 1주택 세액공제를 반영합니다.</p>\n<p>그래서 계산기에는 종합부동산세만 표시하지 않고 재산세·도시지역분·지방교육세·농어촌특별세를 나눠 보여줍니다. 총액만 보면 정책안 때문에 바뀐 부분과 원래 함께 내는 세목을 구분하기 어렵기 때문입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-전년도-세액이-있으면-세부담-상한-확인\">5. 전년도 세액이 있으면 세부담 상한 확인<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#5-%EC%A0%84%EB%85%84%EB%8F%84-%EC%84%B8%EC%95%A1%EC%9D%B4-%EC%9E%88%EC%9C%BC%EB%A9%B4-%EC%84%B8%EB%B6%80%EB%8B%B4-%EC%83%81%ED%95%9C-%ED%99%95%EC%9D%B8\" class=\"hash-link\" aria-label=\"5. 전년도 세액이 있으면 세부담 상한 확인에 대한 직접 링크\" title=\"5. 전년도 세액이 있으면 세부담 상한 확인에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전년도 보유세를 입력하면 계산기에 세부담 상한을 반영할 수 있습니다. 전년도 세액을 입력하지 않으면 이 단계는 적용하지 않습니다.</p>\n<p>이 입력란을 필수로 만들지 않은 이유도 있습니다. 실제 고지된 전년도 세액을 모르는 상태에서 임의의 숫자를 넣으면 오히려 결과가 부정확해지기 때문입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산식을-한-줄씩-따라가-보기\">계산식을 한 줄씩 따라가 보기<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EA%B3%84%EC%82%B0%EC%8B%9D%EC%9D%84-%ED%95%9C-%EC%A4%84%EC%94%A9-%EB%94%B0%EB%9D%BC%EA%B0%80-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"계산식을 한 줄씩 따라가 보기에 대한 직접 링크\" title=\"계산식을 한 줄씩 따라가 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>계산 결과를 제대로 읽으려면 최종 금액보다 중간 숫자를 먼저 봐야 합니다. 계산기에서 입력값이 바뀔 때마다 실제로 달라지는 부분은 크게 <strong>합산 공시가격 → 기본공제 → 공정시장가액비율 → 누진세율 → 공제·세액공제 → 세부담 상한</strong>의 순서로 이어집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-과세표준을-먼저-만든다\">1. 과세표준을 먼저 만든다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#1-%EA%B3%BC%EC%84%B8%ED%91%9C%EC%A4%80%EC%9D%84-%EB%A8%BC%EC%A0%80-%EB%A7%8C%EB%93%A0%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 과세표준을 먼저 만든다에 대한 직접 링크\" title=\"1. 과세표준을 먼저 만든다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저 대상 아파트와 다른 주택의 공시가격을 합산합니다. 그다음 주택 수와 거주 여부에 맞는 기본공제를 빼고, 남은 금액에 해당 연도의 공정시장가액비율을 적용합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">총 공시가격 = 대상 아파트 공시가격 + 다른 주택 공시가격의 합</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">과세표준 = max(0, 총 공시가격 - 기본공제) × 공정시장가액비율</span><br></div></code></pre></div></div>\n<p><code>max(0, ...)</code>는 공제액을 뺀 결과가 음수가 되지 않도록 0으로 처리한다는 뜻입니다. 따라서 공시가격 합계가 과세 기준에 미치지 않으면 과세표준과 종합부동산세 산출세액이 0원이 될 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-누진세율은-전체-금액에-한-번에-곱하지-않는다\">2. 누진세율은 전체 금액에 한 번에 곱하지 않는다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#2-%EB%88%84%EC%A7%84%EC%84%B8%EC%9C%A8%EC%9D%80-%EC%A0%84%EC%B2%B4-%EA%B8%88%EC%95%A1%EC%97%90-%ED%95%9C-%EB%B2%88%EC%97%90-%EA%B3%B1%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 누진세율은 전체 금액에 한 번에 곱하지 않는다에 대한 직접 링크\" title=\"2. 누진세율은 전체 금액에 한 번에 곱하지 않는다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>과세표준이 4억 2천만 원이라고 해서 4억 2천만 원 전체에 하나의 세율을 곱하는 방식은 아닙니다. 각 구간에 들어가는 금액을 잘라서 구간별 세율을 적용한 뒤 더합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">누진 산출세액</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= 1구간 금액 × 1구간 세율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 2구간 금액 × 2구간 세율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 3구간 금액 × 3구간 세율 ...</span><br></div></code></pre></div></div>\n<p>예를 들어 <strong>2027년 정부안, 거주 1주택, 공시가격 20억 원</strong>을 가정하면 계산기 구조는 다음처럼 읽을 수 있습니다.</p>\n<table><thead><tr><th>단계</th><th style=\"text-align:right\">계산</th><th style=\"text-align:right\">결과</th></tr></thead><tbody><tr><td>총 공시가격</td><td style=\"text-align:right\">20억 원</td><td style=\"text-align:right\">20억 원</td></tr><tr><td>기본공제</td><td style=\"text-align:right\">14억 원</td><td style=\"text-align:right\">6억 원이 남음</td></tr><tr><td>공정시장가액비율</td><td style=\"text-align:right\">6억 원 × 70%</td><td style=\"text-align:right\">과세표준 4억 2천만 원</td></tr><tr><td>구간별 산출</td><td style=\"text-align:right\">3억 × 0.5% + 1억 2천만 원 × 0.7%</td><td style=\"text-align:right\">234만 원</td></tr></tbody></table>\n<p>여기서 234만 원은 <strong>재산세 공제·1주택 세액공제·세부담 상한을 반영하기 전의 종합부동산세 산출 단계 예시</strong>입니다. 실제 계산기의 최종 보유세는 재산세와 부가세목을 함께 계산하므로 이 숫자와 같지 않습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-재산세와-종합부동산세를-따로-계산한-뒤-합산한다\">3. 재산세와 종합부동산세를 따로 계산한 뒤 합산한다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#3-%EC%9E%AC%EC%82%B0%EC%84%B8%EC%99%80-%EC%A2%85%ED%95%A9%EB%B6%80%EB%8F%99%EC%82%B0%EC%84%B8%EB%A5%BC-%EB%94%B0%EB%A1%9C-%EA%B3%84%EC%82%B0%ED%95%9C-%EB%92%A4-%ED%95%A9%EC%82%B0%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 재산세와 종합부동산세를 따로 계산한 뒤 합산한다에 대한 직접 링크\" title=\"3. 재산세와 종합부동산세를 따로 계산한 뒤 합산한다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>계산기는 종합부동산세만 계산하지 않습니다. 주택별 재산세를 먼저 계산하고, 도시지역분과 지방교육세를 더한 다음, 종합부동산세에서 공제되는 재산세와 세액공제를 반영합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">재산세 과세표준 = 공시가격 × 재산세 공정시장가액비율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">도시지역분 = 재산세 과세표준 × 도시지역분 세율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">지방교육세 = 재산세 × 지방교육세율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">농어촌특별세 = 최종 종합부동산세 × 20%</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">연간 보유세</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= 재산세 + 도시지역분 + 지방교육세</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">+ 최종 종합부동산세 + 농어촌특별세</span><br></div></code></pre></div></div>\n<p>종합부동산세에서 빠지는 재산세 부분은 같은 세원을 두 번 과세하지 않기 위한 조정입니다. 그래서 <code>과세표준 × 누진세율</code>로 나온 금액이 그대로 최종 종합부동산세가 되지 않습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-1주택-세액공제는-산출세액에-적용한다\">4. 1주택 세액공제는 산출세액에 적용한다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#4-1%EC%A3%BC%ED%83%9D-%EC%84%B8%EC%95%A1%EA%B3%B5%EC%A0%9C%EB%8A%94-%EC%82%B0%EC%B6%9C%EC%84%B8%EC%95%A1%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 1주택 세액공제는 산출세액에 적용한다에 대한 직접 링크\" title=\"4. 1주택 세액공제는 산출세액에 적용한다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>1주택에 해당하는 경우에는 연령·보유기간·거주기간에 따라 세액공제율이 달라질 수 있습니다. 계산기에서는 해당 조건으로 계산한 공제액을 산출세액에서 빼고, 정부안 단계에서는 별도 공제 한도도 적용합니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">세액공제 후 종합부동산세</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">= max(0, 산출 종합부동산세 - 재산세 공제 - 1주택 세액공제)</span><br></div></code></pre></div></div>\n<p>나이·보유기간·거주기간을 입력하지 않으면 관련 공제가 충분히 반영되지 않을 수 있습니다. 반대로 조건을 임의로 높여 입력하면 실제 증빙 요건을 충족하지 않아 결과가 달라질 수 있으므로, 확인 가능한 값만 입력해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-전년도-세액이-있으면-세부담-상한을-마지막에-확인한다\">5. 전년도 세액이 있으면 세부담 상한을 마지막에 확인한다<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#5-%EC%A0%84%EB%85%84%EB%8F%84-%EC%84%B8%EC%95%A1%EC%9D%B4-%EC%9E%88%EC%9C%BC%EB%A9%B4-%EC%84%B8%EB%B6%80%EB%8B%B4-%EC%83%81%ED%95%9C%EC%9D%84-%EB%A7%88%EC%A7%80%EB%A7%89%EC%97%90-%ED%99%95%EC%9D%B8%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"5. 전년도 세액이 있으면 세부담 상한을 마지막에 확인한다에 대한 직접 링크\" title=\"5. 전년도 세액이 있으면 세부담 상한을 마지막에 확인한다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전년도 보유세를 입력한 경우에는 올해 계산액이 전년도보다 일정 비율 이상 커지지 않도록 상한을 확인합니다. 계산기의 구조를 단순화하면 다음과 같습니다.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">허용 보유세 = 전년도 보유세 × 해당 기준의 상한비율</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">상한 적용 후 세액 = min(상한 적용 전 보유세, 허용 보유세)</span><br></div></code></pre></div></div>\n<p>실제 계산에서는 재산세처럼 이미 고정된 세목을 먼저 제외하고 종합부동산세와 농어촌특별세 쪽을 조정합니다. 전년도 세액을 입력하지 않으면 이 단계는 건너뜁니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"입력-조건이-바뀌면-어느-식이-달라질까\">입력 조건이 바뀌면 어느 식이 달라질까<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EC%9E%85%EB%A0%A5-%EC%A1%B0%EA%B1%B4%EC%9D%B4-%EB%B0%94%EB%80%8C%EB%A9%B4-%EC%96%B4%EB%8A%90-%EC%8B%9D%EC%9D%B4-%EB%8B%AC%EB%9D%BC%EC%A7%88%EA%B9%8C\" class=\"hash-link\" aria-label=\"입력 조건이 바뀌면 어느 식이 달라질까에 대한 직접 링크\" title=\"입력 조건이 바뀌면 어느 식이 달라질까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>입력 조건</th><th>계산에서 달라지는 부분</th></tr></thead><tbody><tr><td>명의 형태 (단독 / 부부 공동명의)</td><td>인별 9억 공제(총 18억)와 1주택자 특례 신청(12억/14억+세액공제) 중 최적 세액 자동 선택</td></tr><tr><td>다른 주택 공시가격</td><td>총 공시가격, 주택 수, 기본공제와 누진 구간</td></tr><tr><td>실거주 주택 선택</td><td>거주 주택 비중에 따른 공제와 1주택 여부</td></tr><tr><td>만 나이</td><td>1주택 고령자 세액공제율</td></tr><tr><td>보유기간·거주기간</td><td>장기보유·장기거주 세액공제율</td></tr><tr><td>3채 이상·조정대상지역 주택</td><td>정부안의 공정시장가액비율과 세율 조건</td></tr><tr><td>전년도 보유세</td><td>세부담 상한 적용 여부와 상한 조정액</td></tr></tbody></table>\n<p>따라서 같은 아파트의 공시가격을 입력하더라도 다른 주택을 추가하거나, 실거주 주택을 바꾸거나, 전년도 세액을 입력하면 최종 금액이 달라질 수 있습니다. 계산기를 사용할 때는 총액만 캡처하기보다 <strong>공시가격 합계·공제액·과세표준·공정시장가액비율·공제액·상한 조정액</strong>을 함께 기록하는 편이 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과를-읽을-때-확인할-네-가지\">결과를 읽을 때 확인할 네 가지<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EA%B2%B0%EA%B3%BC%EB%A5%BC-%EC%9D%BD%EC%9D%84-%EB%95%8C-%ED%99%95%EC%9D%B8%ED%95%A0-%EB%84%A4-%EA%B0%80%EC%A7%80\" class=\"hash-link\" aria-label=\"결과를 읽을 때 확인할 네 가지에 대한 직접 링크\" title=\"결과를 읽을 때 확인할 네 가지에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\"><strong>공시가격 기준일</strong>: 내가 입력한 숫자가 어느 기준연도의 공시가격인지 확인합니다.</li>\n<li class=\"\"><strong>거주 주택 선택</strong>: 여러 주택을 보유한 경우 어느 집에 거주하는지에 따라 공제 구조가 달라집니다.</li>\n<li class=\"\"><strong>현행 기준과 정책안의 차이</strong>: 선택한 단계의 총액보다 현행 기준과의 차이를 먼저 봅니다.</li>\n<li class=\"\"><strong>정부안과 확정 세법 구분</strong>: 계산기의 2027·2028 결과는 정부안 시나리오이며, 확정 고지세액이 아닙니다.</li>\n</ol>\n<p>특히 계산기에서 <code>+</code>로 표시되는 차이는 정부안 기준 추정치가 현행 기준보다 높은 경우이고, <code>−</code>로 표시되는 차이는 낮은 경우입니다. 어느 쪽이든 결과만으로 매수·매도 결정을 내리는 것이 아니라, 공시가격·거주 여부·주택 수를 바꿔가며 민감도를 확인하는 용도로 사용하는 편이 안전합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-83-세제개편안에서-거주용-1주택-종부세-면제-기준은-얼마인가요\">Q. 8.3 세제개편안에서 거주용 1주택 종부세 면제 기준은 얼마인가요?<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#q-83-%EC%84%B8%EC%A0%9C%EA%B0%9C%ED%8E%B8%EC%95%88%EC%97%90%EC%84%9C-%EA%B1%B0%EC%A3%BC%EC%9A%A9-1%EC%A3%BC%ED%83%9D-%EC%A2%85%EB%B6%80%EC%84%B8-%EB%A9%B4%EC%A0%9C-%EA%B8%B0%EC%A4%80%EC%9D%80-%EC%96%BC%EB%A7%88%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 8.3 세제개편안에서 거주용 1주택 종부세 면제 기준은 얼마인가요?에 대한 직접 링크\" title=\"Q. 8.3 세제개편안에서 거주용 1주택 종부세 면제 기준은 얼마인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>정부안 기준으로 실제 거주하는 1세대 1주택자는 공시가격 14억원(시가 약 20억원 수준)까지 종합부동산세 과세 대상에서 제외하는 방향이 제시되었습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-비거주-1주택과-거주용-1주택의-기본공제는-어떻게-다른가요\">Q. 비거주 1주택과 거주용 1주택의 기본공제는 어떻게 다른가요?<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#q-%EB%B9%84%EA%B1%B0%EC%A3%BC-1%EC%A3%BC%ED%83%9D%EA%B3%BC-%EA%B1%B0%EC%A3%BC%EC%9A%A9-1%EC%A3%BC%ED%83%9D%EC%9D%98-%EA%B8%B0%EB%B3%B8%EA%B3%B5%EC%A0%9C%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8B%A4%EB%A5%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 비거주 1주택과 거주용 1주택의 기본공제는 어떻게 다른가요?에 대한 직접 링크\" title=\"Q. 비거주 1주택과 거주용 1주택의 기본공제는 어떻게 다른가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>보유하지만 실거주하지 않는 1주택은 기본공제 9억원이 적용되어 거주용 1주택(14억원)과 분리하여 과세됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-다주택자의-종합부동산세-개편은-언제부터-적용되나요\">Q. 다주택자의 종합부동산세 개편은 언제부터 적용되나요?<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#q-%EB%8B%A4%EC%A3%BC%ED%83%9D%EC%9E%90%EC%9D%98-%EC%A2%85%ED%95%A9%EB%B6%80%EB%8F%99%EC%82%B0%EC%84%B8-%EA%B0%9C%ED%8E%B8%EC%9D%80-%EC%96%B8%EC%A0%9C%EB%B6%80%ED%84%B0-%EC%A0%81%EC%9A%A9%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 다주택자의 종합부동산세 개편은 언제부터 적용되나요?에 대한 직접 링크\" title=\"Q. 다주택자의 종합부동산세 개편은 언제부터 적용되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>정부안은 2026년 현행 기준을 거쳐 2027년 중간 단계, 2028년 본격 시행으로 2년에 걸쳐 단계적으로 개편하는 일정을 두고 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공식-원문\">공식 원문<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EA%B3%B5%EC%8B%9D-%EC%9B%90%EB%AC%B8\" class=\"hash-link\" aria-label=\"공식 원문에 대한 직접 링크\" title=\"공식 원문에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.mofe.go.kr/2026/taxlaw.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">2026년 세제개편안 — 재정경제부</a></li>\n<li class=\"\"><a href=\"https://www.mofe.go.kr/nw/mosfnw/photoDetail.do?menuNo=4010400&amp;searchNttId1=MOSF_000000000078811\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">제59차 세제발전심의위원회 — 재정경제부, 2026.08.03.</a></li>\n<li class=\"\"><a href=\"https://www.mofe.go.kr/lw/lap/detailTbPrvntcView.do?menuNo=7050300&amp;searchBbsId1=MOSFBBS_000000000055&amp;searchNttId1=MOSF_000000000078823\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">「종합부동산세법」 일부개정법률(안) 입법예고 — 재정경제부, 2026.08.04.</a></li>\n<li class=\"\"><a href=\"https://www.law.go.kr/LSW/lsInfoP.do?ancYnChk=0&amp;chrClsCd=010202&amp;efYd=20260101&amp;lsiSeq=280417&amp;urlMode=lsInfoP\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">종합부동산세법 — 국가법령정보센터</a></li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"함께-읽기\">함께 읽기<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%ED%95%A8%EA%BB%98-%EC%9D%BD%EA%B8%B0\" class=\"hash-link\" aria-label=\"함께 읽기에 대한 직접 링크\" title=\"함께 읽기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">아파트 가격을 현재·과거·미래로 나눠 읽는 법</a>: 가격 기준일과 예상 범위를 분리하는 방법</li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-range-not-single-number\">미래 아파트 가격을 하나의 숫자로 단정하면 위험한 이유</a>: 조건별 범위를 읽는 방법</li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/mortgage-rate-apartment-price\">주택담보대출 금리와 아파트 가격은 어떻게 연결될까</a>: 금리와 월 상환 부담을 함께 보는 순서</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"계산-다음에-할-일\">계산 다음에 할 일<a href=\"https://alvin.ing/blog/83-real-estate-tax-reform-calculator#%EA%B3%84%EC%82%B0-%EB%8B%A4%EC%9D%8C%EC%97%90-%ED%95%A0-%EC%9D%BC\" class=\"hash-link\" aria-label=\"계산 다음에 할 일에 대한 직접 링크\" title=\"계산 다음에 할 일에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>블로그 계산기는 정책안의 구조와 내 조건의 차이를 빠르게 확인하는 용도입니다. 실제 관심 아파트의 공시가격, 최근 실거래 흐름, 이사 시점, 금리와 함께 비교하려면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트에서 관심 단지와 조건을 확인해볼 수 있습니다</a>.</p>\n<p>계산 결과는 의사결정 참고용 정보이며, 실제 신고·납부 전에는 최신 법령과 공식 안내를 다시 확인해야 합니다.</p>",
            "url": "https://alvin.ing/blog/83-real-estate-tax-reform-calculator",
            "title": "8.3 부동산 세제개편안, 보유세 계산기로 내 조건 비교하기",
            "summary": "2026년 8월 3일 발표된 부동산 세제개편 정부안을 현행 세법과 비교하고, 공시가격·주택 수·실거주 조건으로 연간 보유세를 직접 계산해봅니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "금융·세금"
            ]
        },
        {
            "id": "https://alvin.ing/blog/real-estate-apartment-statistics-reading-order",
            "content_html": "<p>부동산과 아파트 통계는 숫자를 많이 보는 것보다 <strong>같은 기준으로 비교하는 순서</strong>를 정하는 일이 먼저입니다. 최근 실거래가 한 건, 월간 평균, 과거 차트, 미래 예상 범위는 서로 다른 질문에 답하기 때문입니다. 이 글은 특정 지역의 매수·매도를 권하는 글이 아니라, 관심 단지의 자료를 처음 확인할 때 어떤 순서로 숫자와 조건을 맞춰야 하는지 정리한 입문 안내서입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"한눈에-보는-아파트-통계-읽기-순서\">한눈에 보는 아파트 통계 읽기 순서<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%ED%95%9C%EB%88%88%EC%97%90-%EB%B3%B4%EB%8A%94-%EC%95%84%ED%8C%8C%ED%8A%B8-%ED%86%B5%EA%B3%84-%EC%9D%BD%EA%B8%B0-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"한눈에 보는 아파트 통계 읽기 순서에 대한 직접 링크\" title=\"한눈에 보는 아파트 통계 읽기 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아래 순서를 메모의 기본 틀로 사용하면 새로운 거래나 시장 자료가 추가되어도 같은 기준으로 다시 비교할 수 있습니다.</p>\n<table><thead><tr><th>순서</th><th>확인할 질문</th><th>놓치기 쉬운 부분</th></tr></thead><tbody><tr><td>1</td><td>이 숫자는 무엇을 뜻하나?</td><td>실거래가·호가·평균·중앙값을 섞음</td></tr><tr><td>2</td><td>같은 단지와 평형을 비교했나?</td><td>전용면적·타입·층 조건이 달라짐</td></tr><tr><td>3</td><td>거래 표본이 충분한가?</td><td>한 건의 급매나 특수 거래가 평균을 바꿈</td></tr><tr><td>4</td><td>어느 기간과 지역을 봤나?</td><td>월간 변화와 장기 흐름을 혼동함</td></tr><tr><td>5</td><td>미래 결과의 기준일과 범위는?</td><td>예상가를 확정 가격처럼 받아들임</td></tr><tr><td>6</td><td>출처와 자료 시점은?</td><td>신고일·공개일·기준일이 달라짐</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-먼저-질문과-숫자의-이름을-확인합니다\">1. 먼저 질문과 숫자의 이름을 확인합니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#1-%EB%A8%BC%EC%A0%80-%EC%A7%88%EB%AC%B8%EA%B3%BC-%EC%88%AB%EC%9E%90%EC%9D%98-%EC%9D%B4%EB%A6%84%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 먼저 질문과 숫자의 이름을 확인합니다에 대한 직접 링크\" title=\"1. 먼저 질문과 숫자의 이름을 확인합니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>“지금 확인된 가격이 얼마인가요?”와 “1년 뒤 참고할 가격 범위는 어디인가요?”는 다른 질문입니다. 아파트 가격을 말할 때도 실거래가, 호가, 평균가, 중앙값은 서로 다른 숫자입니다. 실거래가는 계약이 신고된 가격이고, 호가는 매도자가 제시한 가격입니다. 같은 단지라도 표본과 집계 방식이 다르면 결과가 달라질 수 있으므로 차트의 숫자보다 먼저 지표의 정의와 질문을 확인해야 합니다.</p>\n<p>확인할 항목은 다음과 같습니다.</p>\n<ul>\n<li class=\"\">어떤 가격을 집계했는가</li>\n<li class=\"\">거래가 발생한 시점과 공개된 시점은 언제인가</li>\n<li class=\"\">전용면적, 타입, 층처럼 비교 조건이 같은가</li>\n<li class=\"\">거래가 충분하지 않은 기간은 어떻게 표시했는가</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-단지와-평형을-먼저-맞춥니다\">2. 단지와 평형을 먼저 맞춥니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#2-%EB%8B%A8%EC%A7%80%EC%99%80-%ED%8F%89%ED%98%95%EC%9D%84-%EB%A8%BC%EC%A0%80-%EB%A7%9E%EC%B6%A5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 단지와 평형을 먼저 맞춥니다에 대한 직접 링크\" title=\"2. 단지와 평형을 먼저 맞춥니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>같은 단지 안에서도 전용면적과 타입에 따라 거래 가격이 크게 달라질 수 있습니다. 59㎡와 84㎡를 평균으로 묶거나, 저층 거래와 고층 거래를 별도 확인하지 않으면 “단지 가격”이라는 말이 실제로 무엇을 가리키는지 불분명해집니다.</p>\n<p>관심 지역의 단지별 최근 거래와 대표 시세를 평형 단위로 확인하는 순서는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region\">지역별 아파트 실거래가 조회하는 법</a>에서 따로 정리했습니다.</p>\n<p>비교표를 만들 때는 최소한 다음 항목을 한 줄에 적어두는 편이 좋습니다.</p>\n<ul>\n<li class=\"\">단지명과 주소 범위</li>\n<li class=\"\">전용면적 또는 평형</li>\n<li class=\"\">거래 유형과 층 조건</li>\n<li class=\"\">거래일과 자료를 확인한 날짜</li>\n</ul>\n<p>현재 거래와 과거 이력, 미래 예상 범위를 함께 보려면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">아파트 가격을 현재·과거·미래로 나눠 읽는 법</a>처럼 각 숫자의 역할을 먼저 분리해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-최근-거래-한-건을-전체-시세로-확대하지-않습니다\">3. 최근 거래 한 건을 전체 시세로 확대하지 않습니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#3-%EC%B5%9C%EA%B7%BC-%EA%B1%B0%EB%9E%98-%ED%95%9C-%EA%B1%B4%EC%9D%84-%EC%A0%84%EC%B2%B4-%EC%8B%9C%EC%84%B8%EB%A1%9C-%ED%99%95%EB%8C%80%ED%95%98%EC%A7%80-%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 최근 거래 한 건을 전체 시세로 확대하지 않습니다에 대한 직접 링크\" title=\"3. 최근 거래 한 건을 전체 시세로 확대하지 않습니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 시장은 거래가 적은 기간에 한두 건만으로도 평균이 크게 움직일 수 있습니다. 최근 거래가 유용한 출발점이기는 하지만 급매, 고층, 내부 수리 상태, 직거래처럼 단지 전체를 대표하지 않을 수 있는 조건이 함께 들어 있을 수 있습니다.</p>\n<p>최근 거래를 볼 때는 거래 건수, 면적 분포, 층 분포, 거래 유형을 함께 확인합니다. 한 건의 가격이 이전 거래와 다르다면 가격 자체만 비교하기보다 비교 조건이 같은지부터 확인해야 합니다. <a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a>에서 이 과정을 더 자세히 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-한-달의-변화보다-비교-기간과-지역을-고릅니다\">4. 한 달의 변화보다 비교 기간과 지역을 고릅니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#4-%ED%95%9C-%EB%8B%AC%EC%9D%98-%EB%B3%80%ED%99%94%EB%B3%B4%EB%8B%A4-%EB%B9%84%EA%B5%90-%EA%B8%B0%EA%B0%84%EA%B3%BC-%EC%A7%80%EC%97%AD%EC%9D%84-%EA%B3%A0%EB%A6%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 한 달의 변화보다 비교 기간과 지역을 고릅니다에 대한 직접 링크\" title=\"4. 한 달의 변화보다 비교 기간과 지역을 고릅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>전국 평균, 시·도 평균, 시·군·구 평균, 개별 단지의 수치는 서로 다른 질문에 답합니다. 먼저 관심 단지와 같은 생활권의 지표를 확인하고, 그다음 더 넓은 지역의 흐름과 비교하는 편이 해석하기 쉽습니다.</p>\n<p>아파트 시장은 한두 건의 거래만으로도 평균이 크게 움직일 수 있습니다. 그래서 월간 변화만 보고 결론을 내리기보다 최근 몇 달 또는 분기 흐름을 함께 봅니다. 같은 기간을 전년 동기와 비교하면 계절적 요인을 줄이는 데 도움이 되고, 장기 흐름과 단기 변화가 같은 방향인지도 확인할 수 있습니다.</p>\n<p>기간을 바꿔도 방향이 유지되는지 보는 것이 핵심입니다. 짧은 기간에서만 나타나는 변화라면 거래 구성이나 특정 면적의 영향일 수 있습니다. 비교표에는 지역 범위, 면적, 기간, 지표 정의를 한 줄에 함께 적어 기준이 흔들리지 않게 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-가격-주변의-조건을-함께-봅니다\">5. 가격 주변의 조건을 함께 봅니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#5-%EA%B0%80%EA%B2%A9-%EC%A3%BC%EB%B3%80%EC%9D%98-%EC%A1%B0%EA%B1%B4%EC%9D%84-%ED%95%A8%EA%BB%98-%EB%B4%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"5. 가격 주변의 조건을 함께 봅니다에 대한 직접 링크\" title=\"5. 가격 주변의 조건을 함께 봅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>가격만으로 시장을 설명하기는 어렵습니다. 금리와 대출 여건, 입주·분양 물량, 전세 시장, 세금과 정책 변화처럼 구매 여력과 공급에 영향을 주는 조건을 함께 확인해야 합니다. 다만 어떤 조건이 가격을 얼마나 움직였다고 단정하기 전에, 해당 기간의 변화와 자료 출처를 나란히 기록하는 것이 안전합니다.</p>\n<p>이 단계의 목적은 복잡한 예측을 만드는 것이 아니라, 가격 그래프 하나에 너무 많은 의미를 부여하지 않는 데 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6-미래-가격은-기간과-범위를-나눠-봅니다\">6. 미래 가격은 기간과 범위를 나눠 봅니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#6-%EB%AF%B8%EB%9E%98-%EA%B0%80%EA%B2%A9%EC%9D%80-%EA%B8%B0%EA%B0%84%EA%B3%BC-%EB%B2%94%EC%9C%84%EB%A5%BC-%EB%82%98%EB%88%A0-%EB%B4%85%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"6. 미래 가격은 기간과 범위를 나눠 봅니다에 대한 직접 링크\" title=\"6. 미래 가격은 기간과 범위를 나눠 봅니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>미래 가격을 확인할 때는 목표 기간을 먼저 고릅니다. 6개월 뒤 이사 계획과 18개월 뒤 갈아타기 계획은 서로 다른 시간축을 사용하므로, 숫자만 나란히 놓으면 비교가 되지 않습니다. <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 아파트 전망을 비교할 때 확인할 것</a>에서 기준일과 목표 월을 맞추는 방법을 정리했습니다.</p>\n<p>또한 예상가는 확정 가격이 아니라 여러 가능성 가운데 기준점으로 읽어야 합니다. 아래·가운데·위 값으로 표시된 범위가 있다면 범위의 폭과 거래 표본, 시장 정보의 시점을 함께 확인합니다. <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값을 해석하는 법</a>에서 실제 결과 화면을 읽는 순서를 이어서 볼 수 있습니다.</p>\n<p>예측 결과를 얼마나 믿을지는 과거 예측이 실제 거래와 얼마나 달랐는지로 판단합니다. 평균 오차율과 범위 적중률을 읽는 법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest\">아파트 가격 예측, 맞았는지 확인하는 법</a>에서 다룹니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"7-기준일자료-상태출처를-마지막에-기록합니다\">7. 기준일·자료 상태·출처를 마지막에 기록합니다<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#7-%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9E%90%EB%A3%8C-%EC%83%81%ED%83%9C%EC%B6%9C%EC%B2%98%EB%A5%BC-%EB%A7%88%EC%A7%80%EB%A7%89%EC%97%90-%EA%B8%B0%EB%A1%9D%ED%95%A9%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"7. 기준일·자료 상태·출처를 마지막에 기록합니다에 대한 직접 링크\" title=\"7. 기준일·자료 상태·출처를 마지막에 기록합니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>좋은 통계 메모에는 숫자뿐 아니라 출처와 한계가 함께 남습니다. <a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개시스템</a>처럼 원자료에 가까운 출처를 우선하고, 작성일과 조회 범위를 기록합니다. 거래가 적은 지역이나 면적은 “자료 부족” 자체가 중요한 정보일 수 있습니다.</p>\n<p>미래 가격 결과를 참고했다면 계산 기준일, 시장 정보가 갱신된 날짜, 거래 표본 상태를 함께 적어두세요. 새 거래가 추가되거나 시장 자료가 갱신되면 같은 단지의 결과가 달라질 수 있습니다. <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">아파트 가격 예측 결과에서 기준일·시장 정보·표본 신뢰도 읽는 법</a>에서 결과를 기록하는 방법을 설명합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-생기는-해석-오류\">자주 생기는 해석 오류<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%EC%9E%90%EC%A3%BC-%EC%83%9D%EA%B8%B0%EB%8A%94-%ED%95%B4%EC%84%9D-%EC%98%A4%EB%A5%98\" class=\"hash-link\" aria-label=\"자주 생기는 해석 오류에 대한 직접 링크\" title=\"자주 생기는 해석 오류에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최근-최고가를-현재-대표-시세로-생각하는-경우\">최근 최고가를 현재 대표 시세로 생각하는 경우<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%EC%B5%9C%EA%B7%BC-%EC%B5%9C%EA%B3%A0%EA%B0%80%EB%A5%BC-%ED%98%84%EC%9E%AC-%EB%8C%80%ED%91%9C-%EC%8B%9C%EC%84%B8%EB%A1%9C-%EC%83%9D%EA%B0%81%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"최근 최고가를 현재 대표 시세로 생각하는 경우에 대한 직접 링크\" title=\"최근 최고가를 현재 대표 시세로 생각하는 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>최고가 거래는 중요한 사례지만 대표값과 같은 뜻은 아닙니다. 면적, 층, 거래 시점과 거래 유형을 확인한 다음 여러 건의 흐름과 비교해야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예상가-가운데-값을-확정-가격으로-생각하는-경우\">예상가 가운데 값을 확정 가격으로 생각하는 경우<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%EC%98%88%EC%83%81%EA%B0%80-%EA%B0%80%EC%9A%B4%EB%8D%B0-%EA%B0%92%EC%9D%84-%ED%99%95%EC%A0%95-%EA%B0%80%EA%B2%A9%EC%9C%BC%EB%A1%9C-%EC%83%9D%EA%B0%81%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"예상가 가운데 값을 확정 가격으로 생각하는 경우에 대한 직접 링크\" title=\"예상가 가운데 값을 확정 가격으로 생각하는 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>가운데 값은 비교를 위한 기준점입니다. 실제 결과는 거래 조건과 시장 상황에 따라 달라질 수 있으므로 아래·가운데·위 값을 함께 보고 범위의 폭을 기록합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결과가-바뀐-것을-오류로만-생각하는-경우\">결과가 바뀐 것을 오류로만 생각하는 경우<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B0%94%EB%80%90-%EA%B2%83%EC%9D%84-%EC%98%A4%EB%A5%98%EB%A1%9C%EB%A7%8C-%EC%83%9D%EA%B0%81%ED%95%98%EB%8A%94-%EA%B2%BD%EC%9A%B0\" class=\"hash-link\" aria-label=\"결과가 바뀐 것을 오류로만 생각하는 경우에 대한 직접 링크\" title=\"결과가 바뀐 것을 오류로만 생각하는 경우에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>기준일, 새 거래, 시장 정보, 표본 상태가 바뀌었는지 먼저 확인합니다. 같은 질문을 같은 조건으로 다시 조회했는지까지 기록하면 결과 변화의 원인을 추적하기 쉽습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"최종-체크리스트\">최종 체크리스트<a href=\"https://alvin.ing/blog/real-estate-apartment-statistics-reading-order#%EC%B5%9C%EC%A2%85-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"최종 체크리스트에 대한 직접 링크\" title=\"최종 체크리스트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul class=\"contains-task-list containsTaskList_mC6p\">\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->실거래가·호가·평균·중앙값 중 무엇인지 적었는가</li>\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->단지, 전용면적, 타입, 층 조건을 맞췄는가</li>\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->최근 거래 한 건이 아니라 거래량과 조건 분포를 봤는가</li>\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->비교 기간과 지역 범위를 고정했는가</li>\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->미래 결과의 목표 기간과 예상 범위를 확인했는가</li>\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"> <!-- -->기준일, 자료 갱신 시점, 출처와 한계를 기록했는가</li>\n</ul>\n<p>정리하면, 부동산과 아파트 통계를 읽는 순서는 <strong>질문 정의 → 조건 맞추기 → 거래 표본 확인 → 기간·지역 맞추기 → 주변 조건 확인 → 미래 범위 확인 → 출처와 한계 기록</strong>입니다. 이 순서만 지켜도 단기 숫자 하나에 흔들리지 않고, 다음에 들어오는 새 데이터를 같은 기준으로 비교할 수 있습니다.</p>\n<p>관심 단지의 최근 거래와 대표 시세는 <a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>에서, 1년 뒤 예상 범위는 <a href=\"https://apt-insights.com/#free-forecast-experience\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">아파트 인사이트 가입 없는 공개 예측</a>에서 같은 기준으로 확인할 수 있습니다. 결과를 해석할 때는 숫자만 보지 말고 이 글의 체크리스트와 함께 기준일·평형·거래 표본을 확인하는 것이 좋습니다.</p>\n<p>더 깊은 데이터 해석은 <a class=\"\" href=\"https://alvin.ing/docs/intro\">개발 리서치 문서</a>와 아래 글에서 이어서 확인할 수 있습니다.</p>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-real-transaction-price-by-region\">지역별 아파트 실거래가 조회하는 법</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">아파트 가격을 현재·과거·미래로 나눠 읽는 법</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-without-signup\">가입 없이 아파트 가격 예측하기</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-periods\">6개월·12개월·18개월 아파트 전망 비교하기</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값 읽기</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-single-trade-limit\">최근 거래 한 건만으로 아파트 시세를 판단하면 안 되는 이유</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-metadata\">아파트 가격 예측 결과에서 기준일·시장 정보·표본 신뢰도 읽기</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-insights-start-guide\">아파트 분석을 시작할 때 지역·단지·이사 시점을 정하는 법</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-analysis-share-url\">아파트 분석 공유 URL을 보내기 전 확인할 것</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-forecast-accuracy-backtest\">아파트 가격 예측, 맞았는지 확인하는 법</a></li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-app-guest-mode\">로그인 없이 아파트 시세 앱 쓰는 법</a></li>\n</ul>",
            "url": "https://alvin.ing/blog/real-estate-apartment-statistics-reading-order",
            "title": "부동산과 아파트 통계를 처음 읽는 순서",
            "summary": "부동산과 아파트 통계를 볼 때 가격, 거래량, 기간, 지역, 금리와 공급을 어떤 순서로 확인하면 좋은지 정리했습니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-price-current-history-forecast",
            "content_html": "<p>아파트 가격을 검색하면 실거래가, 호가, 과거 최고가, 예상 가격이 한 화면에 섞여 나오는 경우가 많습니다. 하지만 이 네 가지 숫자는 서로 다른 질문에 답합니다.</p>\n<ul>\n<li class=\"\">지금 실제로 계약된 가격은 얼마인가</li>\n<li class=\"\">같은 단지가 과거에 어떤 흐름을 보였는가</li>\n<li class=\"\">앞으로 가능한 가격 경로는 어느 정도의 폭을 가지는가</li>\n</ul>\n<p>이 질문을 한 숫자로 합치면 시세를 빠르게 보는 것 같지만, 오히려 중요한 차이를 놓치기 쉽습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"먼저-세-가지-층을-분리해-보기\">먼저 세 가지 층을 분리해 보기<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EB%A8%BC%EC%A0%80-%EC%84%B8-%EA%B0%80%EC%A7%80-%EC%B8%B5%EC%9D%84-%EB%B6%84%EB%A6%AC%ED%95%B4-%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"먼저 세 가지 층을 분리해 보기에 대한 직접 링크\" title=\"먼저 세 가지 층을 분리해 보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<figure class=\"chart_ePMC\" aria-labelledby=\"price-layers-title\"><figcaption id=\"price-layers-title\">아파트 가격을 읽는 세 겹의 기준</figcaption><svg class=\"svg_iJRh\" viewBox=\"0 0 760 300\" role=\"img\"><title>과거 거래, 현재 기준점, 미래 예상 범위를 나누어 보는 개념도</title><desc>과거에는 여러 거래가 쌓이고, 현재 시점에는 기준점이 있으며, 앞으로는 하나의 선이 아니라 범위로 표시됩니다.</desc><line class=\"axis_UuWW\" x1=\"74\" y1=\"238\" x2=\"704\" y2=\"238\"></line><line class=\"axis_UuWW\" x1=\"74\" y1=\"42\" x2=\"74\" y2=\"238\"></line><path class=\"historyLine_La1q\" d=\"M90 188 C150 174 172 202 220 164 S300 182 350 133 S428 161 492 113\"></path><path class=\"rangeFill_qohg\" d=\"M492 86 C546 62 612 76 690 48 L690 178 C612 192 548 168 492 150 Z\"></path><path class=\"rangeLine_e83W\" d=\"M492 118 C548 96 614 105 690 84\"></path><line class=\"nowLine__2dM\" x1=\"492\" y1=\"42\" x2=\"492\" y2=\"238\"></line><circle class=\"currentDot_nwU5\" cx=\"492\" cy=\"113\" r=\"7\"></circle><text class=\"label_qJ8_\" x=\"95\" y=\"270\">과거 거래</text><text class=\"label_qJ8_\" x=\"466\" y=\"270\">현재</text><text class=\"label_qJ8_\" x=\"624\" y=\"270\">앞으로</text><text class=\"annotation_Q2mh\" x=\"108\" y=\"82\">여러 거래의 흐름</text><text class=\"annotation_Q2mh\" x=\"510\" y=\"70\">예상 범위</text><text class=\"annotation_Q2mh\" x=\"503\" y=\"105\">현재 기준점</text><text class=\"axisTitle_QqkH\" data-axis=\"y\" x=\"16\" y=\"150\" transform=\"rotate(-90 16 150)\">가격 수준</text><text class=\"axisTitle_QqkH\" data-axis=\"x\" x=\"370\" y=\"294\">시간</text></svg><div class=\"legend_EjCp\" aria-label=\"차트 범례\"><span class=\"legendItem_onys\"><span class=\"legendSwatch_sSIh legendHistory_AR_m\" aria-hidden=\"true\"></span>과거 실거래 흐름</span><span class=\"legendItem_onys\"><span class=\"legendSwatch_sSIh legendCurrent_ytTv\" aria-hidden=\"true\"></span>현재 기준점</span><span class=\"legendItem_onys\"><span class=\"legendSwatch_sSIh legendRange_sfOB\" aria-hidden=\"true\"></span>미래 예상 범위</span></div><p class=\"note_l0U4\">개념도입니다. 실제 단지 분석에서는 기준일·면적·거래 표본을 따로 확인해야 합니다.</p></figure>\n<p>위 차트는 특정 단지의 실제 데이터가 아니라 <strong>가격 정보를 읽는 순서</strong>를 나타낸 개념도입니다. 과거 거래는 이미 관측된 기록이고, 현재 거래는 기준일의 앵커이며, 미래는 여러 조건에 따라 달라질 수 있는 범위입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-최근-실거래가는-현재-확인된-거래다\">1. 최근 실거래가는 ‘현재 확인된 거래’다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#1-%EC%B5%9C%EA%B7%BC-%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80%EB%8A%94-%ED%98%84%EC%9E%AC-%ED%99%95%EC%9D%B8%EB%90%9C-%EA%B1%B0%EB%9E%98%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 최근 실거래가는 ‘현재 확인된 거래’다에 대한 직접 링크\" title=\"1. 최근 실거래가는 ‘현재 확인된 거래’다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>국토교통부 <a href=\"https://rt.molit.go.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">실거래가 공개시스템</a>의 아파트 거래는 계약일을 기준으로 조회합니다. 신고와 공개 사이에는 시간이 생길 수 있고, 계약이 해제되거나 정정될 수도 있으므로 조회 시점의 데이터 상태도 함께 봐야 합니다.</p>\n<p>실거래가를 볼 때는 가격만 복사하지 말고 다음 조건을 같이 기록하는 편이 좋습니다.</p>\n<ul>\n<li class=\"\">전용면적과 평형</li>\n<li class=\"\">거래 시점과 층</li>\n<li class=\"\">동일 단지 안의 동·향·뷰 차이</li>\n<li class=\"\">직전 거래와의 시간 간격</li>\n<li class=\"\">거래량이 충분한지 여부</li>\n</ul>\n<p>같은 단지라도 면적과 층이 다르면 가격을 그대로 비교하기 어렵습니다. 특히 거래가 드문 단지는 최근 한 건이 단지 전체의 대표 가격처럼 보일 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-과거-이력은-방향보다-맥락을-보여준다\">2. 과거 이력은 방향보다 맥락을 보여준다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#2-%EA%B3%BC%EA%B1%B0-%EC%9D%B4%EB%A0%A5%EC%9D%80-%EB%B0%A9%ED%96%A5%EB%B3%B4%EB%8B%A4-%EB%A7%A5%EB%9D%BD%EC%9D%84-%EB%B3%B4%EC%97%AC%EC%A4%80%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 과거 이력은 방향보다 맥락을 보여준다에 대한 직접 링크\" title=\"2. 과거 이력은 방향보다 맥락을 보여준다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>과거 가격 흐름은 “얼마나 올랐나”만 계산하는 자료가 아닙니다. 다음과 같은 질문을 확인하는 자료입니다.</p>\n<ul>\n<li class=\"\">가격 변화가 한두 건의 거래 때문인지, 여러 달 이어진 흐름인지</li>\n<li class=\"\">상승과 하락이 거래량 변화와 함께 나타났는지</li>\n<li class=\"\">비슷한 면적의 거래가 반복적으로 확인되는지</li>\n<li class=\"\">특정 시점의 정책·금리·공급 변화와 움직임이 겹치는지</li>\n</ul>\n<p>과거 최고가와 현재 거래가를 비교하는 것도 도움이 되지만, 최고가를 회복해야 한다는 목표처럼 사용하면 안 됩니다. 최고가는 특정 시점의 거래 조건을 포함한 기록일 뿐, 미래 가격의 기준선이나 보장값이 아니기 때문입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-미래는-한-줄보다-범위로-읽는다\">3. 미래는 한 줄보다 범위로 읽는다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#3-%EB%AF%B8%EB%9E%98%EB%8A%94-%ED%95%9C-%EC%A4%84%EB%B3%B4%EB%8B%A4-%EB%B2%94%EC%9C%84%EB%A1%9C-%EC%9D%BD%EB%8A%94%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 미래는 한 줄보다 범위로 읽는다에 대한 직접 링크\" title=\"3. 미래는 한 줄보다 범위로 읽는다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>미래 예상은 아직 관측되지 않은 구간입니다. 금리, 공급, 거래량, 정책, 지역별 수요가 달라지면 같은 단지도 다른 경로를 보일 수 있습니다.</p>\n<p>따라서 “12개월 뒤 얼마인가요?”보다 다음 질문이 더 정확합니다.</p>\n<ol>\n<li class=\"\">현재 기준점은 어떤 거래와 기준일로 만들어졌는가</li>\n<li class=\"\">예상 범위의 아래쪽과 위쪽은 어떤 불확실성을 담고 있는가</li>\n<li class=\"\">기간이 길어질수록 범위가 넓어지는가</li>\n<li class=\"\">내 보유·거주·대출 조건을 넣으면 해석이 달라지는가</li>\n</ol>\n<p>미래 가격을 범위로 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-range-not-single-number\">하나의 숫자보다 범위로 봐야 하는 이유</a>에서 더 자세히 설명했습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"아파트-시세를-읽는-실전-순서\">아파트 시세를 읽는 실전 순서<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EC%95%84%ED%8C%8C%ED%8A%B8-%EC%8B%9C%EC%84%B8%EB%A5%BC-%EC%9D%BD%EB%8A%94-%EC%8B%A4%EC%A0%84-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"아파트 시세를 읽는 실전 순서에 대한 직접 링크\" title=\"아파트 시세를 읽는 실전 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"첫째-기준일을-고정한다\">첫째, 기준일을 고정한다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EC%B2%AB%EC%A7%B8-%EA%B8%B0%EC%A4%80%EC%9D%BC%EC%9D%84-%EA%B3%A0%EC%A0%95%ED%95%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"첫째, 기준일을 고정한다에 대한 직접 링크\" title=\"첫째, 기준일을 고정한다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>“최근”이라는 말만으로는 부족합니다. 조회 기준일과 마지막 거래일을 함께 적어야 오래된 정보와 최신 정보를 구분할 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"둘째-비교-조건을-맞춘다\">둘째, 비교 조건을 맞춘다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EB%91%98%EC%A7%B8-%EB%B9%84%EA%B5%90-%EC%A1%B0%EA%B1%B4%EC%9D%84-%EB%A7%9E%EC%B6%98%EB%8B%A4\" class=\"hash-link\" aria-label=\"둘째, 비교 조건을 맞춘다에 대한 직접 링크\" title=\"둘째, 비교 조건을 맞춘다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>전용면적·층·거래 유형이 다른 가격을 한 선에 올리면 차트가 정교해 보여도 해석은 흔들립니다. 같은 조건을 먼저 모은 뒤, 다른 조건은 별도 표본으로 분리합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"셋째-현재과거미래를-다른-색과-영역으로-본다\">셋째, 현재·과거·미래를 다른 색과 영역으로 본다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EC%85%8B%EC%A7%B8-%ED%98%84%EC%9E%AC%EA%B3%BC%EA%B1%B0%EB%AF%B8%EB%9E%98%EB%A5%BC-%EB%8B%A4%EB%A5%B8-%EC%83%89%EA%B3%BC-%EC%98%81%EC%97%AD%EC%9C%BC%EB%A1%9C-%EB%B3%B8%EB%8B%A4\" class=\"hash-link\" aria-label=\"셋째, 현재·과거·미래를 다른 색과 영역으로 본다에 대한 직접 링크\" title=\"셋째, 현재·과거·미래를 다른 색과 영역으로 본다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>과거는 선, 현재는 기준점, 미래는 띠나 범위로 표시하면 숫자의 성격이 한눈에 드러납니다. 세 값을 한 선으로 이어 그리면 예상과 사실이 같은 확실성을 가진 것처럼 보일 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"넷째-숫자와-함께-데이터의-빈틈을-적는다\">넷째, 숫자와 함께 데이터의 빈틈을 적는다<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EB%84%B7%EC%A7%B8-%EC%88%AB%EC%9E%90%EC%99%80-%ED%95%A8%EA%BB%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-%EB%B9%88%ED%8B%88%EC%9D%84-%EC%A0%81%EB%8A%94%EB%8B%A4\" class=\"hash-link\" aria-label=\"넷째, 숫자와 함께 데이터의 빈틈을 적는다에 대한 직접 링크\" title=\"넷째, 숫자와 함께 데이터의 빈틈을 적는다에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>거래가 적은 단지, 면적이 섞인 표본, 해제 거래가 포함된 경우에는 “가격이 얼마다”보다 “이 가격을 얼마나 확실하게 비교할 수 있는가”가 먼저입니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료와-다음-읽을거리\">참고 자료와 다음 읽을거리<a href=\"https://alvin.ing/blog/apartment-price-current-history-forecast#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C%EC%99%80-%EB%8B%A4%EC%9D%8C-%EC%9D%BD%EC%9D%84%EA%B1%B0%EB%A6%AC\" class=\"hash-link\" aria-label=\"참고 자료와 다음 읽을거리에 대한 직접 링크\" title=\"참고 자료와 다음 읽을거리에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/pt/info/info.do?mobileAt=v\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개 안내</a>: 계약일 기준 실거래가와 거래 통계의 차이를 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/pt/bbs/faqList.do?mobileAt=&amp;qnaProcessSttusCode=1\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 FAQ</a>: 계약일·신고일·공개 시점과 해제 거래 표시 기준을 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://www.reb.or.kr/r-one/portal/main/indexPage.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국부동산원 부동산통계정보시스템 R-ONE</a>: 주택가격지수와 거래현황처럼 실거래가와 함께 비교할 공식 통계를 제공합니다.</li>\n<li class=\"\"><a href=\"https://apt-insights.com/apt/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지역별 아파트 실거래가</a>: 단지별 최근 거래, 대표 시세, 최근 1년 거래 범위를 평형 단위로 정리한 페이지입니다.</li>\n<li class=\"\"><a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">미래가격 예측 공식 가이드</a>: 과거 거래와 미래 예상 경로를 구분해 읽는 공개 설명입니다.</li>\n<li class=\"\"><a class=\"\" href=\"https://alvin.ing/blog/apartment-price-range-not-single-number\">미래 가격 범위를 읽는 방법</a>: 하나의 숫자로 단정하지 않는 이유를 이어서 설명합니다.</li>\n</ul>\n<p>과거 거래 흐름을 확인한 다음 내 관심 단지와 보유 조건까지 함께 비교하고 싶다면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공개 아파트 분석 도구</a>에서 같은 질문을 직접 적용해볼 수 있습니다.</p>\n<blockquote>\n<p>실거래가와 예상 범위는 기준일·표본·조건에 따라 달라질 수 있습니다. 이 글은 투자 권유나 매수·매도 추천이 아니며, 최종 판단과 책임은 이용자에게 있습니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-price-current-history-forecast",
            "title": "아파트 가격을 볼 때 현재 거래가·과거 이력·예상 범위를 나눠야 하는 이유",
            "summary": "아파트 시세를 읽을 때 최근 실거래가, 과거 가격 흐름, 미래 예상 범위를 한 숫자로 섞지 않는 방법을 차트로 설명합니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/apartment-price-range-not-single-number",
            "content_html": "<p>“그래서 1년 뒤 아파트 가격은 얼마인가요?”라는 질문은 자연스럽지만, 답을 하나의 숫자로만 받으면 오히려 중요한 정보를 잃을 수 있습니다.</p>\n<p>가격 전망에는 기준일, 거래 표본, 금리, 공급, 정책, 지역별 수요가 함께 들어갑니다. 이 조건들이 조금만 달라져도 결과가 달라질 수 있기 때문에, 좋은 전망은 숫자를 단정하기보다 <strong>가능한 범위와 그 범위를 만든 조건</strong>을 보여줍니다.</p>\n<p>이 글의 초점은 “왜 미래 가격을 범위로 봐야 하는가”라는 개념 설명입니다. 실제 결과 화면에 표시된 아래·가운데·위 값을 어떤 순서로 읽을지는 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위의 아래·가운데·위 값을 해석하는 법</a>에서 별도로 다룹니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"하나의-숫자보다-범위가-필요한-이유\">하나의 숫자보다 범위가 필요한 이유<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%ED%95%98%EB%82%98%EC%9D%98-%EC%88%AB%EC%9E%90%EB%B3%B4%EB%8B%A4-%EB%B2%94%EC%9C%84%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"하나의 숫자보다 범위가 필요한 이유에 대한 직접 링크\" title=\"하나의 숫자보다 범위가 필요한 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<figure class=\"chart_ePMC\" aria-labelledby=\"price-range-title\"><figcaption id=\"price-range-title\">하나의 예측값보다 범위가 알려주는 것</figcaption><svg class=\"svg_iJRh\" viewBox=\"0 0 760 300\" role=\"img\"><title>같은 출발점에서 보수적, 기준, 낙관적 범위가 달라지는 개념도</title><desc>세 가지 가정은 같은 현재 기준점에서 출발하지만 시간이 멀어질수록 가능한 결과의 폭이 달라집니다.</desc><line class=\"axis_UuWW\" x1=\"160\" y1=\"238\" x2=\"704\" y2=\"238\"></line><line class=\"axis_UuWW\" x1=\"160\" y1=\"42\" x2=\"160\" y2=\"238\"></line><line class=\"referenceLine_Lmel\" x1=\"250\" y1=\"56\" x2=\"250\" y2=\"238\"></line><line class=\"referenceLine_Lmel\" x1=\"650\" y1=\"56\" x2=\"650\" y2=\"238\"></line><text class=\"label_qJ8_\" x=\"224\" y=\"270\">현재</text><text class=\"label_qJ8_\" x=\"616\" y=\"270\">먼 미래</text><text class=\"label_qJ8_\" x=\"104\" y=\"94\">보수적</text><text class=\"label_qJ8_\" x=\"115\" y=\"158\">기준</text><text class=\"label_qJ8_\" x=\"103\" y=\"222\">낙관적</text><path class=\"rangeFillMuted_wTnc\" d=\"M250 82 C374 68 526 58 650 48 L650 118 C526 126 374 142 250 138 Z\"></path><path class=\"rangeLine_e83W\" d=\"M250 110 C384 98 526 87 650 80\"></path><path class=\"rangeFill_qohg\" d=\"M250 139 C374 126 526 119 650 101 L650 174 C526 181 374 197 250 188 Z\"></path><path class=\"rangeLine_e83W\" d=\"M250 164 C384 153 526 146 650 138\"></path><path class=\"rangeFillMuted_wTnc\" d=\"M250 196 C374 185 526 182 650 167 L650 236 C526 232 374 230 250 228 Z\"></path><path class=\"rangeLine_e83W\" d=\"M250 212 C384 208 526 207 650 198\"></path><circle class=\"currentDot_nwU5\" cx=\"250\" cy=\"164\" r=\"7\"></circle><text class=\"annotation_Q2mh\" x=\"290\" y=\"64\">시간이 멀어질수록 가정의 차이가 범위에 반영됨</text><text class=\"axisTitle_QqkH\" data-axis=\"y\" x=\"16\" y=\"152\" transform=\"rotate(-90 16 152)\">가능한 가격 경로</text><text class=\"axisTitle_QqkH\" data-axis=\"x\" x=\"395\" y=\"294\">예측 기간</text></svg><div class=\"legend_EjCp\" aria-label=\"차트 범례\"><span class=\"legendItem_onys\"><span class=\"legendSwatch_sSIh legendRange_sfOB\" aria-hidden=\"true\"></span>가능한 결과의 폭</span><span class=\"legendItem_onys\"><span class=\"legendSwatch_sSIh legendCurrent_ytTv\" aria-hidden=\"true\"></span>범위 안의 중심 추정</span></div><p class=\"note_l0U4\">범위는 보장이 아니라 불확실성을 보여주는 참고 정보입니다.</p></figure>\n<p>위 차트는 특정 지역이나 단지의 실제 전망이 아니라, 시간이 멀어질수록 불확실성이 커지는 구조를 보여주는 개념도입니다. 세 경로가 모두 같은 현재 기준점에서 시작하더라도 미래로 갈수록 조건의 차이가 결과의 폭으로 나타납니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"중심-추정값은-결론이-아니라-기준점이다\">중심 추정값은 결론이 아니라 기준점이다<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%EC%A4%91%EC%8B%AC-%EC%B6%94%EC%A0%95%EA%B0%92%EC%9D%80-%EA%B2%B0%EB%A1%A0%EC%9D%B4-%EC%95%84%EB%8B%88%EB%9D%BC-%EA%B8%B0%EC%A4%80%EC%A0%90%EC%9D%B4%EB%8B%A4\" class=\"hash-link\" aria-label=\"중심 추정값은 결론이 아니라 기준점이다에 대한 직접 링크\" title=\"중심 추정값은 결론이 아니라 기준점이다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>중심에 있는 추정값은 여러 가능성 중 하나를 읽기 위한 기준입니다. 그 숫자만 보고 “이 가격에 도달한다”고 해석하면 안 됩니다.</p>\n<p>중심 추정값을 볼 때는 다음을 확인하세요.</p>\n<ul>\n<li class=\"\">기준일이 언제인가</li>\n<li class=\"\">마지막으로 반영된 거래는 언제인가</li>\n<li class=\"\">대상 면적과 비교 표본이 일치하는가</li>\n<li class=\"\">예상 기간이 6개월인지 12개월인지 18개월인지</li>\n<li class=\"\">금리와 공급 같은 조건이 고정되어 있는가</li>\n</ul>\n<p>기간이 길어질수록 확인해야 할 조건이 늘어나므로, 짧은 기간의 좁은 범위와 긴 기간의 넓은 범위를 같은 의미로 비교하면 안 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위의-아래쪽과-위쪽은-무엇을-뜻할까\">범위의 아래쪽과 위쪽은 무엇을 뜻할까<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%EB%B2%94%EC%9C%84%EC%9D%98-%EC%95%84%EB%9E%98%EC%AA%BD%EA%B3%BC-%EC%9C%84%EC%AA%BD%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%84-%EB%9C%BB%ED%95%A0%EA%B9%8C\" class=\"hash-link\" aria-label=\"범위의 아래쪽과 위쪽은 무엇을 뜻할까에 대한 직접 링크\" title=\"범위의 아래쪽과 위쪽은 무엇을 뜻할까에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>범위의 아래쪽은 반드시 하락한다는 뜻이 아닙니다. 거래가 줄거나 자금 부담이 커지는 등 불리한 조건이 이어질 때 가능한 경로를 보여주는 참고선에 가깝습니다.</p>\n<p>범위의 위쪽도 반드시 도달한다는 뜻이 아닙니다. 수요가 유지되고 거래 환경이 개선되는 경우처럼 다른 조건에서 가능한 경로를 보여줍니다.</p>\n<p>따라서 범위를 읽을 때는 “아래냐 위냐”보다 다음을 묻는 편이 낫습니다.</p>\n<ol>\n<li class=\"\">두 경계를 벌어지게 만든 조건은 무엇인가</li>\n<li class=\"\">지금 확인된 자료가 어느 구간까지 충분한가</li>\n<li class=\"\">내 아파트의 거래 표본이 같은 조건을 대표하는가</li>\n<li class=\"\">새 거래나 정책 변화가 생기면 범위가 다시 계산되는가</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"범위가-넓다고-분석이-무의미한-것은-아니다\">범위가 넓다고 분석이 무의미한 것은 아니다<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%EB%B2%94%EC%9C%84%EA%B0%80-%EB%84%93%EB%8B%A4%EA%B3%A0-%EB%B6%84%EC%84%9D%EC%9D%B4-%EB%AC%B4%EC%9D%98%EB%AF%B8%ED%95%9C-%EA%B2%83%EC%9D%80-%EC%95%84%EB%8B%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"범위가 넓다고 분석이 무의미한 것은 아니다에 대한 직접 링크\" title=\"범위가 넓다고 분석이 무의미한 것은 아니다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>범위가 넓다는 것은 현재 시점에서 모르는 것이 많다는 뜻이지, 아무 정보도 없다는 뜻은 아닙니다. 오히려 아래와 같은 판단에 도움이 됩니다.</p>\n<ul>\n<li class=\"\">단기와 장기의 불확실성 차이</li>\n<li class=\"\">금리 변화에 민감한 자금 계획인지 여부</li>\n<li class=\"\">거래가 부족해 추가 확인이 필요한 단지인지 여부</li>\n<li class=\"\">특정 조건을 바꿨을 때 결과가 얼마나 움직이는지</li>\n</ul>\n<p>반대로 범위가 지나치게 좁은데 기준일·거래 표본·조건 설명이 없다면, 숫자가 정교해 보이는 것과 실제로 확실한 것은 구분해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"현재-가격과-미래-범위를-한-차트에-놓는-법\">현재 가격과 미래 범위를 한 차트에 놓는 법<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%ED%98%84%EC%9E%AC-%EA%B0%80%EA%B2%A9%EA%B3%BC-%EB%AF%B8%EB%9E%98-%EB%B2%94%EC%9C%84%EB%A5%BC-%ED%95%9C-%EC%B0%A8%ED%8A%B8%EC%97%90-%EB%86%93%EB%8A%94-%EB%B2%95\" class=\"hash-link\" aria-label=\"현재 가격과 미래 범위를 한 차트에 놓는 법에 대한 직접 링크\" title=\"현재 가격과 미래 범위를 한 차트에 놓는 법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>아파트 가격 차트를 만들 때는 다음 세 가지 표현을 분리하는 것이 좋습니다.</p>\n<table><thead><tr><th>표현</th><th>보여주는 것</th><th>읽을 때 주의할 점</th></tr></thead><tbody><tr><td>점</td><td>현재 기준점 또는 최근 대표 거래</td><td>어떤 조건의 거래인지 확인</td></tr><tr><td>선</td><td>과거 거래 흐름 또는 중심 경로</td><td>사실과 전망의 경계 확인</td></tr><tr><td>띠</td><td>가능한 가격 범위</td><td>보장값이 아닌 불확실성 표시</td></tr></tbody></table>\n<p>이렇게 그리면 독자는 “이미 발생한 가격”과 “앞으로 가능한 경로”를 같은 확실성으로 받아들이지 않게 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"전망을-읽기-전-체크리스트\">전망을 읽기 전 체크리스트<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%EC%A0%84%EB%A7%9D%EC%9D%84-%EC%9D%BD%EA%B8%B0-%EC%A0%84-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"전망을 읽기 전 체크리스트에 대한 직접 링크\" title=\"전망을 읽기 전 체크리스트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">가격 기준이 실거래가인지 호가인지 확인하기</li>\n<li class=\"\">기준일과 마지막 데이터 시점 확인하기</li>\n<li class=\"\">면적·층·거래 유형이 같은지 확인하기</li>\n<li class=\"\">기간별 범위를 따로 비교하기</li>\n<li class=\"\">금리·공급·정책 조건이 바뀌었는지 확인하기</li>\n<li class=\"\">가격 범위를 매수·매도 추천으로 바꾸어 해석하지 않기</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/apartment-price-range-not-single-number#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.reb.or.kr/r-one/portal/main/indexPage.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국부동산원 부동산통계정보시스템 R-ONE</a>: 주택가격지수·거래현황 등 공개 통계를 확인하고 전망의 기준 기간을 맞출 수 있습니다.</li>\n<li class=\"\"><a href=\"https://www.reb.or.kr/reb/cm/cntnts/cntntsView.do?cntntsId=1033&amp;mi=10333&amp;statId=S234820263\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국부동산원 전국주택가격동향조사</a>: 통계의 작성기관·기준시점·공표 범위를 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://rt.molit.go.kr/pt/info/info.do?mobileAt=v\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 실거래가 공개 안내</a>: 계약일 기준 실거래 자료와 거래 통계의 차이를 확인할 수 있습니다.</li>\n</ul>\n<p>앞서 읽은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">현재 거래가·과거 이력·예상 범위를 나눠 보는 방법</a>과 함께 보면 차트의 각 선과 띠가 어떤 역할을 하는지 더 쉽게 이해할 수 있습니다. 공개된 예측 개념을 더 자세히 보고 싶다면 <a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">미래가격 예측 공식 가이드</a>와 <a href=\"https://apt-insights.com/model\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">기술 백서</a>를 참고할 수 있습니다. 실제 결과 카드의 하단·중앙·상단 값을 확인하려면 <a class=\"\" href=\"https://alvin.ing/blog/apartment-forecast-range-reading\">아파트 예상 범위 화면 읽기</a>로 이어서 읽어 보세요.</p>\n<p>내 관심 아파트의 기준일·거래 흐름·기간별 조건을 직접 비교해보고 싶다면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공개 아파트 분석 도구</a>에서 같은 방식으로 조건을 확인해볼 수 있습니다.</p>\n<blockquote>\n<p>가격 전망과 범위는 참고용 분석이며 실제 가격·거래 가능성·수익을 보장하지 않습니다. 이 글은 투자 자문이나 매수·매도 추천이 아닙니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/apartment-price-range-not-single-number",
            "title": "미래 아파트 가격을 하나의 숫자로 단정하면 위험한 이유",
            "summary": "아파트 가격 전망을 중심값 하나가 아니라 가능한 범위로 읽어야 하는 이유와, 기간·거래 표본·금리 조건을 함께 비교하는 방법을 설명합니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "부동산 데이터"
            ]
        },
        {
            "id": "https://alvin.ing/blog/transport-benefit-stages-apartment-price",
            "content_html": "\n<p>“새 노선이 들어온다”는 한 문장만으로 아파트 가격을 판단하기는 어렵습니다. 같은 교통 사업이라도 발표 단계인지, 검토가 끝났는지, 공사가 시작됐는지, 실제로 이용할 수 있는지에 따라 확인해야 할 내용이 완전히 달라집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"교통-호재는-진행-단계가-핵심이다\">교통 호재는 진행 단계가 핵심이다<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#%EA%B5%90%ED%86%B5-%ED%98%B8%EC%9E%AC%EB%8A%94-%EC%A7%84%ED%96%89-%EB%8B%A8%EA%B3%84%EA%B0%80-%ED%95%B5%EC%8B%AC%EC%9D%B4%EB%8B%A4\" class=\"hash-link\" aria-label=\"교통 호재는 진행 단계가 핵심이다에 대한 직접 링크\" title=\"교통 호재는 진행 단계가 핵심이다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<figure class=\"chart_ePMC\" aria-labelledby=\"transport-stage-title\"><figcaption id=\"transport-stage-title\">교통 호재는 단계별로 다시 확인해야 합니다</figcaption><div class=\"timeline_Yq6B\" role=\"img\" aria-label=\"교통 사업의 발표, 검토와 타당성, 계획과 설계, 착공, 개통 단계\"><div class=\"timelineLine_LucZ\" aria-hidden=\"true\"></div><div class=\"timelineStep_A8qs\"><div class=\"timelineDot_mlBL\">1</div><strong>발표</strong><span>방향과 필요성</span></div><div class=\"timelineStep_A8qs\"><div class=\"timelineDot_mlBL\">2</div><strong>검토·타당성</strong><span>수요와 비용 확인</span></div><div class=\"timelineStep_A8qs\"><div class=\"timelineDot_mlBL\">3</div><strong>계획·설계</strong><span>노선·역·공법 구체화</span></div><div class=\"timelineStep_A8qs\"><div class=\"timelineDot_mlBL\">4</div><strong>착공</strong><span>공사가 실제로 시작</span></div><div class=\"timelineStep_A8qs\"><div class=\"timelineDot_mlBL\">5</div><strong>개통</strong><span>이용 가능한 교통</span></div></div><p class=\"note_l0U4\">발표만으로 개통 시점이나 실제 통행 편의를 확정할 수 없습니다. 단계와 공식 문서의 기준일을 함께 확인하세요.</p></figure>\n<p>국토교통부 <a href=\"https://www.data.go.kr/data/15130673/fileData.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">철도산업 사업현황 공공데이터</a>는 사업 추진 과정에서 조사·설계·고시·계획 수립·착공 등 여러 이력이 발생할 수 있음을 보여줍니다. 실제 사업마다 절차와 명칭은 다를 수 있으므로, 차트는 공통적으로 확인하기 쉬운 읽기 순서로 이해하면 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-발표-방향과-필요성을-알리는-단계\">1. 발표: 방향과 필요성을 알리는 단계<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#1-%EB%B0%9C%ED%91%9C-%EB%B0%A9%ED%96%A5%EA%B3%BC-%ED%95%84%EC%9A%94%EC%84%B1%EC%9D%84-%EC%95%8C%EB%A6%AC%EB%8A%94-%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"1. 발표: 방향과 필요성을 알리는 단계에 대한 직접 링크\" title=\"1. 발표: 방향과 필요성을 알리는 단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>발표는 사업이 중요하다는 신호지만, 노선·역 위치·사업비·개통 시점이 모두 확정됐다는 뜻은 아닙니다.</p>\n<p>이 단계에서 확인할 질문은 다음과 같습니다.</p>\n<ul>\n<li class=\"\">어떤 기관이 발표했는가</li>\n<li class=\"\">발표 자료에 사업 대상과 범위가 명확히 적혀 있는가</li>\n<li class=\"\">예산·재원·추진 주체가 함께 언급됐는가</li>\n<li class=\"\">목표 일정인지 확정 일정인지 구분되어 있는가</li>\n</ul>\n<p>기사 제목만 저장하기보다 발표 기관의 원문과 기준일을 먼저 저장하는 편이 안전합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-검토타당성-사업을-추진할-근거를-확인하는-단계\">2. 검토·타당성: 사업을 추진할 근거를 확인하는 단계<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#2-%EA%B2%80%ED%86%A0%ED%83%80%EB%8B%B9%EC%84%B1-%EC%82%AC%EC%97%85%EC%9D%84-%EC%B6%94%EC%A7%84%ED%95%A0-%EA%B7%BC%EA%B1%B0%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"2. 검토·타당성: 사업을 추진할 근거를 확인하는 단계에 대한 직접 링크\" title=\"2. 검토·타당성: 사업을 추진할 근거를 확인하는 단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>수요, 비용, 기술적 가능성, 주변 사업과의 연계 등을 검토하는 단계입니다. 검토 결과에 따라 사업 범위와 일정이 달라질 수 있습니다.</p>\n<p>아파트 가격을 읽을 때는 “검토 중”이라는 표현을 “공사가 결정됨”으로 바꾸어 쓰지 않아야 합니다. 통과 여부와 조건, 이후 계획 수립 여부를 별도로 확인해야 합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-계획설계-노선과-이용-조건이-구체화되는-단계\">3. 계획·설계: 노선과 이용 조건이 구체화되는 단계<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#3-%EA%B3%84%ED%9A%8D%EC%84%A4%EA%B3%84-%EB%85%B8%EC%84%A0%EA%B3%BC-%EC%9D%B4%EC%9A%A9-%EC%A1%B0%EA%B1%B4%EC%9D%B4-%EA%B5%AC%EC%B2%B4%ED%99%94%EB%90%98%EB%8A%94-%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"3. 계획·설계: 노선과 이용 조건이 구체화되는 단계에 대한 직접 링크\" title=\"3. 계획·설계: 노선과 이용 조건이 구체화되는 단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기본계획, 실시설계, 사업계획 승인 같은 문서가 나오면 노선·역·환승·공사 범위를 더 구체적으로 확인할 수 있습니다. 그래도 설계와 협의 과정에서 세부 내용이 바뀔 수 있습니다.</p>\n<p>이 단계에서는 단순히 “역이 생긴다”가 아니라 다음을 지도에 표시해보세요.</p>\n<ul>\n<li class=\"\">단지에서 역까지 실제 보행 동선</li>\n<li class=\"\">환승 횟수와 주요 업무지구까지의 이동 시간</li>\n<li class=\"\">역 출입구와 생활권의 위치</li>\n<li class=\"\">공사 기간 동안의 우회·소음·교통 영향</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-착공-기대와-공사가-분리되는-단계\">4. 착공: 기대와 공사가 분리되는 단계<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#4-%EC%B0%A9%EA%B3%B5-%EA%B8%B0%EB%8C%80%EC%99%80-%EA%B3%B5%EC%82%AC%EA%B0%80-%EB%B6%84%EB%A6%AC%EB%90%98%EB%8A%94-%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"4. 착공: 기대와 공사가 분리되는 단계에 대한 직접 링크\" title=\"4. 착공: 기대와 공사가 분리되는 단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>착공은 사업이 현장 단계로 넘어갔다는 강한 신호입니다. 하지만 착공했다고 바로 통행이 시작되는 것은 아닙니다. 공사 기간, 공정률, 개통 목표, 추가 공사 여부를 계속 확인해야 합니다.</p>\n<p>특히 교통 호재를 가격 차트에 반영할 때는 착공일 하나만 표시하지 말고, 착공 이후 실제 공정과 개통 일정의 변동도 별도로 기록하는 것이 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-개통-실제-통행-편의를-확인하는-단계\">5. 개통: 실제 통행 편의를 확인하는 단계<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#5-%EA%B0%9C%ED%86%B5-%EC%8B%A4%EC%A0%9C-%ED%86%B5%ED%96%89-%ED%8E%B8%EC%9D%98%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EB%8B%A8%EA%B3%84\" class=\"hash-link\" aria-label=\"5. 개통: 실제 통행 편의를 확인하는 단계에 대한 직접 링크\" title=\"5. 개통: 실제 통행 편의를 확인하는 단계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>개통은 계획이 실제 이용 가능한 교통 서비스로 바뀌는 시점입니다. 이때부터는 발표 자료가 아닌 실제 이동 시간, 배차 간격, 환승 편의, 혼잡도, 이용 요금을 확인할 수 있습니다.</p>\n<p>역이 개통되어도 모든 단지가 같은 혜택을 받는 것은 아닙니다. 도보권인지, 버스 환승이 필요한지, 출근 시간대에 실제로 편리한지에 따라 체감 편의는 달라집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"교통-호재를-아파트-가격과-연결하는-순서\">교통 호재를 아파트 가격과 연결하는 순서<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#%EA%B5%90%ED%86%B5-%ED%98%B8%EC%9E%AC%EB%A5%BC-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EA%B3%BC-%EC%97%B0%EA%B2%B0%ED%95%98%EB%8A%94-%EC%88%9C%EC%84%9C\" class=\"hash-link\" aria-label=\"교통 호재를 아파트 가격과 연결하는 순서에 대한 직접 링크\" title=\"교통 호재를 아파트 가격과 연결하는 순서에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">사업 단계와 기준일을 먼저 적습니다.</li>\n<li class=\"\">공식 문서에서 노선·역·일정을 확인합니다.</li>\n<li class=\"\">단지에서 역까지의 실제 동선을 지도에서 봅니다.</li>\n<li class=\"\">개통 전에는 기대 요인과 일정 위험을 분리합니다.</li>\n<li class=\"\">개통 후에는 실제 통행 시간과 생활 편의를 다시 확인합니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-교통-호재는-발표-착공-개통-중-어느-시점에-집값에-가장-크게-반영되나요\">Q. 교통 호재는 발표, 착공, 개통 중 어느 시점에 집값에 가장 크게 반영되나요?<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#q-%EA%B5%90%ED%86%B5-%ED%98%B8%EC%9E%AC%EB%8A%94-%EB%B0%9C%ED%91%9C-%EC%B0%A9%EA%B3%B5-%EA%B0%9C%ED%86%B5-%EC%A4%91-%EC%96%B4%EB%8A%90-%EC%8B%9C%EC%A0%90%EC%97%90-%EC%A7%91%EA%B0%92%EC%97%90-%EA%B0%80%EC%9E%A5-%ED%81%AC%EA%B2%8C-%EB%B0%98%EC%98%81%EB%90%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 교통 호재는 발표, 착공, 개통 중 어느 시점에 집값에 가장 크게 반영되나요?에 대한 직접 링크\" title=\"Q. 교통 호재는 발표, 착공, 개통 중 어느 시점에 집값에 가장 크게 반영되나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>통상적으로 초기 계획 발표 시 기대감으로 1차 선반영이 일어나고, 사업 확정 후 실제 착공 시 2차 상승, 그리고 완공 및 개통으로 실제 통행 편의가 입증될 때 3차 시세 형성이 이루어집니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-단순-계획-발표-단계의-교통-호재를-볼-때-주의할-점은-무엇인가요\">Q. 단순 계획 발표 단계의 교통 호재를 볼 때 주의할 점은 무엇인가요?<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#q-%EB%8B%A8%EC%88%9C-%EA%B3%84%ED%9A%8D-%EB%B0%9C%ED%91%9C-%EB%8B%A8%EA%B3%84%EC%9D%98-%EA%B5%90%ED%86%B5-%ED%98%B8%EC%9E%AC%EB%A5%BC-%EB%B3%BC-%EB%95%8C-%EC%A3%BC%EC%9D%98%ED%95%A0-%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 단순 계획 발표 단계의 교통 호재를 볼 때 주의할 점은 무엇인가요?에 대한 직접 링크\" title=\"Q. 단순 계획 발표 단계의 교통 호재를 볼 때 주의할 점은 무엇인가요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>발표 단계는 예비타당성조사, 재원 마련, 기본설계 등 거쳐야 할 관문이 많아 사업 지연이나 노선 변경, 무산 위험이 높으므로 목표 일정을 확정된 사실로 오해하지 말아야 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-역세권-아파트라도-개통-후-가격이-오르지-않는-경우가-있나요\">Q. 역세권 아파트라도 개통 후 가격이 오르지 않는 경우가 있나요?<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#q-%EC%97%AD%EC%84%B8%EA%B6%8C-%EC%95%84%ED%8C%8C%ED%8A%B8%EB%9D%BC%EB%8F%84-%EA%B0%9C%ED%86%B5-%ED%9B%84-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%98%A4%EB%A5%B4%EC%A7%80-%EC%95%8A%EB%8A%94-%EA%B2%BD%EC%9A%B0%EA%B0%80-%EC%9E%88%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 역세권 아파트라도 개통 후 가격이 오르지 않는 경우가 있나요?에 대한 직접 링크\" title=\"Q. 역세권 아파트라도 개통 후 가격이 오르지 않는 경우가 있나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>착공 이전 단계에서 기대감이 과도하게 선반영되어 이미 높은 시세가 형성되었거나, 배차 간격이 길고 출퇴근 핵심 업무지구로의 직결성이 떨어지는 노선일 경우 개통 후 추가 상승 폭이 제한될 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/transport-benefit-stages-apartment-price#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://www.data.go.kr/data/15130673/fileData.do\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 철도산업 사업현황 공공데이터</a>: 철도 사업의 조사·설계·고시·계획·착공 관련 이력을 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://www.molit.go.kr/2026plan/sub2_economy.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 2026년 업무계획</a>: 철도·도로 등 교통 인프라 사업의 정책 방향과 추진 계획을 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://www.molit.go.kr/2024plan_traffic/total/total_03.jsp\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">국토교통부 교통 분야 정책 자료</a>: 사업 제안·검토·계획 수립·고시 등 교통 사업 절차의 사례를 참고할 수 있습니다.</li>\n</ul>\n<p>교통 호재 하나만으로 아파트 가격이 정해지는 것은 아닙니다. 거래량, 공급, 전세 흐름, 직주근접, 생활 인프라를 함께 봐야 같은 지역 안에서 단지별 차이를 설명할 수 있습니다.</p>\n<p>아파트 가격을 현재 거래·과거 흐름·미래 범위로 나누어 읽는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">아파트 가격의 세 가지 기준</a>에서 이어집니다. 공개 분석의 기본 개념과 데이터 해석 원칙은 <a href=\"https://apt-insights.com/guides/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공식 가이드 모음</a>에서 확인할 수 있습니다.</p>\n<p>교통과 거래 흐름을 내 관심 단지에 함께 적용해보고 싶다면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공개 아파트 분석 도구</a>에서 직접 비교할 수 있습니다.</p>\n<blockquote>\n<p>교통 사업의 일정과 범위는 공식 발표·고시·설계·공사 과정에서 달라질 수 있습니다. 이 글은 특정 지역이나 단지의 가격 상승을 보장하거나 매수를 권유하지 않습니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/transport-benefit-stages-apartment-price",
            "title": "아파트 교통 호재 분석법: 발표·착공·개통 단계별 집값 반영 시점",
            "summary": "교통 호재가 아파트 가격에 반영되는 발표, 예비타당성조사, 착공, 개통 4대 핵심 단계와 단계별 집값 상승률 및 투자 유의점을 정리합니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트"
            ]
        },
        {
            "id": "https://alvin.ing/blog/mortgage-rate-apartment-price",
            "content_html": "\n<p>금리가 오르면 집값이 내리고, 금리가 내리면 집값이 오른다는 설명은 이해하기 쉽습니다. 하지만 실제 아파트 시장에서는 금리 변화와 실거래가 움직임 사이에 시간이 생깁니다.</p>\n<p>금리는 먼저 대출을 이용하는 가계의 월 부담과 구매 가능한 가격대를 바꾸고, 그 다음 거래 속도와 협상 조건을 거쳐 가격에 영향을 줍니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리에서-아파트-가격까지는-여러-단계를-거친다\">금리에서 아파트 가격까지는 여러 단계를 거친다<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#%EA%B8%88%EB%A6%AC%EC%97%90%EC%84%9C-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EA%B9%8C%EC%A7%80%EB%8A%94-%EC%97%AC%EB%9F%AC-%EB%8B%A8%EA%B3%84%EB%A5%BC-%EA%B1%B0%EC%B9%9C%EB%8B%A4\" class=\"hash-link\" aria-label=\"금리에서 아파트 가격까지는 여러 단계를 거친다에 대한 직접 링크\" title=\"금리에서 아파트 가격까지는 여러 단계를 거친다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<figure class=\"chart_ePMC\" aria-labelledby=\"rate-transmission-title\"><figcaption id=\"rate-transmission-title\">금리 변화가 아파트 가격에 닿는 경로</figcaption><div class=\"flow_ye3U\" role=\"img\" aria-label=\"대출금리 변화가 월 상환 부담, 구매 가능한 가격대, 거래 속도를 거쳐 아파트 가격에 영향을 주는 흐름\"><div class=\"flowStep_xWpY\"><div class=\"flowNumber_DZpq\">1</div><strong>대출금리 변화</strong><span>시장·정책·상품 조건</span><span class=\"flowArrow_kUQw\" aria-hidden=\"true\">→</span></div><div class=\"flowStep_xWpY\"><div class=\"flowNumber_DZpq\">2</div><strong>월 상환 부담</strong><span>같은 금액을 빌려도 달라짐</span><span class=\"flowArrow_kUQw\" aria-hidden=\"true\">→</span></div><div class=\"flowStep_xWpY\"><div class=\"flowNumber_DZpq\">3</div><strong>구매 가능한 가격대</strong><span>가계 현금흐름이 제약</span><span class=\"flowArrow_kUQw\" aria-hidden=\"true\">→</span></div><div class=\"flowStep_xWpY\"><div class=\"flowNumber_DZpq\">4</div><strong>거래의 속도</strong><span>협상·관망·실행 시점</span></div></div><div class=\"flowFootnote_uFCw\">금리 변화 → 가계 현금흐름 → 거래 조건 → 실제 가격으로 이어지는 시간차가 있습니다.</div></figure>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리별-월-상환액과-총-이자-부담-직접-비교하기\">금리별 월 상환액과 총 이자 부담 직접 비교하기<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#%EA%B8%88%EB%A6%AC%EB%B3%84-%EC%9B%94-%EC%83%81%ED%99%98%EC%95%A1%EA%B3%BC-%EC%B4%9D-%EC%9D%B4%EC%9E%90-%EB%B6%80%EB%8B%B4-%EC%A7%81%EC%A0%91-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"금리별 월 상환액과 총 이자 부담 직접 비교하기에 대한 직접 링크\" title=\"금리별 월 상환액과 총 이자 부담 직접 비교하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<div class=\"container_bPHW\"><div class=\"title_FUzC\">💡 주택담보대출 금리별 월 상환액 비교기</div><div class=\"subtitle_lFpS\">금리가 1%p 변할 때 매월 지출하는 원리금과 총 이자 부담이 얼마나 달라지는지 직접 확인해보세요. (원리금 균등상환 기준)</div><div class=\"grid_sNaf\"><div class=\"field__lMB\"><label for=\"mortgage-principal\">대출 원금</label><select id=\"mortgage-principal\" class=\"select_h7Cg\"><option value=\"3\">3억원</option><option value=\"4\">4억원</option><option value=\"5\" selected=\"\">5억원</option><option value=\"6\">6억원</option><option value=\"7\">7억원</option><option value=\"8\">8억원</option><option value=\"10\">10억원</option></select></div><div class=\"field__lMB\"><label for=\"mortgage-years\">대출 기간</label><select id=\"mortgage-years\" class=\"select_h7Cg\"><option value=\"20\">20년 (240개월)</option><option value=\"30\" selected=\"\">30년 (360개월)</option><option value=\"40\">40년 (480개월)</option></select></div><div class=\"field__lMB\"><label for=\"mortgage-rate-a\">기준 금리 (인하 전)</label><input id=\"mortgage-rate-a\" type=\"number\" step=\"0.1\" min=\"1\" max=\"15\" class=\"input_BD4_\" value=\"4.5\"></div><div class=\"field__lMB\"><label for=\"mortgage-rate-b\">비교 금리 (인하 후)</label><input id=\"mortgage-rate-b\" type=\"number\" step=\"0.1\" min=\"1\" max=\"15\" class=\"input_BD4_\" value=\"3.5\"></div></div><div class=\"resultBox_AYfG\"><div class=\"resultGrid_MyLc\"><div class=\"resultCard_SIcO\"><div class=\"cardHeader_KHfh\">기준 금리 <!-- -->4.5<!-- -->% 적용 시</div><div class=\"cardMonthly_bk39\">월 <!-- -->253만원</div><div class=\"cardSub_MCxq\">30<!-- -->년 총 이자: <!-- -->4억 1,203만원</div></div><div class=\"resultCard_SIcO\"><div class=\"cardHeader_KHfh\">비교 금리 <!-- -->3.5<!-- -->% 적용 시</div><div class=\"cardMonthly_bk39\">월 <!-- -->225만원</div><div class=\"cardSub_MCxq\">30<!-- -->년 총 이자: <!-- -->3억 828만원</div></div></div><div class=\"diffHighlight_Jp6C\"><span>금리가 <strong>1.0<!-- -->%p</strong> 낮아지면:</span><span>매달 <strong>29만원</strong> 절감 (<!-- -->30<!-- -->년 누적 총 <strong>1억 375만원</strong> 절약)</span></div><p class=\"footnote_dcFD\">* 거치기간 없는 원리금균등분할상환 기준 단순 계산이며, 실제 은행 대출 취급 시 중도상환수수료, 우대금리 조건, 거치 여부 등에 따라 달라질 수 있습니다.</p></div></div>\n<p>이 흐름은 모든 지역과 모든 가구에 같은 크기로 적용되는 공식이 아닙니다. 기존 대출의 고정·변동 여부, 대출 만기, 소득, 보유 현금, 전세 상황에 따라 체감 부담이 달라집니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-시장-금리와-내-적용-금리는-다르다\">1. 시장 금리와 내 적용 금리는 다르다<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#1-%EC%8B%9C%EC%9E%A5-%EA%B8%88%EB%A6%AC%EC%99%80-%EB%82%B4-%EC%A0%81%EC%9A%A9-%EA%B8%88%EB%A6%AC%EB%8A%94-%EB%8B%A4%EB%A5%B4%EB%8B%A4\" class=\"hash-link\" aria-label=\"1. 시장 금리와 내 적용 금리는 다르다에 대한 직접 링크\" title=\"1. 시장 금리와 내 적용 금리는 다르다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>한국은행 <a href=\"https://snapshot.bok.or.kr/dashboard/A/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">금융·경제 스냅샷</a>과 <a href=\"https://ecos.bok.or.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">경제통계시스템</a>에서 확인하는 대출금리는 여러 금융기관의 평균을 보여주는 통계입니다.</p>\n<p>이 평균은 시장의 방향을 읽는 데 유용하지만, 개인이 실제로 적용받는 금리와는 다를 수 있습니다. 신용 조건, 담보 가치, 대출 기간, 고정·변동 선택, 우대 조건에 따라 달라지기 때문입니다.</p>\n<p>따라서 기사를 읽을 때는 “평균 금리가 몇 퍼센트인가”에서 멈추지 말고 다음 두 값을 분리해야 합니다.</p>\n<ul>\n<li class=\"\">시장을 읽는 참고 금리</li>\n<li class=\"\">내 대출 계약에 실제 적용되는 금리</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-월-상환-부담이-먼저-바뀐다\">2. 월 상환 부담이 먼저 바뀐다<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#2-%EC%9B%94-%EC%83%81%ED%99%98-%EB%B6%80%EB%8B%B4%EC%9D%B4-%EB%A8%BC%EC%A0%80-%EB%B0%94%EB%80%90%EB%8B%A4\" class=\"hash-link\" aria-label=\"2. 월 상환 부담이 먼저 바뀐다에 대한 직접 링크\" title=\"2. 월 상환 부담이 먼저 바뀐다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>같은 금액을 빌려도 금리와 만기가 바뀌면 월 납입액과 전체 이자 부담이 달라집니다. 원리금균등상환인지, 원금균등상환인지, 만기일시상환인지에 따라서도 현금흐름은 달라집니다.</p>\n<p>그래서 아파트 가격을 금리와 연결할 때는 “금리 1%포인트 변화 = 집값 몇 퍼센트 변화”처럼 바로 환산하기보다 다음 순서가 현실적입니다.</p>\n<ol>\n<li class=\"\">대출 잔액과 남은 기간 확인</li>\n<li class=\"\">고정·변동 여부 확인</li>\n<li class=\"\">월 상환액이 소득과 생활비에서 차지하는 비중 확인</li>\n<li class=\"\">금리가 바뀌어도 유지할 수 있는 현금흐름인지 확인</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-구매-가능한-가격대가-달라진다\">3. 구매 가능한 가격대가 달라진다<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#3-%EA%B5%AC%EB%A7%A4-%EA%B0%80%EB%8A%A5%ED%95%9C-%EA%B0%80%EA%B2%A9%EB%8C%80%EA%B0%80-%EB%8B%AC%EB%9D%BC%EC%A7%84%EB%8B%A4\" class=\"hash-link\" aria-label=\"3. 구매 가능한 가격대가 달라진다에 대한 직접 링크\" title=\"3. 구매 가능한 가격대가 달라진다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>월 상환 부담이 커지면 같은 소득을 가진 가구가 감당할 수 있는 대출 규모가 줄어들 수 있습니다. 반대로 부담이 줄면 더 높은 가격대까지 검토할 여지가 생깁니다.</p>\n<p>하지만 이것이 곧바로 모든 아파트 가격의 등락으로 이어지지는 않습니다. 지역별 공급, 전세 가격, 보유자의 매도 필요성, 현금 구매자 비중이 함께 작용하기 때문입니다.</p>\n<p>금리 기사를 아파트 시세에 연결할 때는 지역별 거래량과 거래 간격을 같이 보는 것이 좋습니다. 가격이 유지되어 보여도 거래가 크게 줄었다면 시장의 조정이 거래량과 협상 과정에서 먼저 나타났을 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-가격보다-거래-속도와-협상력이-먼저-움직일-수-있다\">4. 가격보다 거래 속도와 협상력이 먼저 움직일 수 있다<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#4-%EA%B0%80%EA%B2%A9%EB%B3%B4%EB%8B%A4-%EA%B1%B0%EB%9E%98-%EC%86%8D%EB%8F%84%EC%99%80-%ED%98%91%EC%83%81%EB%A0%A5%EC%9D%B4-%EB%A8%BC%EC%A0%80-%EC%9B%80%EC%A7%81%EC%9D%BC-%EC%88%98-%EC%9E%88%EB%8B%A4\" class=\"hash-link\" aria-label=\"4. 가격보다 거래 속도와 협상력이 먼저 움직일 수 있다에 대한 직접 링크\" title=\"4. 가격보다 거래 속도와 협상력이 먼저 움직일 수 있다에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>금리 변화 직후에 모든 계약 가격이 같은 방향으로 이동하지는 않습니다. 먼저 매수자는 관망하고, 매도자는 가격을 유지하려 하며, 실제 계약까지 걸리는 시간이 길어질 수 있습니다.</p>\n<p>이때 확인할 지표는 다음과 같습니다.</p>\n<ul>\n<li class=\"\">월별 거래 건수</li>\n<li class=\"\">최근 거래 사이의 간격</li>\n<li class=\"\">같은 면적의 거래가 반복되는지 여부</li>\n<li class=\"\">호가와 실제 계약 가격의 차이</li>\n<li class=\"\">전세 가격과 매매 가격의 동반 움직임</li>\n</ul>\n<p>가격만 보면 변화가 늦게 보일 수 있으므로, 거래량과 거래 간격을 함께 차트에 그리는 편이 좋습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"금리와-아파트-가격을-함께-읽는-체크리스트\">금리와 아파트 가격을 함께 읽는 체크리스트<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#%EA%B8%88%EB%A6%AC%EC%99%80-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EC%9D%84-%ED%95%A8%EA%BB%98-%EC%9D%BD%EB%8A%94-%EC%B2%B4%ED%81%AC%EB%A6%AC%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"금리와 아파트 가격을 함께 읽는 체크리스트에 대한 직접 링크\" title=\"금리와 아파트 가격을 함께 읽는 체크리스트에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>질문</th><th>확인할 자료</th><th>해석의 주의점</th></tr></thead><tbody><tr><td>금리가 변했나</td><td>한국은행 평균 금리·기준금리</td><td>개인 적용 금리와 다름</td></tr><tr><td>내 부담이 변했나</td><td>대출 잔액·만기·상환 방식</td><td>가구별 차이가 큼</td></tr><tr><td>거래가 반응했나</td><td>거래량·거래 간격</td><td>가격보다 먼저 움직일 수 있음</td></tr><tr><td>가격이 반응했나</td><td>같은 면적·층의 실거래</td><td>표본이 적으면 과대해석 위험</td></tr><tr><td>다른 조건은 같은가</td><td>공급·전세·정책·지역 수요</td><td>금리 하나로 설명하지 않기</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"자주-묻는-질문-faq\">자주 묻는 질문 (FAQ)<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8-faq\" class=\"hash-link\" aria-label=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" title=\"자주 묻는 질문 (FAQ)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-기준금리가-인하되면-아파트-가격은-바로-반등하나요\">Q. 기준금리가 인하되면 아파트 가격은 바로 반등하나요?<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#q-%EA%B8%B0%EC%A4%80%EA%B8%88%EB%A6%AC%EA%B0%80-%EC%9D%B8%ED%95%98%EB%90%98%EB%A9%B4-%EC%95%84%ED%8C%8C%ED%8A%B8-%EA%B0%80%EA%B2%A9%EC%9D%80-%EB%B0%94%EB%A1%9C-%EB%B0%98%EB%93%B1%ED%95%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 기준금리가 인하되면 아파트 가격은 바로 반등하나요?에 대한 직접 링크\" title=\"Q. 기준금리가 인하되면 아파트 가격은 바로 반등하나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>기준금리가 인하되더라도 은행의 대출 가산금리 정책, 스트레스 DSR 규제 강화, 기존 주택 매물 소화 과정 등을 거치므로 시장 가격에 반영되기까지는 보통 3개월에서 6개월 이상의 시차가 발생합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-주택담보대출-금리가-1p-변할-때-월-상환액-부담은-얼마나-차이-나나요\">Q. 주택담보대출 금리가 1%p 변할 때 월 상환액 부담은 얼마나 차이 나나요?<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#q-%EC%A3%BC%ED%83%9D%EB%8B%B4%EB%B3%B4%EB%8C%80%EC%B6%9C-%EA%B8%88%EB%A6%AC%EA%B0%80-1p-%EB%B3%80%ED%95%A0-%EB%95%8C-%EC%9B%94-%EC%83%81%ED%99%98%EC%95%A1-%EB%B6%80%EB%8B%B4%EC%9D%80-%EC%96%BC%EB%A7%88%EB%82%98-%EC%B0%A8%EC%9D%B4-%EB%82%98%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 주택담보대출 금리가 1%p 변할 때 월 상환액 부담은 얼마나 차이 나나요?에 대한 직접 링크\" title=\"Q. 주택담보대출 금리가 1%p 변할 때 월 상환액 부담은 얼마나 차이 나나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>대출 5억원 30년 만기 원리금 균등상환 기준, 금리가 1%p(예: 4.5%에서 3.5%) 낮아지면 매달 납부하는 원리금이 약 29만원 줄어들며, 30년간 누적 총 이자는 1억원 이상 절약됩니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"q-스트레스-dsr이란-무엇이며-대출-한도에-어떤-영향을-주나요\">Q. 스트레스 DSR이란 무엇이며 대출 한도에 어떤 영향을 주나요?<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#q-%EC%8A%A4%ED%8A%B8%EB%A0%88%EC%8A%A4-dsr%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EB%8C%80%EC%B6%9C-%ED%95%9C%EB%8F%84%EC%97%90-%EC%96%B4%EB%96%A4-%EC%98%81%ED%96%A5%EC%9D%84-%EC%A3%BC%EB%82%98%EC%9A%94\" class=\"hash-link\" aria-label=\"Q. 스트레스 DSR이란 무엇이며 대출 한도에 어떤 영향을 주나요?에 대한 직접 링크\" title=\"Q. 스트레스 DSR이란 무엇이며 대출 한도에 어떤 영향을 주나요?에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>향후 잠재적 금리 인상 위험을 감안해 실제 대출 금리에 가산금리(스트레스 금리)를 얹어 연간 원리금 상환액을 산정하는 규제입니다. 금리 자체가 오르지 않아도 계산상 상환 부담이 커져 실제 빌릴 수 있는 총 대출 한도가 축소됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-자료\">참고 자료<a href=\"https://alvin.ing/blog/mortgage-rate-apartment-price#%EC%B0%B8%EA%B3%A0-%EC%9E%90%EB%A3%8C\" class=\"hash-link\" aria-label=\"참고 자료에 대한 직접 링크\" title=\"참고 자료에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://snapshot.bok.or.kr/dashboard/A/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국은행 금융·경제 스냅샷</a>: 금리와 금융시장 관련 주요 지표를 한 화면에서 확인할 수 있습니다.</li>\n<li class=\"\"><a href=\"https://ecos.bok.or.kr/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국은행 경제통계시스템 ECOS</a>: 대출금리와 거시경제 통계를 직접 조회할 수 있는 공식 통계 시스템입니다.</li>\n<li class=\"\"><a href=\"https://www.bok.or.kr/imer/bbs/P0002455/view.do?menuNo=500788&amp;nttId=10096001\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">한국은행 경제연구원 주택담보대출 차입자의 금리 선택 분석</a>: 고정·변동금리 선택과 가계 금융 부담의 관계를 살펴본 연구자료입니다.</li>\n</ul>\n<p>금리와 가격을 기간별로 비교하는 방법은 <a class=\"\" href=\"https://alvin.ing/blog/apartment-price-current-history-forecast\">현재 거래가·과거 이력·예상 범위를 나눠 보는 글</a>에서 이어서 확인할 수 있습니다. 금리 조건을 바꿨을 때 가능한 가격 경로를 어떻게 읽는지는 <a href=\"https://apt-insights.com/guides/apartment-price-forecast\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공식 가이드의 미래가격 예측 설명</a>도 참고할 만합니다.</p>\n<p>내 관심 단지의 최근 거래와 금리 조건을 함께 놓고 비교해보고 싶다면 <a href=\"https://app.apt-insights.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">공개 아파트 분석 도구</a>에서 확인할 수 있습니다.</p>\n<blockquote>\n<p>금리와 주택 가격의 관계는 지역·가구·대출 상품·공급 조건에 따라 달라집니다. 이 글은 금융상품 가입이나 대출 실행을 권유하지 않으며, 최종 판단 전 금융기관의 최신 조건을 확인해야 합니다.</p>\n</blockquote>",
            "url": "https://alvin.ing/blog/mortgage-rate-apartment-price",
            "title": "주택담보대출 금리와 아파트 가격의 상관관계: 금리 인하가 집값에 미치는 영향",
            "summary": "주택담보대출 금리가 아파트 가격에 바로 반영되지 않는 이유와 금리 변화에 따른 월 상환 부담, 구매 가능 가격대, 거래 흐름을 계산기와 함께 살펴봅니다.",
            "date_modified": "2026-08-06T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "부동산",
                "아파트",
                "금융·세금"
            ]
        },
        {
            "id": "https://alvin.ing/blog/introduction-to-flutter",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"플러터란\">플러터란?<a href=\"https://alvin.ing/blog/introduction-to-flutter#%ED%94%8C%EB%9F%AC%ED%84%B0%EB%9E%80\" class=\"hash-link\" aria-label=\"플러터란?에 대한 직접 링크\" title=\"플러터란?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>플러터는 구글이 출시한 오픈소스 크로스플랫폼 GUI 애플리케이션 프레임워크입니다. 안드로이드, iOS, 윈도우즈, 리눅스 및 웹 애플리케이션과 구글 퓨시아 앱의 주된 소스코드로 사용됩니다. 2.0 버전부터 웹 애플리케이션을 지원했으며, 3.0 버전에서는 맥OS와 윈도우즈 애플리케이션도 지원하게 되었습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"플러터-기반의-대표적인-서비스\">플러터 기반의 대표적인 서비스<a href=\"https://alvin.ing/blog/introduction-to-flutter#%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B8%B0%EB%B0%98%EC%9D%98-%EB%8C%80%ED%91%9C%EC%A0%81%EC%9D%B8-%EC%84%9C%EB%B9%84%EC%8A%A4\" class=\"hash-link\" aria-label=\"플러터 기반의 대표적인 서비스에 대한 직접 링크\" title=\"플러터 기반의 대표적인 서비스에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>우리가 알만한 몇 가지 서비스를 소개하겠습니다. 플러터 공식 홈페이지에서 제공되는 각 서비스의 성공 지표는 다음과 같습니다. 네이버 지식iN에 대한 설명은 다음 장에서 계속됩니다.</p>\n<ul>\n<li class=\"\">네이버 지식iN</li>\n<li class=\"\">구글 페이<!-- -->\n<ul>\n<li class=\"\">엔지니어의 노력 70% 감소, 코드 라인 수 35% 감소</li>\n</ul>\n</li>\n<li class=\"\">텐센트<!-- -->\n<ul>\n<li class=\"\">개발 시간이 33% 감소, 앱 코드에서 플러터의 비중은 90%</li>\n</ul>\n</li>\n<li class=\"\">eBay 모터스<!-- -->\n<ul>\n<li class=\"\">네이티브보다 개발 속도가 2배 빠르다고 생각하는 개발자 비중이 70%</li>\n</ul>\n</li>\n<li class=\"\">BMW</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"플러터-구조-및-동작-원리\">플러터 구조 및 동작 원리<a href=\"https://alvin.ing/blog/introduction-to-flutter#%ED%94%8C%EB%9F%AC%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC\" class=\"hash-link\" aria-label=\"플러터 구조 및 동작 원리에 대한 직접 링크\" title=\"플러터 구조 및 동작 원리에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>플러터는 세 가지 계층으로 구성됩니다. 하드웨어와 직접 통신하는 임베더 계층, C++로 작성된 엔진 계층, 그리고 개발자들이 주로 사용하는 프레임워크 계층입니다. 임베더 계층은 6개 플랫폼의 네이티브 플랫폼과 통신하며 운영체제 기능을 모듈화합니다. 엔진 계층은 플러터 코어 API, 스키아 그래픽 엔진, 파일 시스템, 네트워크 기능 등을 정의합니다.</p>\n<p>프레임워크 계층에는 플러터를 사용하는 데 필수적인 위젯, 애니메이션, 매터리얼 디자인 패키지, 쿠퍼티노 디자인 패키지 등이 포함됩니다. 이렇게 세 가지 계층으로 나뉘고 잘 모듈화된 아키텍처 덕분에 플러터는 다양한 플랫폼을 쉽게 지원하며, 일관된 API 및 개발 경험을 제공합니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-1\" src=\"https://alvin.ing/assets/images/1-8b1bfbc8d340ba17d5f999fb271bfcc4.png\" width=\"1538\" height=\"1264\" class=\"img_ev3q\"></p>\n<p>플러터는 스키아 엔진을 지원하는 모든 플랫폼에서 실행될 수 있도록 구현됩니다. 플러터 팀은 iOS와 안드로이드 앱뿐만 아니라 윈도우, 리눅스, 맥OS 애플리케이션, 심지어 웹사이트까지 플러터 코드로 배포할 수 있도록 했습니다. 플러터를 사용하면 한 번에 6가지 플랫폼에 애플리케이션을 배포할 수 있습니다.</p>\n<p>플러터가 스키아 엔진을 사용할 때의 장점은 무엇일까요? 대부분의 크로스플랫폼 앱 개발 프레임워크들은 웹뷰를 사용하거나 각 플랫폼의 UI 라이브러리를 사용합니다. 하지만 플러터는 웹뷰를 사용하지 않고 직접 스키아 엔진을 이용하여 화면에 UI를 그립니다.</p>\n<blockquote>\n<p>기존의 플랫폼에서 제공되는 UI를 모두 버리고 자체적으로 UI를 렌더링하기 때문에 iOS에서 매터리얼 디자인과 ripple 애니메이션을 볼 수 있고, 안드로이드에서 쿠퍼티노 디자인을 사용할 수 있습니다.</p>\n<p>플러터는 화면 전체를 2D 그래픽 API로 fillRect하고, drawText와 drawImage를 사용하여 앱을 만드는 것과 같은 방식으로 스키아 기반으로 렌더링해줍니다. 이는 웹 개발에서 HTML을 모두 무시하고 전체를 플래시나 캔버스로 만드는 것과 유사합니다.</p>\n</blockquote>\n<p>예를 들어, 플러터의 대표적인 경쟁 프레임워크인 리액트 네이티브는 자바스크립트 브릿지를 통해 플랫폼과 통신합니다. 또한 플랫폼의 UI(OEM 위젯)를 그대로 사용합니다. 그래서 플랫폼과 리액트 네이티브 간의 통신에는 상당한 리소스 비용이 듭니다. 하지만 플러터는 위젯을 스키아 엔진에 직접 그려내고 필요한 제스처 및 이벤트를 브릿지를 통하지 않고 실행하기 때문에 리액트 네이티브에 비해 상당히 빠른 성능을 자랑합니다.</p>\n<p>참고로 플러터 팀은 초당 60프레임을 목표로 많은 노력을 기울인다고 합니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-2\" src=\"https://alvin.ing/assets/images/2-7eca7ff3dc9d2eed32ecda3a6995fec9.png\" width=\"1506\" height=\"1318\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"다트-언어를-채택한-이유\">다트 언어를 채택한 이유<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EB%8B%A4%ED%8A%B8-%EC%96%B8%EC%96%B4%EB%A5%BC-%EC%B1%84%ED%83%9D%ED%95%9C-%EC%9D%B4%EC%9C%A0\" class=\"hash-link\" aria-label=\"다트 언어를 채택한 이유에 대한 직접 링크\" title=\"다트 언어를 채택한 이유에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다트는 2011년에 구글이 개발한 클라이언트-사이드 개발 언어입니다. 처음에는 자바스크립트를 대체하기 위한 언어로 소개되었으며, 실제로 처음 제공한 트랜스 컴파일 결과물도 자바스크립트였습니다. 다트는 JIT(Just-In-Time) 컴파일을 통해 VM 위에서 동작하는 방식과 AOT(Ahead-Of-Time) 컴파일을 통해 런타임에서 바로 동작하는 방식을 모두 지원합니다.</p>\n<p>JIT 컴파일은 인터프리터처럼 실행 전에 코드를 컴파일하지 않아도 되기 때문에, 코드 수정 시 발생하는 빌드 시간을 줄여 개발자들이 더 편리하게 개발할 수 있는 장점이 있습니다. 그러나 VM 위에서 동작하기 때문에 대부분의 코드가 네이티브 플랫폼에 비해 성능상 느리다는 단점이 있습니다. 그러나 다트는 AOT 컴파일도 지원하기 때문에 실제 배포 시 AOT 컴파일을 통해 런타임에서 바로 동작하는 코드를 생성할 수 있습니다.</p>\n<blockquote>\n<p>AOT 컴파일은 다트 2버전이 나오면서 추가된 기능인데, 아마도 플러터 팀의 요청이 있었을 것이라고 생각합니다.</p>\n</blockquote>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-3\" src=\"https://alvin.ing/assets/images/3-90d9e6690c5aee821bb2df6facd3b393.png\" width=\"1280\" height=\"635\" class=\"img_ev3q\"></p>\n<p>혹시 다른 언어도 다트처럼 JIT와 AOT 컴파일러를 둘다 사용하는지 궁금해서 검색을 해봤는데, 다트처럼 개발 단계와 릴리즈 단계에서 각각 다른 컴파일 방식을 사용하는 언어는 없었습니다.</p>\n<ol>\n<li class=\"\"><strong>C# / .NET</strong>: .NET Core와 .NET 프레임워크는 JIT 컴파일을 기본으로 하지만, .NET Native나 AOT 컴파일 옵션을 통해 AOT 컴파일도 가능합니다.</li>\n<li class=\"\"><strong>Dart</strong>: Dart 언어는 플러터에서 주로 사용되며, AOT와 JIT 둘 다 지원합니다. 개발 중에는 JIT 컴파일을 사용하여 빠른 개발 사이클을 유지하고, 릴리즈 시에는 AOT 컴파일을 사용하여 최적의 성능을 달성합니다.</li>\n<li class=\"\"><strong>JavaScript / TypeScript</strong>: 일반적으로 자바스크립트는 인터프리터 언어로 분류되며, JIT 컴파일이 많이 사용됩니다. 그러나 웹 어셈플리를 통해 AOT 컴파일도 가능합니다.</li>\n<li class=\"\"><strong>Rust</strong>: 러스트는 기본적으로 AOT 컴파일을 사용하지만, JIT 컴파일을 가능하게 하는 라이브러리도 존재합니다.</li>\n<li class=\"\"><strong>Go</strong>: Go 언어는 주로 AOT 컴파일을 사용하지만, 몇몇 특별한 상황에서는 JIT 컴파일을 사용하는 경우도 있습니다.</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"hot-reload\">hot reload<a href=\"https://alvin.ing/blog/introduction-to-flutter#hot-reload\" class=\"hash-link\" aria-label=\"hot reload에 대한 직접 링크\" title=\"hot reload에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>플러터의 hot reload를 사용하면 개발 시간을 단축시키고 거의 즉시에 가까운 속도로 개발할 수 있습니다. 이 기능은 다트의 JIT 컴파일을 기반으로 하며, 다트가 JIT 컴파일을 지원하기 때문에 앱을 즉시 수정하고 실행할 수 있습니다.</p>\n<blockquote>\n<p>제니퍼 화면 개발 중 웹팩 번들러에서 제공하는 hot reload를 사용합니다. 수정된 코드가 빌드되고 브라우저에 반영되는 과정에는 몇 초의 시간이 소요되어 답답한 경우가 종종 있습니다. 이는 제니퍼의 소스 코드 규모가 방대하고 웹팩을 그대로 사용하기 때문에 발생하는 현상일 수 있습니다. 물론 최근 Vercel에서 발표한 터보팩과 같은 번들러는 더 빠를 수도 있습니다.</p>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"네이버의-플러터-도입-과정\">네이버의 플러터 도입 과정<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EB%84%A4%EC%9D%B4%EB%B2%84%EC%9D%98-%ED%94%8C%EB%9F%AC%ED%84%B0-%EB%8F%84%EC%9E%85-%EA%B3%BC%EC%A0%95\" class=\"hash-link\" aria-label=\"네이버의 플러터 도입 과정에 대한 직접 링크\" title=\"네이버의 플러터 도입 과정에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>최근에 데이빗과 플러터 스터디를 진행하면서 모니터링 스터디 주제로 선정해야겠다는 생각을 했었습니다. 관련해서 검색해보는데, <a href=\"https://d2.naver.com/helloworld/3384599\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">네이버의 플러터 도입 과정</a>을 블로그에 자세히 올린게 있어서 개인적으로 느낀 점이 많아 이렇게 소개해보려고 합니다.</p>\n<p>먼저, 크로스플랫폼 도입을 검토하게 된 이유가 흥미로웠습니다. 네이버 정도되는 규모의 회사에서는 서비스 앱 개발을 어떤 프로세스로 진행하는지 어느 정도 파악할 수 있었습니다. 특히 디자인 단계에서의 어려움은 iOS와 안드로이드에서 모두 동일한 UI를 제공하려고 하더라도 구현하기 어려운 UI가 존재한다는 것이었습니다.</p>\n<p>각 플랫폼마다 개발, 테스트, 배포를 진행하며, 플랫폼 상황에 따라 배포 일정이 달라질 수 있고, 서비스 상황에 따라 개발자 불균형 문제가 발생할 수 있다는 점입니다. 또한, 기획을 제외하고 디자인부터 별도의 프로세스로 진행되는 것이 인상 깊었습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-4\" src=\"https://alvin.ing/assets/images/4-2eecf96a14d7023c7eb1973835429a36.png\" width=\"928\" height=\"366\" class=\"img_ev3q\"></p>\n<p>이와 같은 상황에서 최대한 개발 효율성을 높이고자 다양한 방법을 시도했는데, 과거 네이버 블로그 앱 개발팀에 있던 시절에는 아래와 같은 방법을 시도했다고 말합니다.</p>\n<ul>\n<li class=\"\">기술 공유</li>\n<li class=\"\">네이밍 컨벤션 맞추기</li>\n<li class=\"\">라이브러리 개발</li>\n</ul>\n<p>기술 공유의 경우에는 서로 다른 플랫폼 간에 도움을 주는 지식이 아니기 때문에 시간이 흐를수록 꾸준한 참여를 유지하기 어려웠으며, 플랫폼 별로 선호하는 네이밍 컨벤션이 다르고 개발 일정에 따라 매번 컨벤션을 맞추기 어렵다는 한계가 있었습니다.</p>\n<p>또한, 팀 내에서 라이브러리 개발을 담당하는 인원이 필요하다는 문제가 있었고, 꾸준한 관리가 어려워서 서비스 별로 다른 스펙을 라이브러리로 구현하기도 어렵다는 문제도 있습니다.</p>\n<p>다음은 플랫폼의 차이와 관련하여 비슷한 경험이 있는지 사내 모바일 개발자를 대상으로 설문 조사를 진행하여 다음과 같은 결과를 얻었습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-5\" src=\"https://alvin.ing/assets/images/5-de2146e3f3c93405f47f0da3cda50173.png\" width=\"1092\" height=\"854\" class=\"img_ev3q\"></p>\n<p>대다수 개발자들은 플랫폼에 특화된 스펙을 구현하는 것이 어려웠고, 개발자 불균형으로 인해 프로젝트 진행에 문제가 있었다는 것을 알 수 있습니다. 또한, 서비스 상황에 따라 크로스플랫폼이 필요하다고 생각하는 비율도 월등히 높았다고 언급합니다.</p>\n<p>결국 네이버는 프로토타입 프로젝트도 진행해 보고, 개발자 불균형 문제를 겪으면서 더 효율적인 개발 방법은 없을까 고민한 결과, 팀에서 크로스플랫폼을 검토하기로 결정했습니다. 대부분의 팀원들은 크로스플랫폼에 대해 회의적인 시각을 가졌으며, 네이티브 방식으로 개발한 앱보다 실행 성능이 낮을 것으로 예상하여 검토를 시작했다고 합니다. 하지만 검토를 진행하면서 이 부분이 편견이었음을 알았으며, 지식iN 앱을 플러터 기반으로 개발하고 정식 서비스를 시작했습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"크로스플랫폼에-도전\">크로스플랫폼에 도전<a href=\"https://alvin.ing/blog/introduction-to-flutter#%ED%81%AC%EB%A1%9C%EC%8A%A4%ED%94%8C%EB%9E%AB%ED%8F%BC%EC%97%90-%EB%8F%84%EC%A0%84\" class=\"hash-link\" aria-label=\"크로스플랫폼에 도전에 대한 직접 링크\" title=\"크로스플랫폼에 도전에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>1차 테스트로 일주일 동안 6명의 개발자가 플러터, 리액트 네이티브, 자마린(xamarin), SCADE 4개의 크로스플랫폼에 대한 성능과 생산성을 검토했습니다. 크로스플랫폼 도입을 위한 과정이 체계적이고, 많은 노력을 기울였기 때문에 크로스플랫폼 도입을 검토하는 사람들에게 많은 도움이 될 것으로 생각합니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"table-1\" src=\"https://alvin.ing/assets/images/table-1-69a59aea7f6f50973960bdc11cfb8a11.png\" width=\"1410\" height=\"968\" class=\"img_ev3q\"></p>\n<p>평가 기준을 바탕으로 각 플랫폼을 비교한 결과, 플러터가 가장 좋은 평가를 받았습니다. 특히, 플러터의 성능은 팀에서 기대한 것보다 훨씬 우수하게 나왔습니다. 화면 동작에서는 네이티브 방식과 구분하기 어려울 정도의 성능을 보였다고 합니다.</p>\n<p>네이버에서는 추가적인 검증을 위해 2차 테스트를 진행했는데, 플러터로 어떤 단계까지 구현이 가능한지 확인하기 위해 조금 더 난이도가 있는 앱을 과제로 삼았습니다. 약 2개월 동안 진행된 프로토타입 서비스를 플러터로 구현하기로 하고, iOS 개발자 4명과 안드로이드 개발자 3명이 약 2주 동안 테스트를 진행했습니다.</p>\n<p>추가 기능을 테스트하기 위해 라이브러리, Google 지도, 웹뷰, 커스텀 UI 등을 구현하여 확인한 결과, iOS 개발자 6명과 안드로이드 개발자 6명이 2개월 동안 개발한 서비스를 2주 만에 유사하게 구현했습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"table-2\" src=\"https://alvin.ing/assets/images/table-2-aa7e5e08ee19e04e93017595f3211e0c.png\" width=\"1410\" height=\"262\" class=\"img_ev3q\"></p>\n<p>팀원들의 공통적인 의견은 각각 네이티브 방식으로 개발할 때보다 훨씬 수월했다는 점입니다. 사용성 확인을 위해 UI에 굉장히 집중한 프로토타입 서비스에서는 플러터가 네이티브 방식보다 훨씬 빠르고 편하게 UI를 구현할 수 있기 때문입니다. 특히 안드로이드 개발자들의 만족도가 높았다고 합니다.</p>\n<p>다음은 2차 테스트를 마무리하고, 팀원들이 작성한 플러터에 대한 피드백을 요약한 내용입니다. 내용을 가볍게 살펴보시면 좋을 것 같습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"table-3\" src=\"https://alvin.ing/assets/images/table-3-c46dc28450976f8a6b82b3a6a9d1f03a.png\" width=\"1406\" height=\"1780\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"플러터-스터디를-하면서-느낀점\">플러터 스터디를 하면서 느낀점<a href=\"https://alvin.ing/blog/introduction-to-flutter#%ED%94%8C%EB%9F%AC%ED%84%B0-%EC%8A%A4%ED%84%B0%EB%94%94%EB%A5%BC-%ED%95%98%EB%A9%B4%EC%84%9C-%EB%8A%90%EB%82%80%EC%A0%90\" class=\"hash-link\" aria-label=\"플러터 스터디를 하면서 느낀점에 대한 직접 링크\" title=\"플러터 스터디를 하면서 느낀점에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>다트 문법이 자바나 코틀린이랑 비슷하기 때문에 플러터 개발은 고대(?) 유물인 자바 스윙이 떠오르긴 했었는데, 전혀 아니었습니다. 네이버 팀에서 플러터로 개발할 때 개발 기간이 짧아진 이유에 대해 다트 언어의 어렵지 않은 문법과 플러터의 선언형 UI 방식 때문이라고 결론을 내렸는데, 제 생각도 동일합니다.</p>\n<p>선언형 UI 방식은 복잡한 UI를 작성할 때 이해하기에 더 직관적이기 때문에 유리합니다. 사실, 프론트엔드 개발자라면 익숙한 HTML이나 JSX, 뷰 템플릿 문법들은 모두 선언형으로 볼 수 있습니다.</p>\n<p>아래 코드를 비교하면 명령형과 선언형의 차이를 쉽게 이해할 수 있습니다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// Imperative style</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">b</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">setColor</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">red</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">b</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">clearChildren</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token maybe-class-name\">ViewC</span><span class=\"token plain\"> c3 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">ViewC</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">b</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">add</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">c3</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><br></div></code></pre></div></div>\n<p>Win32에서 웹, Android 및 iOS에 이르는 프레임워크는 일반적으로 명령형 UI 프로그래밍 스타일을 사용합니다. 이 스타일은 여러분이 가장 익숙한 스타일일 수 있는데, UIView 또는 이와 동등한 기능을 갖춘 UI 엔티티를 수동으로 구성하고 나중에 UI가 변경되면 메서드와 설정자를 사용하여 변경하는 방식입니다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// Declarative style</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:#d73a49\">ViewB</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">color</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> red</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">child</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token function maybe-class-name\" style=\"color:#d73a49\">ViewC</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>반면, 플러터는 개발자가 다양한 UI 상태 간 전환 방법을 프로그래밍해야 하는 부담을 덜어주기 위해 개발자가 현재 UI 상태를 설명하고 전환은 프레임워크에 맡길 수 있도록 합니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"개발자-도구\">개발자 도구<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%8F%84%EA%B5%AC\" class=\"hash-link\" aria-label=\"개발자 도구에 대한 직접 링크\" title=\"개발자 도구에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>플러터 2.0부터 개발자 도구가 지원되었는데, 직접 사용해보니 매우 편리했습니다. 앞에서 언급한 hot reload와 함께 개발자 도구는 개발 생산성을 크게 향상시킬 것으로 기대됩니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-6\" src=\"https://alvin.ing/assets/images/6-70e785d8777ec635d34a171836f73288.gif\" width=\"1200\" height=\"795\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"예제-소개\">예제 소개<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EC%98%88%EC%A0%9C-%EC%86%8C%EA%B0%9C\" class=\"hash-link\" aria-label=\"예제 소개에 대한 직접 링크\" title=\"예제 소개에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저, 웹툰 예제는 노마드코더의 클론 코딩 강의에서 다룬 내용을 따라서 구현한 것입니다. 플러터는 네이티브 앱 수준의 페이지 전환 효과를 쉽게 구현할 수 있도록 관련 API를 제공합니다. 강의 댓글 중에서 흥미로운 내용을 발견했는데, 리액트 네이티브로 동일한 기능을 구현하는 것은 매우 어렵다며, 플러터로는 정말 간단하게 구현할 수 있다는 점이 좋았다는 것이었습니다.</p>\n<p>플러터는 iOS의 쿠퍼티노 디자인 패키지를 지원하지만 네이티브 앱만큼 완벽하지는 않습니다. 시간이 지남에 따라 네이티브 앱과의 디자인 격차는 더 벌어질 것으로 예상됩니다. 필요에 따라 플러터의 디자인 패키지에서 제공하지 않는 UI를 개발해야 할 수도 있습니다. 이런 경우, 개발자는 CustomPainter 클래스를 상속받아 직접 캔버스에 그릴 수 있습니다.</p>\n<p>이렇게 구현한 클래스는 결국 플러터에서 제공되는 위젯들과 동일한 위젯으로 취급되기 때문에 기존의 위젯들과 함께 자연스럽게 사용할 수 있습니다. 제니퍼에서 캔버스를 활용하여 만든 컴포넌트들 중에는 기존의 마크업이나 스타일과 함께 사용되는 경우도 있지만, 서로 독립적인 부분도 있으며, 특히 이벤트를 구현할 때 고려해야 할 사항이 많습니다.</p>\n<p>마지막으로 플러터와 관련된 검색 중에 토스 앱에 있는 3D 인터랙션을 플러터로 구현한 예제를 발견했습니다. 개인적으로 토스의 UX/UI가 매우 훌륭하다고 생각하는데, 일부 기능 중 하나를 플러터로 쉽게 구현한 것을 보고 플러터의 가능성을 높게 평가하게 되었습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-7\" src=\"https://alvin.ing/assets/images/7-fd3d7ab75ce995909b3d84d1a66305bd.png\" width=\"1432\" height=\"860\" class=\"img_ev3q\"></p>\n<ol>\n<li class=\"\"><a href=\"https://flutter-for-beginners.vercel.app/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">페이지 전환 예제</a> : 페이지 전환시 효과를 쉽게 구현할 수 있습니다. (데스크탑 브라우저에서는 이미지가 보이지 않음)</li>\n<li class=\"\"><a href=\"https://flutter-playground.vercel.app/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">캔버스 그리기 예제</a> : 캔버스에 그라디언트 효과를 주고, 심볼(별모양)을 직접 그려서 무작위로 화면에 보여지는 배경 위젯입니다.</li>\n<li class=\"\"><a href=\"https://toss-gift-card.vercel.app/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">3D 인터랙션 예제</a> : 토스 앱의 상품권 추가시 3D 인터랙션을 구현한 예제입니다.</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며에 대한 직접 링크\" title=\"글을 마치며에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>플러터 스터디를 진행하고 모니터링 스터디 발표 자료를 준비하면서 몇 가지 결론을 내리게 되었습니다. 첫째로, 데스크탑과 모바일은 완전히 다른 기획과 사용자 경험이 필요하다는 것입니다. 모바일은 프론트엔드 영역이 아니라 플랫폼에 종속된 전혀 다른 분야로 생각하고 크게 고민하지 않았습니다. 사실 플랫폼이 iOS와 안드로이드로 크게 나뉘어져 있기 때문에 어느 한 쪽을 선택하는 것이 어려웠습니다. 플러터 덕분에 이러한 선택의 어려움을 해결하고, 본격적으로 모바일 UX에 대해 알아볼 수 있게 되었습니다.</p>\n<p>두 번째로, 이건 지극히 개인적인 사정이긴 한데, 프레임워크의 발전과 ChatGPT의 등장으로 프론트엔드 개발자로서 성장의 한계를 느끼고 있던 시점에 플러터를 발견하여 데스크탑 웹을 넘어 여러 플랫폼으로 프론트엔드 역량을 확장해나가야겠다는 새로운 목표가 생겼습니다.</p>\n<p>데스크탑과 모바일을 모두 고려한 서비스가 무조건 성공하는 것은 아니지만, 현재 성공한 서비스들을 살펴보면 둘 중 하나만 지원되는 서비스는 드물다고 생각됩니다. 네이버의 플러터 도입 검토 과정을 보면 알 수 있듯이, 보다 적은 인원으로 네이티브 수준의 애플리케이션을 개발할 수 있다는 것은 개발 인원이 적은 조직에서 충분히 고려해볼 만하다고 생각합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-링크\">참고 링크<a href=\"https://alvin.ing/blog/introduction-to-flutter#%EC%B0%B8%EA%B3%A0-%EB%A7%81%ED%81%AC\" class=\"hash-link\" aria-label=\"참고 링크에 대한 직접 링크\" title=\"참고 링크에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><a href=\"https://goldenrabbit.co.kr/2023/04/02/flutter-1/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">[Flutter] 어떻게 플러터는 다른 크로스 플랫폼보다 더 강력한 성능을 내는 걸까?</a></li>\n<li class=\"\"><a href=\"https://velog.io/@cyb9701/%ED%86%A0%EC%8A%A4-%EC%83%81%ED%92%88%EA%B6%8C-3D-%EC%9D%B8%ED%84%B0%EB%9E%99%EC%85%98\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">[Flutter] 상품권 추가 3D 인터랙션</a></li>\n<li class=\"\"><a href=\"https://beomseok95.tistory.com/315\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Flutter(플러터)가 Dart(다트) 언어를 사용하는 이유</a></li>\n<li class=\"\"><a href=\"https://d2.naver.com/helloworld/3384599\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">지식iN 앱을 Flutter로 개발하는 이유</a></li>\n</ul>",
            "url": "https://alvin.ing/blog/introduction-to-flutter",
            "title": "크로스플랫폼 앱 개발을 위한 플러터 소개",
            "summary": "플러터란?",
            "date_modified": "2023-10-10T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Dark",
                "Flutter",
                "iOS",
                "Android"
            ]
        },
        {
            "id": "https://alvin.ing/blog/react-server-components",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"개요\">개요<a href=\"https://alvin.ing/blog/react-server-components#%EA%B0%9C%EC%9A%94\" class=\"hash-link\" aria-label=\"개요에 대한 직접 링크\" title=\"개요에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>2020년 12월 React 팀은 서버 주도(Server-Driven) 멘탈 모델로써 모던 UX를 가능하게 하는 것을 목표로 하는 <a href=\"https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">zero-bundle React 서버 컴포넌트</a>를 시연했습니다. 이때 소개한 서버 컴포넌트는 서버 사이드 렌더링(SSR)과는 상당히 다르며 클라이언트 측 번들 크기를 매우 줄일 수 있다고 하였으며, 서버와 클라이언트(브라우저)가 React 애플리케이션을 서로 협력하여 렌더링 할 수 있게 됩니다.</p>\n<p>그리고 2022년 10월 <a href=\"https://nextjs.org/conf\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Next.js Conf</a>에서 Next.js 13부터 React 서버 컴포넌트를 지원한다고 발표했습니다. 처음 서버 컴포넌트를 소개한 후, 시간이 꽤 지났음에도 불구하고, 아직도 실험적인 단계이긴 하지만 Next.js 기반으로 서버 컴포넌트를 구현해볼 수 있게 되었습니다. Next.js 관련해서는 <a href=\"https://www.notion.so/NextJS-43cf54bc542441a0ae33f5d005db18a5\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">데이빗이 작성한 문서</a>를 참고하시면 됩니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ssr의-한계\">SSR의 한계<a href=\"https://alvin.ing/blog/react-server-components#ssr%EC%9D%98-%ED%95%9C%EA%B3%84\" class=\"hash-link\" aria-label=\"SSR의 한계에 대한 직접 링크\" title=\"SSR의 한계에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>오늘날 자바스크립트의 서버 사이드 렌더링(SSR)은 초기 페이지 로드 시간을 개선하기 위한 차선책입니다. 컴포넌트의 자바스크립트는 서버에서 HTML 문자열로 렌더링됩니다. HTML은 브라우저에게 전달되고 나타나며, 빠른 FCP(First Contentful Paint) 혹은 LCP(Largest Contentful Paint)를 가지게 됩니다.</p>\n<p>하지만 Hydration 단계를 통해 인터렉션이 가능해진 엘리먼트를 위해서는 여전히 자바스크립트가 필요합니다. 서버 사이드 렌더링은 일반적으로 최초 페이지 로드를 위해 사용되기 때문에 Hydration 이후에는 추가적으로 쓰이지 않습니다.</p>\n<p>클라이언트에서의 Hydration을 전혀 하지 않고, React와 SSR만 가지고 애플리케이션을 만들 수도 있지만 애플리케이션에서 인터렉션을 많이 해야 하는 경우에는 어쩔 수 없이 클라이언트 측으로 코드를 보내야 합니다. 서버 컴포넌트의 하이브리드 모델은 이 선택을 컴포넌트 기준으로 가능하도록 해줍니다.</p>\n<p>React의 서버 컴포넌트를 활용하면 컴포넌트들을 정기적으로 다시 받아올 수 있습니다. 새로운 데이터가 있을 때 서버에서 애플리케이션의 컴포넌트들을 리-렌더링 할 수 있으므로 클라이언트 측에 전송해야 하는 코드량을 줄일 수 있습니다.</p>\n<p>SSR은 서버에서 HTML을 생성하고 클라이언트로 전송하는 방식입니다. SSR은 초기 로딩 속도를 높일 수 있지만 RSC는 더 많은 기능을 제공합니다.</p>\n<blockquote>\n<p>Hydration이란?</p>\n<ol>\n<li class=\"\">컴포넌트를 렌더링하고, 이벤트 핸들러를 연결하는 프로세스</li>\n<li class=\"\">서버 단에서 렌더링한 정적 컨텐츠와 번들링 된 JS 파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 JS 코드를 서로 매칭 시키는 과정</li>\n</ol>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rsc-vs-ssr\">RSC vs SSR<a href=\"https://alvin.ing/blog/react-server-components#rsc-vs-ssr\" class=\"hash-link\" aria-label=\"RSC vs SSR에 대한 직접 링크\" title=\"RSC vs SSR에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>결론부터 말하자면 RSC는 SSR을 대체할 수 없습니다. SSR은 해당 페이지의 HTML 코드를 미리 빌드합니다. 이것은 SEO에 효과적이고, 사용자가 자바스크립트 코드를 다운받는 동안 해당 페이지의 내용을 미리 볼 수 있습니다. 즉, SSR은 해당 페이지 자체를 렌더링하는 것이고, 서버 컴포넌트는 각각의 컴포넌트마다 클라이언트 컴포넌트로 렌더링 할 것인지 서버 컴포넌트로 렌더링 할 것인지를 선택해야 합니다.</p>\n<p>Next.js와 SSR의 차이점에 대해 <a href=\"https://www.youtube.com/watch?v=TQQPAU21ZUw\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Dan과 Lauren의 talk</a>에서 언급한 내용을 정리해 보면:</p>\n<ul>\n<li class=\"\">서버 컴포넌트의 코드는 클라이언트로 전달되지 않습니다. 하지만 서버 사이드 렌더링의 모든 컴포넌트의 코드는 자바스크립트 번들에 포함되어 클라이언트로 전송됩니다.</li>\n<li class=\"\">서버 컴포넌트는 페이지 레벨에 상관없이 모든 컴포넌트에서 서버에 접근 가능합니다. 하지만 Next.js의 경우 가장 top level의 페이지에서만&nbsp;<code>getServerProps()</code>나&nbsp;<code>getInitialProps()</code>로 서버에 접근 가능합니다.</li>\n<li class=\"\">서버 컴포넌트는 클라이언트 상태를 유지하며 re-fetch 될 수 있습니다. 서버 컴포넌트는 HTML이 아닌 특별한 형태로 컴포넌트를 전달하기 때문에 필요한 경우 포커스, 인풋 입력값 같은 클라이언트 상태를 유지하며 여러 번 데이터를 가져오고 리렌더링하여 전달할 수 있습니다. 하지만 SSR의 경우 HTML로 전달되기 때문에 새로운 re-fetch가 필요한 경우 HTML 전체를 다시 렌더링 해야 하며, 이로 인해 클라이언트 상태를 유지할 수 없습니다.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"탄생-배경\">탄생 배경<a href=\"https://alvin.ing/blog/react-server-components#%ED%83%84%EC%83%9D-%EB%B0%B0%EA%B2%BD\" class=\"hash-link\" aria-label=\"탄생 배경에 대한 직접 링크\" title=\"탄생 배경에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>React 팀은 다방면으로 성능 향상을 해왔으나 Data Fetching의 경우, 사용자와 개발자 경험 모두를 만족시킬 수있는 방법을 찾기가 어려웠습니다. React 컴포넌트의 비동기적 Data Fetching의 가장 큰 문제점은 클라이언트와 서버 간 요청의 High Latency와 연속된 클라이언트-서버 API 요청으로 발생하는 Waterfall이었습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-1\" src=\"https://alvin.ing/assets/images/1-935c343318aa677f0b545d987b87fb99.png\" width=\"790\" height=\"449\" class=\"img_ev3q\"></p>\n<p>이와 같이 클라이언트 컴포넌트에서 비동기 Data Fetching은 클라이언트-서버의 Waterfall을 야기하고, 성능을 저하시키는 원인이 됩니다.</p>\n<p>이를 위한 해결책으로 서버 컴포넌트가 탄생하게 되었으며, RSC는 용어 그대로 서버에서 동작하는 React 컴포넌트입니다. 서버 컴포넌트를 사용하면 컴포넌트 렌더링을 클라이언트가 아닌 서버에서 수행할 수 있습니다.</p>\n<p>서버에서 렌더링을 수행하기 때문에 API를 통한 데이터 요청의 Latency를 줄일 수 있고, 클라이언트에서의 연속된 API 호출을 제거하여, 클라이언트-서버의 Waterfall을 막을 수 있습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-2\" src=\"https://alvin.ing/assets/images/2-23d90ee5f71896cab9d2f7dbc1a9706f.png\" width=\"790\" height=\"449\" class=\"img_ev3q\"></p>\n<p>아쉽게도 서버 컴포넌트에서의 데이터 요청을 처리하여도 중첩된 컴포넌트에서의 여러 API 요청에 따른 네트워크 Waterfall은 여전히 존재합니다.</p>\n<p>하지만 서버 컴포넌트는 서버에서 동작하고 렌더링 된다는 특성상 다양한 종류의 백엔드 리소스에 접근할수 있고, HTML이 아닌 ‘특별한’ 형태로 렌더링 되어 클라이언트에 전달되기 때문에 클라이언트로 전달되는 번들 사이즈 또한 감소시킬 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"서버-컴포넌트란\">서버 컴포넌트란?<a href=\"https://alvin.ing/blog/react-server-components#%EC%84%9C%EB%B2%84-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%9E%80\" class=\"hash-link\" aria-label=\"서버 컴포넌트란?에 대한 직접 링크\" title=\"서버 컴포넌트란?에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>React가 UI를 구축하는 방식을 바꾼 것과 유사하게, 서버와 클라이언트를 활용하는 하이브리드 애플리케이션을 구축하기 위한 새로운 사고 모델을 도입했습니다.</p>\n<p>SPA의 경우처럼 전체 애플리케이션을 클라이언트 측에서 렌더링하는 대신, React는 이제 컴포넌트의 목적에 따라 렌더링할 위치를 선택할 수 있는 유연성을 제공합니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image-3\" src=\"https://alvin.ing/assets/images/3-ec31acade9996d3cec524a604d5c425e.avif\" width=\"1600\" height=\"652\" class=\"img_ev3q\"></p>\n<p>페이지를 더 작은 컴포넌트로 분할하면 대부분의 컴포넌트가 비대화형이며 서버에서 서버 컴포넌트로 렌더링 할 수 있음을 알 수 있습니다. 더 작은 인터랙티브 UI의 경우, 클라이언트 컴포넌트로 나타낼 수 있습니다. 이는 Next.js의 서버 우선 접근 방식과 일치합니다.</p>\n<p>서버 컴포넌트의 특징을 정리하면 다음과 같습니다.</p>\n<ul>\n<li class=\"\">자유로운 서버 리소스 접근 : 데이터베이스, 파일 시스템 등등</li>\n<li class=\"\">제로 번들 사이즈 컴포넌트 : 서버 컴포넌트는 브라우저에 다운로드 되지 않고, 서버에서 미리 렌더링 된 정적 컨텐츠로 전달됨</li>\n<li class=\"\">자동 코드 분할 : 서버 컴포넌트에서 Import 되는 모든 클라이언트 컴포넌트를 코드 분할 포인트로 간주하기 때문에 Lazy 로드가 필요하지 않음</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"클라이언트와-서버-컴포넌트-구성하기\">클라이언트와 서버 컴포넌트 구성하기<a href=\"https://alvin.ing/blog/react-server-components#%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8%EC%99%80-%EC%84%9C%EB%B2%84-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"클라이언트와 서버 컴포넌트 구성하기에 대한 직접 링크\" title=\"클라이언트와 서버 컴포넌트 구성하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>서버에서 React는 결과를 클라이언트로 보내기 전에 모든 서버 컴포넌트를 렌더링 합니다. 그리고 클라이언트에서 React는 클라이언트 컴포넌트를 렌더링하고 서버 컴포넌트의 렌더링 결과에 슬롯을 생성하여 서버와 클라이언트에서 수행한 작업을 병합합니다.</p>\n<p>클라이언트 컴포넌트는 코드 상단에 ‘use client’ 디렉티브를 명시해야 합니다. 그리고 서버 컴포넌트를 import 할 수 없습니다.</p>\n<p>대신 클라이언트 컴포넌트를 디자인 할 때, React 프로퍼티를 사용하여 서버 컴포넌트의 “holes”를 표시할 수 있습니다. 서버 컴포넌트는 서버에서 렌더링되고, 클라이언트 컴포넌트가 클라이언트에서 렌더링되면 서버 컴포넌트의 렌더링 된 결과로 “hole”이 채워집니다.</p>\n<p>일반적인 패턴은 React의 children 프로퍼티를 사용하여 “hole”을 만드는 것입니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token string\" style=\"color:#e3116c\">'use client'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> useState </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'react'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">ExampleClientComponent</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  children</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> React</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">ReactNode</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">count</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> setCount</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">useState</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token plain\">button onClick</span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">setCount</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">count </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">count</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token operator\" style=\"color:#393A34\">/</span><span class=\"token plain\">button</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">children</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token operator\" style=\"color:#393A34\">/</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>&lt;ExampleClientComponent&gt;는 자식 컴포넌트가 무엇인지 전혀 알지 못합니다. 사실, 이 컴포넌트의 관점에서는 자식들이 결국 서버 컴포넌트의 결과에 의해 채워질 것이라는 사실조차 알지 못합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// This pattern works:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// You can pass a Server Component as a child or prop of a</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// Client Component.</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> ExampleClientComponent </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./example-client-component'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> ExampleServerComponent </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./example-server-component'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// Pages in Next.js are Server Components by default</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">Page</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token plain\">ExampleClientComponent</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token plain\">ExampleServerComponent </span><span class=\"token operator\" style=\"color:#393A34\">/</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token operator\" style=\"color:#393A34\">/</span><span class=\"token plain\">ExampleClientComponent</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>그리고 서버 컴포넌트는 클라이언트 컴포넌트를 Import 할 수 있지만 서버에서 클라이언트 컴포넌트로 전달되는 프로퍼티는 직렬화가 가능해야 합니다. 즉, 함수나 날짜 등과 같은 값은 클라이언트 컴포넌트에 직접 전달할 수 없습니다.</p>\n<p>다음은 클라이언트와 서버 컴포넌트의 특징을 정리한 표입니다.</p>\n<table><thead><tr><th width=\"70%\">특징</th><th width=\"15%\">서버</th><th width=\"15%\">클라이언트</th></tr></thead><tbody><tr><td>데이터 가져오기</td><td>O</td><td>X</td></tr><tr><td>백엔드 리소스에 직접 액세스 (직접)</td><td>O</td><td>X</td></tr><tr><td>서버에 민감한 정보 보관 (액세스 토큰, API 키 등)</td><td>O</td><td>X</td></tr><tr><td>서버에 대한 대규모 종속성 유지 / 클라이언트 측 자바스크립트 감소</td><td>O</td><td>X</td></tr><tr><td>인터랙티브 및 이벤트 리스너 추가 (onClick, onChange 등)</td><td>X</td><td>O</td></tr><tr><td>상태 및 라이프사이클 효과 사용 (useState, useReducer, useEffect 등)</td><td>X</td><td>O</td></tr><tr><td>브라우저 전용 API 사용</td><td>X</td><td>O</td></tr><tr><td>상태, 효과 또는 브라우저 전용 API에 의존하는 사용자 지정 후크 사용</td><td>X</td><td>O</td></tr><tr><td>React 클래스 컴포넌트 사용</td><td>X</td><td>O</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"데모-살펴보기\">데모 살펴보기<a href=\"https://alvin.ing/blog/react-server-components#%EB%8D%B0%EB%AA%A8-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"데모 살펴보기에 대한 직접 링크\" title=\"데모 살펴보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>데모 화면은 Postgres DB에 저장된 사용자 목록을 가져와서 테이블 형태로 보여줍니다. 캐시 처리를 위해 Redis에 사용자 목록을 10초간 보관합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// lib/service.ts</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> kv </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"@vercel/kv\"</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> sql </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"@vercel/postgres\"</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">interface</span><span class=\"token plain\"> </span><span class=\"token class-name\">User</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">number</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  image</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  email</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  createdAt</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> Date</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">getUsers</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">cacheKey</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> cachedData </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">await</span><span class=\"token plain\"> kv</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token generic-function function\" style=\"color:#d73a49\">get</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name\">User</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">[</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">]</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token template-string string\" style=\"color:#e3116c\">users-</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">${</span><span class=\"token template-string interpolation\">cacheKey</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">}</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">if</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">cachedData </span><span class=\"token operator\" style=\"color:#393A34\">===</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">null</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> data </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">await</span><span class=\"token plain\"> sql</span><span class=\"token operator\" style=\"color:#393A34\">&lt;</span><span class=\"token plain\">User</span><span class=\"token operator\" style=\"color:#393A34\">&gt;</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token template-string string\" style=\"color:#e3116c\">SELECT * FROM users</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">await</span><span class=\"token plain\"> kv</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">set</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token template-string string\" style=\"color:#e3116c\">users-</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">${</span><span class=\"token template-string interpolation\">cacheKey</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">}</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">JSON</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">stringify</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">rows</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> ex</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> nx</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">rows</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">else</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> cachedData</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// app/api/route.ts</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> getUsers </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'@/lib/service'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> NextResponse </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'next/server'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">GET</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">request</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> Request</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> NextResponse</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">json</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> users</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">await</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">getUsers</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>아래는 클라이언트 컴포넌트로 구현된 테이블 컴포넌트입니다. 데이터를 가져오기 위해 /api/users를 호출하고, API 내부에는 앞에서 구현한 서비스 함수를 사용합니다.</p>\n<div class=\"language-tsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-tsx codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// components/client-table.tsx</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token string\" style=\"color:#e3116c\">'use client'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">type</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">User</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'@/lib/service'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:#393A34\">{</span><span class=\"token imports\"> useState</span><span class=\"token imports punctuation\" style=\"color:#393A34\">,</span><span class=\"token imports\"> useEffect </span><span class=\"token imports punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'react'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">ReloadButton</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./reload-button'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">TableHead</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./table-head'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">TableRow</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'@/components/table-row'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">ClientTable</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">users</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> setUsers</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">useState</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name\">User</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">[</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">]</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">duration</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> setDuration</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">useState</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">loading</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> setLoading</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">useState</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">boolean</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token boolean\" style=\"color:#36acaa\">false</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token function-variable function\" style=\"color:#d73a49\">loadData</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> startTime </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token known-class-name class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">setLoading</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">fetch</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'/api/users'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">then</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">res</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> res</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">json</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">then</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token function\" style=\"color:#d73a49\">setUsers</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">users</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token function\" style=\"color:#d73a49\">setDuration</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token known-class-name class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token plain\"> startTime</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token function\" style=\"color:#d73a49\">setLoading</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token boolean\" style=\"color:#36acaa\">false</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token function\" style=\"color:#d73a49\">useEffect</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">loadData</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">className</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">bg-white/30 p-12 shadow-xl ring-1 ring-gray-900/5 rounded-lg backdrop-blur-lg max-w-xl mx-auto w-full</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableHead</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">userCount</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">users</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">.</span><span class=\"token tag script language-javascript property-access\" style=\"color:#00009f\">length</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">duration</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">duration</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">ReloadButton</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">onClick</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">loadData</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">loading</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">loading</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableHead</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">className</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">divide-y divide-gray-900/5</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">users</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">map</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> index</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableRow</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">key</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">index</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">user</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">user</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableRow</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>클라이언트 컴포넌트와 달리 API 호출을 위한 코드는 생략하고, 앞에서 구현한 서비스 함수를 바로 사용할 수 있습니다.</p>\n<div class=\"language-tsx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-tsx codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// components/server-table.tsx</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:#393A34\">{</span><span class=\"token imports\"> getUsers </span><span class=\"token imports punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'@/lib/service'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">RefreshButton</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./refresh-button'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">TableHead</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./table-head'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">TableRow</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./table-row'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">default</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">ServerTable</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> startTime </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token known-class-name class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> users </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">await</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">getUsers</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'server'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> duration </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token known-class-name class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token plain\"> startTime</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">className</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">bg-white/30 p-12 shadow-xl ring-1 ring-gray-900/5 rounded-lg backdrop-blur-lg max-w-xl mx-auto w-full</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableHead</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">userCount</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">users</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">.</span><span class=\"token tag script language-javascript property-access\" style=\"color:#00009f\">length</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">duration</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">duration</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">RefreshButton</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableHead</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">className</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">divide-y divide-gray-900/5</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">users</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">map</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">user</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> index</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableRow</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">key</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">index</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">user</span><span class=\"token tag script language-javascript script-punctuation punctuation\" style=\"color:#393A34\">=</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">{</span><span class=\"token tag script language-javascript\" style=\"color:#00009f\">user</span><span class=\"token tag script language-javascript punctuation\" style=\"color:#393A34\">}</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag class-name\" style=\"color:#00009f\">TableRow</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain-text\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain-text\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>데모 화면과 소스 코드는 아래 링크를 통해 직접 확인할 수 있습니다.</p>\n<ul>\n<li class=\"\"><a href=\"https://next.alvin.biz/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Demo</a></li>\n<li class=\"\"><a href=\"https://github.com/seogi1004/nextjs-rsc-starter\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub</a></li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며<a href=\"https://alvin.ing/blog/react-server-components#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며에 대한 직접 링크\" title=\"글을 마치며에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이번 스터디 발표 준비를 하면서 RSC에 대해 알아보고 이해하는 과정을 겪으면서 느꼈던 점은 언젠가 APM 에이전트 라인업에 RSC가 포함될 수도 있을 것 같다는 생각이 들었습니다.</p>\n<p>지금처럼 프론트엔드와 백엔드 개발 영역의 구분이 명확하지 않았던 시절의 웹 개발을 했던 모습도 떠오릅니다. 물론 그때와 지금은 엄청난 차이가 있고, 자바스크립트는 웹 페이지의 인터랙티브 한 기능을 제공하기 위한 보조적인 역할만 했던 시기이기도 합니다.</p>\n<p>RSC가 추구하는 방향성을 이해하려고 하다보니 문득 이런 생각이 들었습니다. 어쩌면 다시 옛날처럼 프론트엔드와 백엔드를 구분하지 않고 개발하는 시대가 올 수도 있겠구나. 다만, 과거와 달리 앞으로는 메인은 화면 개발이고, 서브로 렌더링 성능 개선을 위한 서버 개발을 해야하는 상황이 올 수도 있겠다는 생각을 했습니다. (프론트엔드 개발자 기준에서…)</p>\n<p>앞으로 웹 생태계에 어떤 변화가 다가올지 알 수는 없지만 한가지 분명한 것은 RSC가 큰 영향을 줄 수 있을 것 같습니다. 그래서 꾸준한 관심과 기대를 가져볼만하다고 생각합니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-링크\">참고 링크<a href=\"https://alvin.ing/blog/react-server-components#%EC%B0%B8%EA%B3%A0-%EB%A7%81%ED%81%AC\" class=\"hash-link\" aria-label=\"참고 링크에 대한 직접 링크\" title=\"참고 링크에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>문서를 읽고 이해하는 것보다 직접 구현해보는게 나을 것 같아서 이번에도 데모 개발에 시간을 많이 할애했습니다. 본문 내용의 대부분은 아래 문서를 인용한 것이니 참고하시길 바랍니다.</p>\n<ul>\n<li class=\"\"><a href=\"https://ko.legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Introducing Zero-Bundle-Size React Server Components</a></li>\n<li class=\"\"><a href=\"https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">RFC: React Server Components</a></li>\n<li class=\"\"><a href=\"https://nextjs.org/docs/getting-started/react-essentials\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">React Essentials</a></li>\n<li class=\"\"><a href=\"https://www.plasmic.app/blog/how-react-server-components-work\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">How React server components work: an in-depth guide</a></li>\n<li class=\"\"><a href=\"https://kulkarniankita.com/react/react-server-client-components\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">React Server vs Client components in Next.js 13</a></li>\n<li class=\"\"><a href=\"https://tech.kakaopay.com/post/react-server-components\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">React 18: 리액트 서버 컴포넌트 준비하기</a></li>\n</ul>",
            "url": "https://alvin.ing/blog/react-server-components",
            "title": "RSC(React Server Components) 살펴보기",
            "summary": "개요",
            "date_modified": "2023-03-15T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "React",
                "React Server Components",
                "Next.js"
            ]
        },
        {
            "id": "https://alvin.ing/blog/d3-hierarchy",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"children을-포함하는-계층-데이터\">children을 포함하는 계층 데이터<a href=\"https://alvin.ing/blog/d3-hierarchy#children%EC%9D%84-%ED%8F%AC%ED%95%A8%ED%95%98%EB%8A%94-%EA%B3%84%EC%B8%B5-%EB%8D%B0%EC%9D%B4%ED%84%B0\" class=\"hash-link\" aria-label=\"children을 포함하는 계층 데이터에 대한 직접 링크\" title=\"children을 포함하는 계층 데이터에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>D3에서 사용할 데이터를 정의할 때, 부모-자식 관계를 정하기 위해서 children을 반드시 포함시켜야 합니다.\nchildren에 자식 노드를 추가하면서 계층 데이터 형태로 구성할 수 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">interface</span><span class=\"token plain\"> </span><span class=\"token class-name\">TreeData</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    children</span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> TreeData</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">TREE_DATA</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> TreeData </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Mountains'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Pontus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Uranus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Eros'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Erebus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Tartarus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기본적인-hierarchy-객체-생성하기\">기본적인 Hierarchy 객체 생성하기<a href=\"https://alvin.ing/blog/d3-hierarchy#%EA%B8%B0%EB%B3%B8%EC%A0%81%EC%9D%B8-hierarchy-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"기본적인 Hierarchy 객체 생성하기에 대한 직접 링크\" title=\"기본적인 Hierarchy 객체 생성하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>hierarchy 함수를 호출하면 D3에서 정의한 HierarchyNode 타입의 객체가 리턴되며, 각각의 프로퍼티에 대한 설명은 다음과 같습니다.</p>\n<ul>\n<li class=\"\">children : 자식 노드들</li>\n<li class=\"\">data : 사용자가 정의한 데이터</li>\n<li class=\"\">depth : 트리에서 자신의 노드의 깊이</li>\n<li class=\"\">height : 자식 노드의 최대 깊이</li>\n<li class=\"\">parent : 부모 노드 없으면 null</li>\n</ul>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> root </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">hierarchy</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name\">TreeData</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">TREE_DATA</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token builtin\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">root</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  data</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\">  </span><span class=\"token string\" style=\"color:#e3116c\">\"Chaos\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">Array</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  depth</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  height</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  parent</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">null</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"레이아웃-객체-생성하기\">레이아웃 객체 생성하기<a href=\"https://alvin.ing/blog/d3-hierarchy#%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"레이아웃 객체 생성하기에 대한 직접 링크\" title=\"레이아웃 객체 생성하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>앞에서 생성한 객체를 가지고, D3에서 제공하는 레이아웃 객체를 생성할 수 있습니다.\n아래는 트리를 그리기 위한 레이아웃 객체를 생성하는 코드이며, HierarchyNode 타입을 상속한 HierarchyPointNode 타입의 객체로 변경됩니다.</p>\n<p>x, y 프로퍼티가 추가된 것을 확인할 수 있으며, 캔버스나 SVG로 무엇인가 그릴 때, 해당 값을 그대로 사용하면 됩니다.</p>\n<p>HierarchyNode 타입을 상속하는 타입은 HierarchyPointNode 외에도 HierarchyRectangularNode, HierarchyCircularNode 타입이 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> treeLayout </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">tree</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">size</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token constant\" style=\"color:#36acaa\">WIDTH</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">HEIGHT</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">treeLayout</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">root</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token builtin\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">root</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  data</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\">  </span><span class=\"token string\" style=\"color:#e3116c\">\"Chaos\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">Array</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  depth</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  height</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  parent</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">null</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  x</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">233.33333333333334</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  y</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"로우셋을-계층-데이터로-변환하기\">로우셋을 계층 데이터로 변환하기<a href=\"https://alvin.ing/blog/d3-hierarchy#%EB%A1%9C%EC%9A%B0%EC%85%8B%EC%9D%84-%EA%B3%84%EC%B8%B5-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"로우셋을 계층 데이터로 변환하기에 대한 직접 링크\" title=\"로우셋을 계층 데이터로 변환하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>때로는 children 프로퍼티가 포함되어있지 않고, 부모 키만 알고 있는 데이터를 가지고 있을 수 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">interface</span><span class=\"token plain\"> </span><span class=\"token class-name\">RowData1</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    parentId</span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">interface</span><span class=\"token plain\"> </span><span class=\"token class-name\">RowData2</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    pid</span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">string</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">ROW_DATA_1</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> RowData1</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Eros'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Erebus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Tartarus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Mountains'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Pontus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Uranus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> parentId</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">ROW_DATA_2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> RowData2</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Eros'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Erebus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Tartarus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Chaos'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Mountains'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Pontus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> id2</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Uranus'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> pid</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Gaia'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>D3에서는 children과 마찬가지로 id와 parentId 프로퍼티를 스스로 인식합니다.\nstratify 함수를 사용하면 hierarchy 함수와 동일한 객체를 리턴하게 됩니다.</p>\n<p>하지만 데이터 id와 parentId 프로퍼티가 포함되어 있지 않다면 id와 parentId 메소드를 통해 부모-자식 관계를 설정할 수 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> root1 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">stratify</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name\">RowData1</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">ROW_DATA_1</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> root2 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">stratify</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name\">RowData2</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">id</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">id2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">parentId</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">pid</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">ROW_DATA_2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token builtin\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">root2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> Node</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  data</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">id</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\">  </span><span class=\"token string\" style=\"color:#e3116c\">\"Chaos\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> children</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">Array</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  depth</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  height</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  parent</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">null</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"hierarchy-객체의-메소드-소개\">Hierarchy 객체의 메소드 소개<a href=\"https://alvin.ing/blog/d3-hierarchy#hierarchy-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%86%8C%EA%B0%9C\" class=\"hash-link\" aria-label=\"Hierarchy 객체의 메소드 소개에 대한 직접 링크\" title=\"Hierarchy 객체의 메소드 소개에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>계층 데이터를 쉽게 핸들링할 수 있는 몇가지 메소드들을 소개합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> chaos </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> root2</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> gaia </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> chaos</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">children</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> pontus </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> chaos</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">children</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">children</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">1</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> tartarus </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> chaos</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">children</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">3</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ancestors\">ancestors<a href=\"https://alvin.ing/blog/d3-hierarchy#ancestors\" class=\"hash-link\" aria-label=\"ancestors에 대한 직접 링크\" title=\"ancestors에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>자신을 포함하여 루트까지 모든 부모 노드의 배열을 반환합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">gaia</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">ancestors</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"ancestors-1\" src=\"https://alvin.ing/assets/images/1-3c7669819663cf061217e429c4115f60.png\" width=\"1034\" height=\"248\" class=\"img_ev3q\"></p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">pontus</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">ancestors</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"ancestors-2\" src=\"https://alvin.ing/assets/images/2-8ce8ff34638d18c2ac1fcb5d2200ecbb.png\" width=\"1016\" height=\"242\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"descendants\">descendants<a href=\"https://alvin.ing/blog/d3-hierarchy#descendants\" class=\"hash-link\" aria-label=\"descendants에 대한 직접 링크\" title=\"descendants에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>자신을 포함하여 모든 자식 노드의 배열을 반환합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">gaia</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">descendants</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"descendants\" src=\"https://alvin.ing/assets/images/3-d3ad6f65c7c61eb7fd4e1fac7d6f1cfb.png\" width=\"1022\" height=\"266\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"leaves\">leaves<a href=\"https://alvin.ing/blog/d3-hierarchy#leaves\" class=\"hash-link\" aria-label=\"leaves에 대한 직접 링크\" title=\"leaves에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>해당 노드의 자식 중에 자식이 없는 노드의 배열을 반환합니다</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">gaia</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">leaves</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"leaves\" src=\"https://alvin.ing/assets/images/4-1ce68f26b16c38b3d0e92625154cb314.png\" width=\"1014\" height=\"268\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"path\">path<a href=\"https://alvin.ing/blog/d3-hierarchy#path\" class=\"hash-link\" aria-label=\"path에 대한 직접 링크\" title=\"path에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>해당 노드부터 대상 노드까지 연결된 모든 노드의 배열을 반환합니다.</p>\n<div class=\"theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 12 16\"><path fill-rule=\"evenodd\" d=\"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z\"></path></svg></span>노드 순서</div><div class=\"admonitionContent_BuS1\"><p>Tartarus -&gt; Chaos -&gt; Gaia -&gt; Pontus</p></div></div>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">tartarus</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">path</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">pontus</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"path\" src=\"https://alvin.ing/assets/images/5-4fe4370afb962b8ed8db19a49ec4b4d0.png\" width=\"1038\" height=\"290\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"links\">links<a href=\"https://alvin.ing/blog/d3-hierarchy#links\" class=\"hash-link\" aria-label=\"links에 대한 직접 링크\" title=\"links에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>해당 노드의 자식 링크를 나타내는 객체 배열을 반환합니다. 각 링크 객체의 target은 자식이고, source는 부모입니다.\ngaia의 자식 노드인 mountains, pontus, uranus를 target으로 가진 HierarchyPointLink 타입을 가지는 배열을 리턴합니다.</p>\n<p>앞에서 트리 레이아웃을 사용했기 때문에 HierarchyLink가 아닌 HierarchyPointLink 타입의 객체를 리턴합니다.\n그 밖에도 HierarchyCircularLink, HierarchyRectangularLink 타입이 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">gaia</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">links</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"descendants\" src=\"https://alvin.ing/assets/images/3-d3ad6f65c7c61eb7fd4e1fac7d6f1cfb.png\" width=\"1022\" height=\"266\" class=\"img_ev3q\"></p>",
            "url": "https://alvin.ing/blog/d3-hierarchy",
            "title": "D3 Hierarchy 모듈로 데이터 핸들링하기",
            "summary": "children을 포함하는 계층 데이터",
            "date_modified": "2023-02-12T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "D3.js"
            ]
        },
        {
            "id": "https://alvin.ing/blog/offscreen-canvas-api",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"캔버스-애니메이션의-문제점\">캔버스 애니메이션의 문제점<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EC%BA%94%EB%B2%84%EC%8A%A4-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98%EC%9D%98-%EB%AC%B8%EC%A0%9C%EC%A0%90\" class=\"hash-link\" aria-label=\"캔버스 애니메이션의 문제점에 대한 직접 링크\" title=\"캔버스 애니메이션의 문제점에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>웹 개발시 다이나믹한 그래픽 처리가 필요하면 캔버스를 사용합니다.\n이제 캔버스는 HTML 엘리먼트 중에서 사용 통계가 40%가 넘을 정도로 아주 범용적입니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/1-c87c6a5b87a90801989d39854ca9d1c9.webp\" width=\"1400\" height=\"368\" class=\"img_ev3q\"></p>\n<p>캔버스는 애니메이션을 잘 처리하기 위한 목적으로 나온 태그이지만 현실은 다이나믹한 그래픽 처리에 어려움이 있습니다.</p>\n<ul>\n<li class=\"\">자바스크립트 엔진과 렌더링 엔진 사이의 바인딩 오버헤드 발생</li>\n<li class=\"\">GPU 가속을 사용하더라도 Skia 내부의 오버헤드 발생</li>\n<li class=\"\">GPU 가속 쓰더라도 CPU를 써야하는 부분에서 페인팅 라이브러리 오버헤드 발생</li>\n<li class=\"\">위 프로세스 처리 후 DOM 렌더링을 처리하기에도 벅찬 메인 스레드</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"1400\" height=\"281\" class=\"img_ev3q\"></p>\n<p>프레임 드랍이 발생하지 않게 하기 위해서는 메인 스레드에서 1프레임(16.7ms) 안에 DOM, Javascript, Painting을 처리하고, 남는 시간에 캔버스 렌더링을 시도해야 합니다.\n하지만 메인 스레드는 위 그림처럼 이미 많은 일을 하고 있는 경우가 많습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기존의-문제점-개선-방법\">기존의 문제점 개선 방법<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EA%B8%B0%EC%A1%B4%EC%9D%98-%EB%AC%B8%EC%A0%9C%EC%A0%90-%EA%B0%9C%EC%84%A0-%EB%B0%A9%EB%B2%95\" class=\"hash-link\" aria-label=\"기존의 문제점 개선 방법에 대한 직접 링크\" title=\"기존의 문제점 개선 방법에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"풀-스크린으로-캔버스-렌더링하기\">풀 스크린으로 캔버스 렌더링하기<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%ED%92%80-%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%9C%BC%EB%A1%9C-%EC%BA%94%EB%B2%84%EC%8A%A4-%EB%A0%8C%EB%8D%94%EB%A7%81%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"풀 스크린으로 캔버스 렌더링하기에 대한 직접 링크\" title=\"풀 스크린으로 캔버스 렌더링하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>UI에 제약이 생기지만 캔버스를 풀 스크린으로 렌더링하면 핸들링할 Target DOM 이 없기 때문에 메인 스레드 자원을 더 사용할 수 있으며, GPU 가속까지 붙이면 성능을 개선할 수 있습니다.\n애니메이션을 전체 화면에서 처리할 경우는 고려해볼 수 있는 선택지입니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"백그라운드-캔버스\">백그라운드 캔버스<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EC%BA%94%EB%B2%84%EC%8A%A4\" class=\"hash-link\" aria-label=\"백그라운드 캔버스에 대한 직접 링크\" title=\"백그라운드 캔버스에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>프리젠테이션용, 백그라운드용 캔버스를 두개 만듭니다.\n백그라운드에서 여러 오브젝트를 다 그린 다음에 프레젠테이션 캔버스에 백그라운드 캔버스에서 그린 오브젝트를 가져와 한번에 한번에 엎어치기 하는 방식입니다. (현재 제니퍼 대시보드 차트에서도 사용되고 있는 방식)</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"오프스크린-캔버스를-사용한-개선\">오프스크린 캔버스를 사용한 개선<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EC%98%A4%ED%94%84%EC%8A%A4%ED%81%AC%EB%A6%B0-%EC%BA%94%EB%B2%84%EC%8A%A4%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EA%B0%9C%EC%84%A0\" class=\"hash-link\" aria-label=\"오프스크린 캔버스를 사용한 개선에 대한 직접 링크\" title=\"오프스크린 캔버스를 사용한 개선에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>이미 사용되고 있는 WebWorker API를 통해 새로운 스레드 생성하여 렌더링 처리를 시도할 수 있으며, 캔버스를 DOM에서 분리할 수 있습니다.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"등장-배경\">등장 배경<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EB%93%B1%EC%9E%A5-%EB%B0%B0%EA%B2%BD\" class=\"hash-link\" aria-label=\"등장 배경에 대한 직접 링크\" title=\"등장 배경에 대한 직접 링크\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">자바스크립트 부하를 줄이기 위해 다른 스레드에서 실행할 수 있으면 좋겠음</li>\n<li class=\"\">크진 않지만 스키아의 부하를 줄이기 위해 다른 스레드에서 실행하면 좋겠음</li>\n<li class=\"\">DOM 렌더링과 분리되면 좋겠음</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"제약-사항\">제약 사항<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EC%A0%9C%EC%95%BD-%EC%82%AC%ED%95%AD\" class=\"hash-link\" aria-label=\"제약 사항에 대한 직접 링크\" title=\"제약 사항에 대한 직접 링크\" translate=\"no\">​</a></h4>\n<p>WebWorker에서는 직접적으로 DOM 엑세스가 불가능합니다.\n캔버스가 HTML(DOM)이기에 메인 스레드에서 분리가 불가능합니다.(HTML은 JS, CSS 등 다른 자원에서 DOM 트리 접근시 싱크가 맞아야 하는데, 다른 스레드에서 처리하게 되면 싱크 이슈가 발생함)\nReact, Vue와 같이 Shadow DOM을 사용하게 되면 Atomic 하게 처리할 수 있습니다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"개발-방식\">개발 방식<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EA%B0%9C%EB%B0%9C-%EB%B0%A9%EC%8B%9D\" class=\"hash-link\" aria-label=\"개발 방식에 대한 직접 링크\" title=\"개발 방식에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>OffscreenCanvas 객체에서 만들어진 프레임을 동기적으로 화면에 보여주는 방법</p>\n<ul>\n<li class=\"\">새 프레임이 컨텍스트에 렌더링이 되고나면, 가장 최근에 렌더링 된 이미지를 저장하는 transferToImageBitmap 메소드를 호출할 수 있습니다. 이 메소드는 다른 수 많은 Web API에서 사용되고 있는 ImageBitmap 객체를 리턴합니다.</li>\n<li class=\"\">&lt;canvas&gt; 엘리먼트를 여러개 생성하여 더블버퍼링 구현을 할 필요가 없으며, 프레젠테이션 캔버스에 비트맵 복사가 일어나지 않기 때문에 성능상 이점이 있습니다.</li>\n</ul>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> one </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token dom variable\" style=\"color:#36acaa\">document</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getElementById</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"one\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getContext</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"bitmaprenderer\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> two </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token dom variable\" style=\"color:#36acaa\">document</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getElementById</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"two\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getContext</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"bitmaprenderer\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> offscreen </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">OffscreenCanvas</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">256</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">256</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> gl </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> offscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getContext</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'webgl'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// ... gl 컨텍스트를 이용해 첫 번째 캔버스에 무언가를 그립니다 ...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 첫 번째 캔버스에 렌더링을 수행합니다.</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> bitmapOne </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> offscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">transferToImageBitmap</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">one</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">transferFromImageBitmap</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">bitmapOne</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// ... gl 컨텍스트를 이용해 두 번째 캔버스에 무언가를 그립니다 ...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 두 번째 캔버스에 렌더링을 수행합니다.</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> bitmapTwo </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> offscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">transferToImageBitmap</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">two</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">transferFromImageBitmap</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">bitmapTwo</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>OffscreenCanvas 객체에서 만들어진 프레임을 비동기적으로 화면에 보여주는 방법</p>\n<ul>\n<li class=\"\">worker 또는 메인 스레드 위에서 &lt;canvas&gt; 엘리먼트의 transferControlToOffscreen 메소드를 호출하여, OffscreenCanvas 객체를 얻고, 해당 컨텍스트는 worker에서 새 프레임을 렌더링 할 수 있습니다.</li>\n</ul>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// main.js (메인 스레드 코드)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> htmlCanvas </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token dom variable\" style=\"color:#36acaa\">document</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getElementById</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"canvas\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> offscreen </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> htmlCanvas</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">transferControlToOffscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> worker </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">Worker</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"offscreencanvas.js\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">worker</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">postMessage</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token literal-property property\" style=\"color:#36acaa\">canvas</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> offscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">offscreen</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// offscreencanvas.js (worker 코드)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function-variable function\" style=\"color:#d73a49\">onmessage</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">evt</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> canvas </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> evt</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">canvas</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> gl </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> canvas</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">getContext</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"webgl\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">render</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">time</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// ... gl 컨텍스트를 이용해 무언가를 그립니다 ...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">requestAnimationFrame</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">render</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token function\" style=\"color:#d73a49\">requestAnimationFrame</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">render</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"데모\">데모<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EB%8D%B0%EB%AA%A8\" class=\"hash-link\" aria-label=\"데모에 대한 직접 링크\" title=\"데모에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p><a href=\"https://codesandbox.io/p/github/seogi1004/vue3-vite-starter/main\" target=\"_blank\">데모 화면</a>은 다음과 같이 구성되어 있습니다.</p>\n<ul>\n<li class=\"\">일반 캔버스 샘플</li>\n<li class=\"\">메인 스레드에서 동작하는 오프스크린 캔버스 샘플</li>\n<li class=\"\">worker에서 동작하는 오프스크린 캔버스 샘플</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/3-b32711c95c5cb9d580c7e4e212ac3a42.gif\" width=\"1680\" height=\"902\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결론\">결론<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EA%B2%B0%EB%A1%A0\" class=\"hash-link\" aria-label=\"결론에 대한 직접 링크\" title=\"결론에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">기존의 캔버스 관련 코드는 고치지 않고, WebWorker로만 옮겨가서 그대로 사용할 수 있습니다. 다만, 이벤트 처리와 데이터 가져오는 방식에 대한 고민이 필요합니다.</li>\n<li class=\"\">메인 스레드와 worker 간의 데이터 전송을 위한 postMessage 함수 사용은 지양해야 합니다.</li>\n<li class=\"\">postMessage 함수 사용시 정책상의 이유로 데이터 복사본이 생성되는데, 이때 오버헤드가 발생합니다. (WebWorker API를 사용하지 않는 가장 큰 이유) 그래서 데이터 가져오는 코드를 worker 안에서 처리하면 좋습니다.</li>\n<li class=\"\">웹팩 같은 번들러의 도움으로 worker 안에서 미리 작성한 모듈 재사용이 가능합니다.</li>\n<li class=\"\">Zero-copy 백그라운드 렌더링을 오프스크린 캔버스로 구현할 수 있습니다.</li>\n<li class=\"\">크롬 69 버전과 파이어폭스 105 버전(지난 달인 9월 20일 릴리즈)부터 지원됩니다. 오프스크린 캔버스의 사용률은 공개된 이후부터 지속적으로 증가해서 현재는 25%가 넘었습니다. 많은 프론트엔드 개발자들이 캔버스의 문제점을 인식하고, 개선하기 위한 방법으로 오프스크린 캔버스를 선택한 것이라고 생각합니다.</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/4-343654b695b6e5ff49ee74c332e28fcc.webp\" width=\"1400\" height=\"228\" class=\"img_ev3q\"></p>\n<ul>\n<li class=\"\">Three.js에서 오프스크린 캔버스를 사용할 수 있습니다.</li>\n<li class=\"\">WebGL 및 WebXR을 오프스크린 캔버스로 구현할 수 있습니다.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고\">참고<a href=\"https://alvin.ing/blog/offscreen-canvas-api#%EC%B0%B8%EA%B3%A0\" class=\"hash-link\" aria-label=\"참고에 대한 직접 링크\" title=\"참고에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><a href=\"https://tv.naver.com/v/4578450\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://tv.naver.com/v/4578450</a></li>\n<li class=\"\"><a href=\"https://tech.kakao.com/2021/06/02/frontend-growth-09/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://tech.kakao.com/2021/06/02/frontend-growth-09/</a></li>\n</ul>",
            "url": "https://alvin.ing/blog/offscreen-canvas-api",
            "title": "OffscreenCanvas API 살펴보기",
            "summary": "캔버스 애니메이션의 문제점",
            "date_modified": "2022-11-15T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Canvas",
                "OffscreenCanvas"
            ]
        },
        {
            "id": "https://alvin.ing/blog/d3-scale",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"개요\">개요<a href=\"https://alvin.ing/blog/d3-scale#%EA%B0%9C%EC%9A%94\" class=\"hash-link\" aria-label=\"개요에 대한 직접 링크\" title=\"개요에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>D3 스케일(=척도)은 시각화의 기본 작업을 위한 편리한 추상화 모델입니다.\n추상 데이터의 차원을 시각적 표현으로 매핑합니다.\n예를 들어 산점도 차트에서 x축과 y축에 대한 값을 픽셀 단위로 변경하는 것처럼 정량적 데이터를 좌표 값으로 변경하는 데 가장 많이 사용됩니다.\n스케일은 색상, 선, 폭 또는 심볼 크기와 같은 거의 모든 시각적 인코딩을 나타낼 수 있습니다.\n또한 정의된 범주형 데이터 또는 구분이 필요한 개별 데이터와 같은 거의 모든 유형의 데이터와 함께 사용할 수 있습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalelinear-선형\">scaleLinear (선형)<a href=\"https://alvin.ing/blog/d3-scale#scalelinear-%EC%84%A0%ED%98%95\" class=\"hash-link\" aria-label=\"scaleLinear (선형)에 대한 직접 링크\" title=\"scaleLinear (선형)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>가장 보편적으로 사용하는 스케일이며, 다른 스케일과 마찬가지로 domain(정의역)과 range(치역)만 기억하면 됩니다.\ndomain은 입력 값, range는 입력 값에 대응하는 출력 값입니다.\ninvert는 반대로 출력 값을 입력 값으로 넣으면 원래의 입력 값을 반환하는 역함수입니다.</p>\n<blockquote>\n<p>y = mx + b</p>\n</blockquote>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleLinear</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">80</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 16;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">5</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 40;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">6</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 48</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">15</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 120</span><br></div></code></pre></div></div>\n<div class=\"scale\"><div class=\"column-list\"><div class=\"column\" style=\"background-color:gray;width:100px;height:16px;left:0\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:40px;left:100px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:48px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:120px;left:300px\"></div></div><h3>clamp(true)</h3><div class=\"column-list\"><div class=\"column\" style=\"background-color:gray;width:100px;height:16px;left:0\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:40px;left:100px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:48px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:80px;left:300px\"></div></div><h3>ticks(3)</h3><div class=\"column-list\"><div class=\"tick\" style=\"top:2px\">0</div><div class=\"tick\" style=\"top:42px\">5</div><div class=\"tick\" style=\"top:82px\">10</div><div class=\"column\" style=\"background-color:gray;width:100px;height:16px;left:0\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:40px;left:100px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:48px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:80px;left:300px\"></div></div><h3>invert</h3><div class=\"column-list\"><div class=\"tick\" style=\"top:2px\">0</div><div class=\"column\" style=\"background-color:gray;width:100px;height:16px;left:0\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:40px;left:100px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:48px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;height:80px;left:300px\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalepower-지수\">scalePower (지수)<a href=\"https://alvin.ing/blog/d3-scale#scalepower-%EC%A7%80%EC%88%98\" class=\"hash-link\" aria-label=\"scalePower (지수)에 대한 직접 링크\" title=\"scalePower (지수)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>결과 값을 보간하기 위해 제공되는 함수이며, 지수(exponent)에 따라 결과 값을 서서히 늘리거나 줄일 수 있습니다.</p>\n<blockquote>\n<p>y = mx^k + b</p>\n</blockquote>\n<p>거듭제곱을 하다보면 기하급수적으로 값이 커지기 때문에 D3 스케일에서는 domain 범위에 맞게 별도의 보정을 합니다.\n(Math.pow(입력값, exponent) / Math.pow(최대값, exponent - 1))</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleLinear</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 10;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">25</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 20;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 30</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">75</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 40</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// return 50</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func2 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scalePow</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">exponent</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0.5</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func3 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleSqrt</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func4 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scalePow</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">exponent</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><div class=\"point-list flex\"><div class=\"point\" style=\"width:10px;height:10px;left:0\"></div><div class=\"point\" style=\"width:20px;height:20px;left:87px\"></div><div class=\"point\" style=\"width:30px;height:30px;left:174px\"></div><div class=\"point\" style=\"width:40px;height:40px;left:261px\"></div><div class=\"point\" style=\"width:50px;height:50px;left:348px\"></div></div><h3>exponent(0.5)</h3><div class=\"point-list flex\"><div class=\"point\" style=\"width:10px;height:10px;left:0\"></div><div class=\"point\" style=\"width:30px;height:30px;left:87px\"></div><div class=\"point\" style=\"width:38.2842712474619px;height:38.2842712474619px;left:174px\"></div><div class=\"point\" style=\"width:44.64101615137755px;height:44.64101615137755px;left:261px\"></div><div class=\"point\" style=\"width:50px;height:50px;left:348px\"></div></div><h3>sqrt</h3><div class=\"point-list flex\"><div class=\"point\" style=\"width:10px;height:10px;left:0\"></div><div class=\"point\" style=\"width:30px;height:30px;left:87px\"></div><div class=\"point\" style=\"width:38.2842712474619px;height:38.2842712474619px;left:174px\"></div><div class=\"point\" style=\"width:44.64101615137755px;height:44.64101615137755px;left:261px\"></div><div class=\"point\" style=\"width:50px;height:50px;left:348px\"></div></div><h3>exponent(2)</h3><div class=\"point-list\"><div class=\"point\" style=\"width:10px;height:10px;left:0\"></div><div class=\"point\" style=\"width:12.5px;height:12.5px;left:87px\"></div><div class=\"point\" style=\"width:20px;height:20px;left:174px\"></div><div class=\"point\" style=\"width:32.5px;height:32.5px;left:261px\"></div><div class=\"point\" style=\"width:50px;height:50px;left:348px\"></div></div><br><h3>linear colors</h3><div class=\"colors\"><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 252, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 250, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 247, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 245, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 242, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 240, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 237, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 235, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 232, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 230, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 227, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 224, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 222, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 219, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 217, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 214, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 212, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 209, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 207, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 204, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 201, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 199, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 196, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 194, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 191, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 189, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 186, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 184, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 181, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 179, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 176, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 173, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 171, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 168, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 166, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 163, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 161, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 158, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 156, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 153, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 150, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 148, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 145, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 143, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 140, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 138, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 135, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 133, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 130, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 128, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 125, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 122, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 120, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 117, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 115, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 112, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 110, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 107, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 105, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 102, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 99, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 97, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 94, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 92, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 89, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 87, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 84, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 82, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 79, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 77, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 74, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 71, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 69, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 66, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 64, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 61, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 59, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 56, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 54, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 51, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 48, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 46, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 43, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 41, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 38, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 36, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 33, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 31, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 28, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 26, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 23, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 20, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 18, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 15, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 13, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 10, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 8, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 5, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 3, 0)\"></div></div><h3>sqrt or exponent(0.5) colors</h3><div class=\"colors\"><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 230, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 219, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 211, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 204, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 198, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 193, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 188, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 183, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 179, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 174, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 170, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 167, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 163, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 160, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 156, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 153, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 150, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 147, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 144, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 141, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 138, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 135, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 133, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 130, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 128, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 125, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 122, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 120, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 118, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 115, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 113, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 111, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 109, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 106, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 104, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 102, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 100, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 98, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 96, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 94, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 92, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 90, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 88, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 86, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 84, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 82, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 80, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 78, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 77, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 75, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 73, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 71, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 69, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 68, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 66, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 64, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 62, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 61, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 59, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 57, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 56, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 54, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 53, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 51, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 49, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 48, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 46, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 45, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 43, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 42, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 40, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 39, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 37, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 36, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 34, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 33, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 31, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 30, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 28, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 27, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 26, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 24, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 23, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 21, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 20, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 19, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 17, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 16, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 14, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 13, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 12, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 10, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 9, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 8, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 6, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 5, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 4, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 3, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 1, 0)\"></div></div><h3>exponent(2) colors</h3><div class=\"colors\"><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 255, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 254, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 254, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 254, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 253, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 253, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 252, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 252, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 251, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 251, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 250, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 249, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 248, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 248, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 247, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 246, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 245, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 244, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 243, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 242, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 240, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 239, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 238, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 236, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 235, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 234, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 232, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 230, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 229, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 227, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 226, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 224, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 222, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 220, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 218, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 216, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 214, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 212, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 210, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 208, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 206, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 203, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 201, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 199, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 196, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 194, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 191, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 189, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 186, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 183, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 181, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 178, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 175, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 172, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 169, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 166, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 163, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 160, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 157, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 154, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 151, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 147, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 144, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 141, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 137, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 134, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 130, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 126, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 123, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 119, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 115, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 112, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 108, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 104, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 100, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 96, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 92, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 88, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 84, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 79, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 75, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 71, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 66, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 62, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 58, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 53, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 48, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 44, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 39, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 34, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 30, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 25, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 20, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 15, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 10, 0)\"></div><div class=\"color\" style=\"background-color:rgb(255, 5, 0)\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalelog-scalesymlog-로그\">scaleLog, scaleSymlog (로그)<a href=\"https://alvin.ing/blog/d3-scale#scalelog-scalesymlog-%EB%A1%9C%EA%B7%B8\" class=\"hash-link\" aria-label=\"scaleLog, scaleSymlog (로그)에 대한 직접 링크\" title=\"scaleLog, scaleSymlog (로그)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>최대값이 극단적으로 클 경우, 결과값의 분포를 비교적 완만하게 보정해주는 스케일입니다.\nSymlog 함수는 대칭 로그를 의미하며, 양수 및 음수 값을 허용합니다.</p>\n<blockquote>\n<p>y = mlog(x) + b</p>\n</blockquote>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> data </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10000</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1000000</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><h3>linear</h3><div class=\"bar-list\"><div class=\"bar\" style=\"width:10px\"></div><div class=\"bar\" style=\"width:10.0005310000531px\"></div><div class=\"bar\" style=\"width:10.0589410058941px\"></div><div class=\"bar\" style=\"width:15.899941589994159px\"></div><div class=\"bar\" style=\"width:600px\"></div></div><h3>log</h3><div class=\"bar-list\"><div class=\"bar\" style=\"width:10px\"></div><div class=\"bar\" style=\"width:94.28571428571429px\"></div><div class=\"bar\" style=\"width:262.8571428571429px\"></div><div class=\"bar\" style=\"width:431.42857142857133px\"></div><div class=\"bar\" style=\"width:600px\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scaleband-밴드\">scaleBand (밴드)<a href=\"https://alvin.ing/blog/d3-scale#scaleband-%EB%B0%B4%EB%93%9C\" class=\"hash-link\" aria-label=\"scaleBand (밴드)에 대한 직접 링크\" title=\"scaleBand (밴드)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>Linear 스케일과 비슷하게 동작하지만 domain 사이에 여백(padding)을 비율로 설정할 수 있으며, 일반적으로 바나 컬럼 차트를 구현할 때, 사용하는 목적으로 만들어졌습니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/scale-band-b3aca3353b28b33de9ddc0f419c891aa.png\" width=\"1576\" height=\"424\" class=\"img_ev3q\"></p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">DOMAIN</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">3</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:#36acaa\">RANGE</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">400</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func1 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleBand</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">DOMAIN</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">RANGE</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func2 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleBand</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">DOMAIN</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">RANGE</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">paddingInner</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0.6</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func3 </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleBand</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">DOMAIN</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token constant\" style=\"color:#36acaa\">RANGE</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">paddingOuter</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0.2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">align</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0.5</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 0이면 맨 왼쪽으로 당김</span><br></div></code></pre></div></div>\n<div class=\"scale\"><h3>no padding <small>(step:<!-- -->100<!-- -->)</small></h3><div class=\"column-list\"><div class=\"column\" style=\"background-color:red;width:100px;left:0\"></div><div class=\"column\" style=\"background-color:green;width:100px;left:100px\"></div><div class=\"column\" style=\"background-color:blue;width:100px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:100px;left:300px\"></div></div><h3>inner padding <small>(step:<!-- -->117.64705882352942<!-- -->)</small></h3><div class=\"column-list\"><div class=\"column\" style=\"background-color:red;width:47.05882352941177px;left:0\"></div><div class=\"column\" style=\"background-color:green;width:47.05882352941177px;left:117.64705882352942px\"></div><div class=\"column\" style=\"background-color:blue;width:47.05882352941177px;left:235.29411764705884px\"></div><div class=\"column\" style=\"background-color:gray;width:47.05882352941177px;left:352.9411764705883px\"></div></div><h3>outer padding <small>(step:<!-- -->90.9090909090909<!-- -->)</small></h3><div class=\"column-list\"><div class=\"column\" style=\"background-color:red;width:90.9090909090909px;left:18.181818181818187px\"></div><div class=\"column\" style=\"background-color:green;width:90.9090909090909px;left:109.0909090909091px\"></div><div class=\"column\" style=\"background-color:blue;width:90.9090909090909px;left:200px\"></div><div class=\"column\" style=\"background-color:gray;width:90.9090909090909px;left:290.90909090909093px\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalepoint-점\">scalePoint (점)<a href=\"https://alvin.ing/blog/d3-scale#scalepoint-%EC%A0%90\" class=\"hash-link\" aria-label=\"scalePoint (점)에 대한 직접 링크\" title=\"scalePoint (점)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>Band 스케일과 달리 domain 개별로 여백이 적용되며, bandwidth 개념이 없고, (최대 range/domain 수)로 시작점을 정합니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/scale-point-40ee5388a138bd92871868b99397ec17.png\" width=\"1448\" height=\"350\" class=\"img_ev3q\"></p>\n<div class=\"scale\"><h3>no padding <small>(step:<!-- -->133.33333333333334<!-- -->)</small></h3><div class=\"point-list\"><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:0\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:133.33333333333334px\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:266.6666666666667px\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:400px\"></div></div><h3>padding <small>(step:<!-- -->125<!-- -->)</small></h3><div class=\"point-list\"><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:12.5px\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:137.5px\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:262.5px\"></div><div class=\"point\" style=\"margin-left:-10px;width:20px;height:20px;left:387.5px\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scaletime-시간\">scaleTime (시간)<a href=\"https://alvin.ing/blog/d3-scale#scaletime-%EC%8B%9C%EA%B0%84\" class=\"hash-link\" aria-label=\"scaleTime (시간)에 대한 직접 링크\" title=\"scaleTime (시간)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>Linear 스케일과 동일하지만 domain 범위를 Date 객체로 정할 수 있습니다.\n앞에서 설명한 ticks 함수를 사용하여 X축을 구현하고, 마우스 오버시 구해지는 실제 좌표값을 invert 함수로 넘겨서 현재 시간을 구합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> now </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> Date</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> start </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">now </span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1000</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">60</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">60</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> end </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">Date</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">now</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleTime</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">start</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> end</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">600</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><div class=\"timeline\"><div class=\"container\"><div class=\"line\" style=\"left:8.2385px\"></div><div class=\"line\" style=\"left:58.2385px\"></div><div class=\"line\" style=\"left:108.23849999999999px\"></div><div class=\"line\" style=\"left:158.23850000000002px\"></div><div class=\"line\" style=\"left:208.23850000000002px\"></div><div class=\"line\" style=\"left:258.2385px\"></div><div class=\"line\" style=\"left:308.2385px\"></div><div class=\"line\" style=\"left:358.2385px\"></div><div class=\"line\" style=\"left:408.2385px\"></div><div class=\"line\" style=\"left:458.2385px\"></div><div class=\"line\" style=\"left:508.2385px\"></div><div class=\"line\" style=\"left:558.2385px\"></div><div class=\"line\" style=\"left:600px;background-color:#000\"><span>7:44:10 AM</span></div></div><div class=\"text\" style=\"left:-4.7615px\">06:45</div><div class=\"text\" style=\"left:45.2385px\">06:50</div><div class=\"text\" style=\"left:95.23849999999999px\">06:55</div><div class=\"text\" style=\"left:145.23850000000002px\">07:00</div><div class=\"text\" style=\"left:195.23850000000002px\">07:05</div><div class=\"text\" style=\"left:245.2385px\">07:10</div><div class=\"text\" style=\"left:295.2385px\">07:15</div><div class=\"text\" style=\"left:345.2385px\">07:20</div><div class=\"text\" style=\"left:395.2385px\">07:25</div><div class=\"text\" style=\"left:445.2385px\">07:30</div><div class=\"text\" style=\"left:495.2385px\">07:35</div><div class=\"text\" style=\"left:545.2385px\">07:40</div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalesequential-연속\">scaleSequential (연속)<a href=\"https://alvin.ing/blog/d3-scale#scalesequential-%EC%97%B0%EC%86%8D\" class=\"hash-link\" aria-label=\"scaleSequential (연속)에 대한 직접 링크\" title=\"scaleSequential (연속)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>보간기(Interpolator) 함수로 정의된 연속된 값에 매핑합니다.\n고유한 보간기 기능을 정의하거나 내장된 D3 보간기 기능을 사용할 수 있습니다.\n일반적으로 숫자값의 연속 간격을 일련의 색상으로 매핑하는데 유용합니다.</p>\n<blockquote>\n<p>scaleSequential 함수는 선형적으로 매핑하는데, 앞에서 설명한 다른 스케일 방식으로 매핑하는 함수도 제공됩니다.\n(scaleSequentialLog, scaleSequentialSymlog, scaleSequentialPow, scaleSequentialSqrt, scaleSequentialQuantile)</p>\n</blockquote>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> interpolateRainbow </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'d3-scale-chromatic'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleSequential</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">interpolator</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">interpolateRainbow</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><div class=\"colors\"><div class=\"color\" style=\"background-color:rgb(110, 64, 170)\"></div><div class=\"color\" style=\"background-color:rgb(117, 63, 173)\"></div><div class=\"color\" style=\"background-color:rgb(125, 63, 175)\"></div><div class=\"color\" style=\"background-color:rgb(134, 62, 177)\"></div><div class=\"color\" style=\"background-color:rgb(142, 62, 178)\"></div><div class=\"color\" style=\"background-color:rgb(150, 61, 179)\"></div><div class=\"color\" style=\"background-color:rgb(158, 61, 179)\"></div><div class=\"color\" style=\"background-color:rgb(167, 60, 179)\"></div><div class=\"color\" style=\"background-color:rgb(175, 60, 178)\"></div><div class=\"color\" style=\"background-color:rgb(183, 60, 177)\"></div><div class=\"color\" style=\"background-color:rgb(191, 60, 175)\"></div><div class=\"color\" style=\"background-color:rgb(199, 61, 172)\"></div><div class=\"color\" style=\"background-color:rgb(207, 61, 169)\"></div><div class=\"color\" style=\"background-color:rgb(214, 62, 166)\"></div><div class=\"color\" style=\"background-color:rgb(221, 63, 162)\"></div><div class=\"color\" style=\"background-color:rgb(228, 65, 157)\"></div><div class=\"color\" style=\"background-color:rgb(234, 66, 153)\"></div><div class=\"color\" style=\"background-color:rgb(240, 68, 148)\"></div><div class=\"color\" style=\"background-color:rgb(245, 70, 142)\"></div><div class=\"color\" style=\"background-color:rgb(250, 73, 136)\"></div><div class=\"color\" style=\"background-color:rgb(254, 75, 131)\"></div><div class=\"color\" style=\"background-color:rgb(255, 78, 124)\"></div><div class=\"color\" style=\"background-color:rgb(255, 82, 118)\"></div><div class=\"color\" style=\"background-color:rgb(255, 86, 112)\"></div><div class=\"color\" style=\"background-color:rgb(255, 90, 106)\"></div><div class=\"color\" style=\"background-color:rgb(255, 94, 99)\"></div><div class=\"color\" style=\"background-color:rgb(255, 99, 93)\"></div><div class=\"color\" style=\"background-color:rgb(255, 103, 87)\"></div><div class=\"color\" style=\"background-color:rgb(255, 109, 81)\"></div><div class=\"color\" style=\"background-color:rgb(255, 114, 76)\"></div><div class=\"color\" style=\"background-color:rgb(255, 120, 71)\"></div><div class=\"color\" style=\"background-color:rgb(255, 125, 66)\"></div><div class=\"color\" style=\"background-color:rgb(255, 131, 61)\"></div><div class=\"color\" style=\"background-color:rgb(255, 138, 57)\"></div><div class=\"color\" style=\"background-color:rgb(255, 144, 54)\"></div><div class=\"color\" style=\"background-color:rgb(251, 150, 51)\"></div><div class=\"color\" style=\"background-color:rgb(246, 157, 49)\"></div><div class=\"color\" style=\"background-color:rgb(242, 164, 47)\"></div><div class=\"color\" style=\"background-color:rgb(237, 170, 46)\"></div><div class=\"color\" style=\"background-color:rgb(231, 177, 46)\"></div><div class=\"color\" style=\"background-color:rgb(226, 183, 47)\"></div><div class=\"color\" style=\"background-color:rgb(220, 190, 48)\"></div><div class=\"color\" style=\"background-color:rgb(215, 196, 50)\"></div><div class=\"color\" style=\"background-color:rgb(209, 202, 52)\"></div><div class=\"color\" style=\"background-color:rgb(204, 208, 56)\"></div><div class=\"color\" style=\"background-color:rgb(198, 214, 60)\"></div><div class=\"color\" style=\"background-color:rgb(193, 220, 65)\"></div><div class=\"color\" style=\"background-color:rgb(188, 225, 70)\"></div><div class=\"color\" style=\"background-color:rgb(183, 230, 76)\"></div><div class=\"color\" style=\"background-color:rgb(179, 235, 83)\"></div><div class=\"color\" style=\"background-color:rgb(175, 240, 91)\"></div><div class=\"color\" style=\"background-color:rgb(166, 241, 89)\"></div><div class=\"color\" style=\"background-color:rgb(156, 243, 87)\"></div><div class=\"color\" style=\"background-color:rgb(146, 244, 87)\"></div><div class=\"color\" style=\"background-color:rgb(136, 245, 87)\"></div><div class=\"color\" style=\"background-color:rgb(127, 246, 88)\"></div><div class=\"color\" style=\"background-color:rgb(117, 246, 90)\"></div><div class=\"color\" style=\"background-color:rgb(108, 246, 92)\"></div><div class=\"color\" style=\"background-color:rgb(99, 247, 95)\"></div><div class=\"color\" style=\"background-color:rgb(90, 246, 99)\"></div><div class=\"color\" style=\"background-color:rgb(82, 246, 103)\"></div><div class=\"color\" style=\"background-color:rgb(74, 245, 108)\"></div><div class=\"color\" style=\"background-color:rgb(67, 244, 113)\"></div><div class=\"color\" style=\"background-color:rgb(60, 242, 118)\"></div><div class=\"color\" style=\"background-color:rgb(54, 241, 124)\"></div><div class=\"color\" style=\"background-color:rgb(48, 239, 130)\"></div><div class=\"color\" style=\"background-color:rgb(43, 236, 137)\"></div><div class=\"color\" style=\"background-color:rgb(39, 233, 143)\"></div><div class=\"color\" style=\"background-color:rgb(35, 230, 150)\"></div><div class=\"color\" style=\"background-color:rgb(32, 226, 156)\"></div><div class=\"color\" style=\"background-color:rgb(29, 223, 163)\"></div><div class=\"color\" style=\"background-color:rgb(27, 219, 170)\"></div><div class=\"color\" style=\"background-color:rgb(26, 214, 176)\"></div><div class=\"color\" style=\"background-color:rgb(25, 209, 182)\"></div><div class=\"color\" style=\"background-color:rgb(25, 205, 188)\"></div><div class=\"color\" style=\"background-color:rgb(26, 199, 194)\"></div><div class=\"color\" style=\"background-color:rgb(27, 194, 199)\"></div><div class=\"color\" style=\"background-color:rgb(28, 188, 204)\"></div><div class=\"color\" style=\"background-color:rgb(30, 183, 209)\"></div><div class=\"color\" style=\"background-color:rgb(33, 177, 213)\"></div><div class=\"color\" style=\"background-color:rgb(35, 171, 216)\"></div><div class=\"color\" style=\"background-color:rgb(39, 165, 219)\"></div><div class=\"color\" style=\"background-color:rgb(42, 159, 222)\"></div><div class=\"color\" style=\"background-color:rgb(46, 152, 223)\"></div><div class=\"color\" style=\"background-color:rgb(50, 146, 225)\"></div><div class=\"color\" style=\"background-color:rgb(54, 140, 225)\"></div><div class=\"color\" style=\"background-color:rgb(58, 134, 225)\"></div><div class=\"color\" style=\"background-color:rgb(63, 128, 225)\"></div><div class=\"color\" style=\"background-color:rgb(67, 122, 224)\"></div><div class=\"color\" style=\"background-color:rgb(72, 116, 222)\"></div><div class=\"color\" style=\"background-color:rgb(76, 110, 219)\"></div><div class=\"color\" style=\"background-color:rgb(81, 105, 217)\"></div><div class=\"color\" style=\"background-color:rgb(85, 99, 213)\"></div><div class=\"color\" style=\"background-color:rgb(89, 94, 209)\"></div><div class=\"color\" style=\"background-color:rgb(93, 89, 205)\"></div><div class=\"color\" style=\"background-color:rgb(96, 84, 200)\"></div><div class=\"color\" style=\"background-color:rgb(100, 80, 195)\"></div><div class=\"color\" style=\"background-color:rgb(103, 75, 189)\"></div><div class=\"color\" style=\"background-color:rgb(105, 71, 183)\"></div><div class=\"color\" style=\"background-color:rgb(108, 67, 177)\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalediverging-양방향\">scaleDiverging (양방향)<a href=\"https://alvin.ing/blog/d3-scale#scalediverging-%EC%96%91%EB%B0%A9%ED%96%A5\" class=\"hash-link\" aria-label=\"scaleDiverging (양방향)에 대한 직접 링크\" title=\"scaleDiverging (양방향)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>양수와 음수, 위쪽과 아래쪽의 두가지 반대 방향으로 진행되는 현상을 시각화하는데 도움이 됩니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"> interpolateRdBu </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'d3-scale-chromatic'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleDiverging</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">50</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">interpolator</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">interpolateRdBu</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"colors\"><div class=\"color\" style=\"background-color:rgb(103, 0, 31)\"></div><div class=\"color\" style=\"background-color:rgb(110, 2, 32)\"></div><div class=\"color\" style=\"background-color:rgb(118, 5, 33)\"></div><div class=\"color\" style=\"background-color:rgb(125, 7, 35)\"></div><div class=\"color\" style=\"background-color:rgb(133, 10, 36)\"></div><div class=\"color\" style=\"background-color:rgb(140, 13, 37)\"></div><div class=\"color\" style=\"background-color:rgb(147, 16, 39)\"></div><div class=\"color\" style=\"background-color:rgb(153, 20, 41)\"></div><div class=\"color\" style=\"background-color:rgb(160, 23, 42)\"></div><div class=\"color\" style=\"background-color:rgb(166, 27, 44)\"></div><div class=\"color\" style=\"background-color:rgb(172, 32, 47)\"></div><div class=\"color\" style=\"background-color:rgb(177, 37, 49)\"></div><div class=\"color\" style=\"background-color:rgb(182, 42, 52)\"></div><div class=\"color\" style=\"background-color:rgb(187, 48, 55)\"></div><div class=\"color\" style=\"background-color:rgb(191, 54, 58)\"></div><div class=\"color\" style=\"background-color:rgb(195, 61, 61)\"></div><div class=\"color\" style=\"background-color:rgb(199, 68, 64)\"></div><div class=\"color\" style=\"background-color:rgb(203, 74, 68)\"></div><div class=\"color\" style=\"background-color:rgb(206, 81, 72)\"></div><div class=\"color\" style=\"background-color:rgb(210, 88, 76)\"></div><div class=\"color\" style=\"background-color:rgb(213, 96, 80)\"></div><div class=\"color\" style=\"background-color:rgb(216, 103, 85)\"></div><div class=\"color\" style=\"background-color:rgb(219, 110, 89)\"></div><div class=\"color\" style=\"background-color:rgb(223, 116, 94)\"></div><div class=\"color\" style=\"background-color:rgb(226, 123, 99)\"></div><div class=\"color\" style=\"background-color:rgb(228, 130, 104)\"></div><div class=\"color\" style=\"background-color:rgb(231, 137, 110)\"></div><div class=\"color\" style=\"background-color:rgb(234, 143, 115)\"></div><div class=\"color\" style=\"background-color:rgb(236, 150, 121)\"></div><div class=\"color\" style=\"background-color:rgb(238, 156, 127)\"></div><div class=\"color\" style=\"background-color:rgb(241, 163, 133)\"></div><div class=\"color\" style=\"background-color:rgb(242, 169, 139)\"></div><div class=\"color\" style=\"background-color:rgb(244, 174, 145)\"></div><div class=\"color\" style=\"background-color:rgb(245, 180, 152)\"></div><div class=\"color\" style=\"background-color:rgb(247, 186, 158)\"></div><div class=\"color\" style=\"background-color:rgb(248, 191, 164)\"></div><div class=\"color\" style=\"background-color:rgb(249, 196, 171)\"></div><div class=\"color\" style=\"background-color:rgb(249, 201, 177)\"></div><div class=\"color\" style=\"background-color:rgb(250, 206, 183)\"></div><div class=\"color\" style=\"background-color:rgb(250, 210, 190)\"></div><div class=\"color\" style=\"background-color:rgb(251, 215, 196)\"></div><div class=\"color\" style=\"background-color:rgb(251, 219, 201)\"></div><div class=\"color\" style=\"background-color:rgb(250, 222, 207)\"></div><div class=\"color\" style=\"background-color:rgb(250, 226, 212)\"></div><div class=\"color\" style=\"background-color:rgb(250, 229, 217)\"></div><div class=\"color\" style=\"background-color:rgb(249, 232, 221)\"></div><div class=\"color\" style=\"background-color:rgb(248, 234, 226)\"></div><div class=\"color\" style=\"background-color:rgb(247, 236, 229)\"></div><div class=\"color\" style=\"background-color:rgb(245, 237, 233)\"></div><div class=\"color\" style=\"background-color:rgb(244, 239, 236)\"></div><div class=\"color\" style=\"background-color:rgb(242, 239, 238)\"></div><div class=\"color\" style=\"background-color:rgb(239, 240, 240)\"></div><div class=\"color\" style=\"background-color:rgb(237, 239, 241)\"></div><div class=\"color\" style=\"background-color:rgb(234, 239, 242)\"></div><div class=\"color\" style=\"background-color:rgb(230, 238, 242)\"></div><div class=\"color\" style=\"background-color:rgb(227, 237, 242)\"></div><div class=\"color\" style=\"background-color:rgb(223, 235, 242)\"></div><div class=\"color\" style=\"background-color:rgb(219, 233, 241)\"></div><div class=\"color\" style=\"background-color:rgb(214, 231, 240)\"></div><div class=\"color\" style=\"background-color:rgb(210, 229, 239)\"></div><div class=\"color\" style=\"background-color:rgb(205, 227, 238)\"></div><div class=\"color\" style=\"background-color:rgb(200, 224, 237)\"></div><div class=\"color\" style=\"background-color:rgb(194, 221, 235)\"></div><div class=\"color\" style=\"background-color:rgb(189, 219, 234)\"></div><div class=\"color\" style=\"background-color:rgb(183, 216, 232)\"></div><div class=\"color\" style=\"background-color:rgb(177, 212, 231)\"></div><div class=\"color\" style=\"background-color:rgb(170, 209, 229)\"></div><div class=\"color\" style=\"background-color:rgb(164, 206, 227)\"></div><div class=\"color\" style=\"background-color:rgb(157, 202, 225)\"></div><div class=\"color\" style=\"background-color:rgb(150, 198, 223)\"></div><div class=\"color\" style=\"background-color:rgb(143, 194, 221)\"></div><div class=\"color\" style=\"background-color:rgb(136, 190, 218)\"></div><div class=\"color\" style=\"background-color:rgb(129, 185, 216)\"></div><div class=\"color\" style=\"background-color:rgb(122, 181, 213)\"></div><div class=\"color\" style=\"background-color:rgb(114, 176, 211)\"></div><div class=\"color\" style=\"background-color:rgb(107, 172, 208)\"></div><div class=\"color\" style=\"background-color:rgb(100, 167, 206)\"></div><div class=\"color\" style=\"background-color:rgb(93, 162, 203)\"></div><div class=\"color\" style=\"background-color:rgb(87, 157, 201)\"></div><div class=\"color\" style=\"background-color:rgb(80, 153, 198)\"></div><div class=\"color\" style=\"background-color:rgb(75, 148, 196)\"></div><div class=\"color\" style=\"background-color:rgb(69, 143, 193)\"></div><div class=\"color\" style=\"background-color:rgb(64, 138, 191)\"></div><div class=\"color\" style=\"background-color:rgb(59, 134, 188)\"></div><div class=\"color\" style=\"background-color:rgb(55, 129, 185)\"></div><div class=\"color\" style=\"background-color:rgb(51, 124, 182)\"></div><div class=\"color\" style=\"background-color:rgb(47, 120, 179)\"></div><div class=\"color\" style=\"background-color:rgb(44, 115, 176)\"></div><div class=\"color\" style=\"background-color:rgb(40, 110, 172)\"></div><div class=\"color\" style=\"background-color:rgb(37, 105, 168)\"></div><div class=\"color\" style=\"background-color:rgb(34, 101, 163)\"></div><div class=\"color\" style=\"background-color:rgb(31, 96, 158)\"></div><div class=\"color\" style=\"background-color:rgb(28, 90, 153)\"></div><div class=\"color\" style=\"background-color:rgb(25, 85, 147)\"></div><div class=\"color\" style=\"background-color:rgb(22, 80, 140)\"></div><div class=\"color\" style=\"background-color:rgb(19, 75, 133)\"></div><div class=\"color\" style=\"background-color:rgb(16, 70, 126)\"></div><div class=\"color\" style=\"background-color:rgb(13, 64, 119)\"></div><div class=\"color\" style=\"background-color:rgb(11, 59, 112)\"></div><div class=\"color\" style=\"background-color:rgb(8, 53, 104)\"></div><div class=\"color\" style=\"background-color:rgb(5, 48, 97)\"></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scaleradial-방사형\">scaleRadial (방사형)<a href=\"https://alvin.ing/blog/d3-scale#scaleradial-%EB%B0%A9%EC%82%AC%ED%98%95\" class=\"hash-link\" aria-label=\"scaleRadial (방사형)에 대한 직접 링크\" title=\"scaleRadial (방사형)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>입력 값이 제곱된 출력 값에 선형적으로 대응하도록 범위가 내부적으로 제곱되는 Linear 스케일의 변형입니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> innerRadius </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">80</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> outerRadius </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">220</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> x </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleBand</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">map</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">row</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> row</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token plain\">name</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> Math</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token constant\" style=\"color:#36acaa\">PI</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> y </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleRadial</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1000</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">innerRadius</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> outerRadius</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> z </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">scaleSequential</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> Math</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token constant\" style=\"color:#36acaa\">PI</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">interpolator</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">interpolateRainbow</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><svg width=\"440\" height=\"440\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"80,0 79.96052482925853,2.5128607262502634 203.4390329374963,6.393329172695835 203.5394673778384,0 \" transform=\"translate(220 220)\" fill=\"rgb(110, 64, 170)\" stroke=\"#fff\"></polygon><polygon points=\"79.96052482925853,2.5128607262502634 79.84213827426173,5.02324156234507 186.58901687742656,11.739185910028931 186.86568320157335,5.872490674665217 \" transform=\"translate(220 220)\" fill=\"rgb(114, 64, 171)\" stroke=\"#fff\"></polygon><polygon points=\"79.84213827426173,5.02324156234507 79.6449571682464,7.528665065481146 195.84883297264386,18.51316541989749 196.33370597490787,12.352269782087236 \" transform=\"translate(220 220)\" fill=\"rgb(117, 63, 173)\" stroke=\"#fff\"></polygon><polygon points=\"79.6449571682464,7.528665065481146 79.36917610515823,10.02665868514434 186.45324080936285,23.554522020709342 187.10110280680266,17.68626145957894 \" transform=\"translate(220 220)\" fill=\"rgb(121, 63, 174)\" stroke=\"#fff\"></polygon><polygon points=\"79.36917610515823,10.02665868514434 79.01506724761103,12.514757203218469 197.8007596766513,31.32856261715452 198.68721087476993,25.10003185500051 \" transform=\"translate(220 220)\" fill=\"rgb(125, 63, 175)\" stroke=\"#fff\"></polygon><polygon points=\"79.01506724761103,12.514757203218469 78.58298005829509,14.990505166857968 163.12818751401124,31.118366037721056 164.02514509934133,25.979030805710032 \" transform=\"translate(220 220)\" fill=\"rgb(129, 62, 176)\" stroke=\"#fff\"></polygon><polygon points=\"78.58298005829509,14.99050516685797 78.0733409550998,17.451459311723404 158.419211295817,35.41088912429429 159.45332388515962,30.417348308755667 \" transform=\"translate(220 220)\" fill=\"rgb(134, 62, 177)\" stroke=\"#fff\"></polygon><polygon points=\"78.0733409550998,17.451459311723404 77.48665289029049,19.895190973188384 187.53918407282683,48.15187832887218 188.9591318557745,42.237370155019924 \" transform=\"translate(220 220)\" fill=\"rgb(138, 62, 178)\" stroke=\"#fff\"></polygon><polygon points=\"77.48665289029049,19.895190973188384 76.82349485415544,22.319288483138344 178.01494035419358,51.71812107242346 179.55160616811025,46.10101689790347 \" transform=\"translate(220 220)\" fill=\"rgb(142, 62, 178)\" stroke=\"#fff\"></polygon><polygon points=\"76.82349485415544,22.319288483138344 76.08452130361228,24.721359549995793 159.09383241733119,51.69271970156815 160.63903677948798,46.66995442398737 \" transform=\"translate(220 220)\" fill=\"rgb(146, 61, 179)\" stroke=\"#fff\"></polygon><polygon points=\"76.08452130361228,24.721359549995793 75.27046151633803,27.09903361962331 162.01538230019202,58.329126770347266 163.76759963742492,53.211318726984324 \" transform=\"translate(220 220)\" fill=\"rgb(150, 61, 179)\" stroke=\"#fff\"></polygon><polygon points=\"75.27046151633803,27.099033619623313 74.3821188710601,29.449964214774237 178.98920487841485,70.86683948379817 181.12686573227563,65.2096841844199 \" transform=\"translate(220 220)\" fill=\"rgb(154, 61, 179)\" stroke=\"#fff\"></polygon><polygon points=\"74.3821188710601,29.449964214774237 73.42037005471849,31.771831250782448 175.6419220781331,76.00704688181949 177.94269243018547,70.45249589398868 \" transform=\"translate(220 220)\" fill=\"rgb(158, 61, 179)\" stroke=\"#fff\"></polygon><polygon points=\"73.42037005471849,31.771831250782448 72.38616419728157,34.062343325205816 179.9350510515152,84.67100796294602 182.50584459775862,78.97733139345378 \" transform=\"translate(220 220)\" fill=\"rgb(162, 61, 179)\" stroke=\"#fff\"></polygon><polygon points=\"72.38616419728156,34.062343325205816 71.28052193506943,36.31923997916375 175.91974545956282,89.63558738022925 178.64846152472956,84.06558488705895 \" transform=\"translate(220 220)\" fill=\"rgb(167, 60, 179)\" stroke=\"#fff\"></polygon><polygon points=\"71.28052193506943,36.31923997916375 70.10453440350909,38.540293928137224 154.7940327640019,85.09873964369012 157.3906672618882,80.19455048284168 \" transform=\"translate(220 220)\" fill=\"rgb(171, 60, 178)\" stroke=\"#fff\"></polygon><polygon points=\"70.10453440350909,38.540293928137224 68.8593621603155,40.723313260029705 149.38360744003919,88.34521916614494 152.0848860423505,83.60937362998948 \" transform=\"translate(220 220)\" fill=\"rgb(175, 60, 178)\" stroke=\"#fff\"></polygon><polygon points=\"68.8593621603155,40.723313260029705 67.5462340401612,42.86614359831973 170.84450226413966,108.42121801614795 174.16579357348814,103.00136318954148 \" transform=\"translate(220 220)\" fill=\"rgb(179, 60, 177)\" stroke=\"#fff\"></polygon><polygon points=\"67.54623404016121,42.86614359831973 66.16644594196495,44.96667022817044 149.78752336130574,101.79549575913326 152.91108605308915,97.04032601772421 \" transform=\"translate(220 220)\" fill=\"rgb(183, 60, 177)\" stroke=\"#fff\"></polygon><polygon points=\"66.16644594196495,44.96667022817044 64.72135954999578,47.02282018339786 157.5364490558597,114.45692995003208 161.05389337953628,109.45211291706057 \" transform=\"translate(220 220)\" fill=\"rgb(187, 60, 176)\" stroke=\"#fff\"></polygon><polygon points=\"64.7213595499958,47.022820183397855 63.21240099005523,49.03256429223812 146.4753954926509,113.61796315653814 149.97194519472734,108.96099619165864 \" transform=\"translate(220 220)\" fill=\"rgb(191, 60, 175)\" stroke=\"#fff\"></polygon><polygon points=\"63.21240099005523,49.03256429223812 61.64105942206313,50.99391917989518 155.11165219177738,128.31951835169752 159.06572743081577,123.38402567828619 \" transform=\"translate(220 220)\" fill=\"rgb(195, 61, 173)\" stroke=\"#fff\"></polygon><polygon points=\"61.64105942206313,50.99391917989518 60.00888557043676,52.90494922589215 129.84579725951198,114.47446900420702 133.37745616328877,110.33942770906249 \" transform=\"translate(220 220)\" fill=\"rgb(199, 61, 172)\" stroke=\"#fff\"></polygon><polygon points=\"60.00888557043676,52.904949225892146 58.31749019371293,54.7637684742951 136.99883980248777,128.65047379901338 140.97224818286827,124.28375500525448 \" transform=\"translate(220 220)\" fill=\"rgb(203, 61, 171)\" stroke=\"#fff\"></polygon><polygon points=\"58.31749019371293,54.7637684742951 56.5685424949238,56.568542494923804 138.9760664232642,138.97606642326423 143.27283386392338,134.54214638382916 \" transform=\"translate(220 220)\" fill=\"rgb(207, 61, 169)\" stroke=\"#fff\"></polygon><polygon points=\"56.5685424949238,56.568542494923804 54.76376847429509,58.31749019371293 109.52753694859018,116.63498038742586 113.1370849898476,113.13708498984761 \" transform=\"translate(220 220)\" fill=\"rgb(210, 62, 167)\" stroke=\"#fff\"></polygon><polygon points=\"54.7637684742951,58.31749019371293 52.904949225892146,60.00888557043677 108.68298870570686,123.27665233826437 112.50157343806414,119.80200757789484 \" transform=\"translate(220 220)\" fill=\"rgb(214, 62, 166)\" stroke=\"#fff\"></polygon><polygon points=\"52.904949225892146,60.00888557043677 50.99391917989517,61.64105942206314 122.470724335131,148.04167472543034 127.06039380402962,144.12172667938268 \" transform=\"translate(220 220)\" fill=\"rgb(217, 63, 164)\" stroke=\"#fff\"></polygon><polygon points=\"50.99391917989517,61.64105942206314 49.032564292238106,63.21240099005523 106.50873819183003,137.31023789413678 110.76920136046348,133.89696326550995 \" transform=\"translate(220 220)\" fill=\"rgb(221, 63, 162)\" stroke=\"#fff\"></polygon><polygon points=\"49.03256429223812,63.21240099005523 47.02282018339784,64.7213595499958 118.32676786786433,162.8628240011179 123.38402567828619,159.06572743081577 \" transform=\"translate(220 220)\" fill=\"rgb(224, 64, 160)\" stroke=\"#fff\"></polygon><polygon points=\"47.02282018339784,64.7213595499958 44.966670228170436,66.16644594196495 101.09063217729586,148.75034809688324 105.71311139958526,145.5016152871443 \" transform=\"translate(220 220)\" fill=\"rgb(228, 65, 157)\" stroke=\"#fff\"></polygon><polygon points=\"44.96667022817044,66.16644594196495 42.866143598319724,67.54623404016121 92.99387863703099,146.53490525248606 97.55076437698933,143.54159080482222 \" transform=\"translate(220 220)\" fill=\"rgb(231, 65, 155)\" stroke=\"#fff\"></polygon><polygon points=\"42.866143598319724,67.54623404016121 40.7233132600297,68.8593621603155 96.15976978979742,162.59729091609273 101.21962507988275,159.49660760645446 \" transform=\"translate(220 220)\" fill=\"rgb(234, 66, 153)\" stroke=\"#fff\"></polygon><polygon points=\"40.7233132600297,68.8593621603155 38.54029392813721,70.10453440350909 97.23125877334029,176.863003133344 102.73868219782744,173.7216242735697 \" transform=\"translate(220 220)\" fill=\"rgb(237, 67, 150)\" stroke=\"#fff\"></polygon><polygon points=\"38.54029392813721,70.10453440350909 36.31923997916373,71.28052193506943 84.6985262232097,166.2302173664749 89.87814992261029,163.48774778734347 \" transform=\"translate(220 220)\" fill=\"rgb(240, 68, 148)\" stroke=\"#fff\"></polygon><polygon points=\"36.31923997916375,71.28052193506943 34.062343325205816,72.38616419728157 76.2166435357617,161.96861210845628 81.26659227620779,159.4946677478891 \" transform=\"translate(220 220)\" fill=\"rgb(242, 69, 145)\" stroke=\"#fff\"></polygon><polygon points=\"34.062343325205816,72.38616419728157 31.771831250782444,73.42037005471849 66.43535780994294,153.5230536956701 71.22485162385595,151.36051431776536 \" transform=\"translate(220 220)\" fill=\"rgb(245, 70, 142)\" stroke=\"#fff\"></polygon><polygon points=\"31.771831250782444,73.42037005471849 29.44996421477423,74.38211887106011 72.21900364206196,182.40438169899346 77.91282801165964,180.04592242333567 \" transform=\"translate(220 220)\" fill=\"rgb(248, 71, 139)\" stroke=\"#fff\"></polygon><polygon points=\"29.44996421477423,74.38211887106011 27.0990336196233,75.27046151633805 67.3019592734873,186.93838335994488 73.14062634149185,184.7321349242035 \" transform=\"translate(220 220)\" fill=\"rgb(250, 73, 136)\" stroke=\"#fff\"></polygon><polygon points=\"27.0990336196233,75.27046151633805 24.721359549995782,76.08452130361229 58.31479016132863,179.47446965335067 63.92344465955523,177.55419801223528 \" transform=\"translate(220 220)\" fill=\"rgb(252, 74, 134)\" stroke=\"#fff\"></polygon><polygon points=\"24.721359549995796,76.08452130361228 22.319288483138344,76.82349485415544 55.823785632102826,192.14673046084067 61.831714621892566,190.29845016711712 \" transform=\"translate(220 220)\" fill=\"rgb(254, 75, 131)\" stroke=\"#fff\"></polygon><polygon points=\"22.319288483138344,76.82349485415544 19.895190973188377,77.48665289029049 47.64167225292893,185.5520626040051 53.446495098500705,183.96404277288013 \" transform=\"translate(220 220)\" fill=\"rgb(255, 77, 128)\" stroke=\"#fff\"></polygon><polygon points=\"19.895190973188377,77.48665289029049 17.451459311723397,78.0733409550998 40.5684682100065,181.49289374661356 46.24927967975734,180.12905157838767 \" transform=\"translate(220 220)\" fill=\"rgb(255, 78, 124)\" stroke=\"#fff\"></polygon><polygon points=\"17.451459311723397,78.0733409550998 14.990505166857961,78.58298005829509 36.00229312553875,188.73062990512312 41.91270051379928,187.50664337650105 \" transform=\"translate(220 220)\" fill=\"rgb(255, 80, 121)\" stroke=\"#fff\"></polygon><polygon points=\"14.990505166857961,78.58298005829509 12.514757203218457,79.01506724761103 25.94080839055381,163.78381826775436 31.072582224053335,162.88818035772167 \" transform=\"translate(220 220)\" fill=\"rgb(255, 82, 118)\" stroke=\"#fff\"></polygon><polygon points=\"12.514757203218457,79.01506724761103 10.026658685144323,79.36917610515823 24.678322754732555,195.34903961599332 30.802207111699815,194.4774818068293 \" transform=\"translate(220 220)\" fill=\"rgb(255, 84, 115)\" stroke=\"#fff\"></polygon><polygon points=\"10.02665868514434,79.36917610515823 7.5286650654811424,79.6449571682464 19.154755968677133,202.63615201694532 25.510259604420707,201.93449788327206 \" transform=\"translate(220 220)\" fill=\"rgb(255, 86, 112)\" stroke=\"#fff\"></polygon><polygon points=\"7.5286650654811424,79.6449571682464 5.023241562345064,79.84213827426173 12.585785536834877,200.04533261049352 18.86315095875486,199.5512932374266 \" transform=\"translate(220 220)\" fill=\"rgb(255, 88, 109)\" stroke=\"#fff\"></polygon><polygon points=\"5.023241562345064,79.84213827426173 2.512860726250254,79.96052482925853 6.064360675073016,192.97108561060108 12.122736558318906,192.6853798565654 \" transform=\"translate(220 220)\" fill=\"rgb(255, 90, 106)\" stroke=\"#fff\"></polygon><polygon points=\"2.512860726250254,79.96052482925853 -1.2864981197413092e-14,80 -3.0190963582815106e-14,187.74042880924503 5.897069378551669,187.647790240716 \" transform=\"translate(220 220)\" fill=\"rgb(255, 92, 102)\" stroke=\"#fff\"></polygon><polygon points=\"-1.2864981197413092e-14,80 -2.5128607262502802,79.96052482925853 -6.145118113685332,195.5408289743482 -3.1460887649915215e-14,195.63736420379013 \" transform=\"translate(220 220)\" fill=\"rgb(255, 94, 99)\" stroke=\"#fff\"></polygon><polygon points=\"-2.5128607262502625,79.96052482925853 -5.023241562345072,79.84213827426173 -12.854707145235128,204.3197191746954 -6.43052664933556,204.62267583635088 \" transform=\"translate(220 220)\" fill=\"rgb(255, 96, 96)\" stroke=\"#fff\"></polygon><polygon points=\"-5.023241562345072,79.84213827426173 -7.52866506548115,79.6449571682464 -15.582489488172655,164.84552003122553 -10.396877555449016,165.253636541261 \" transform=\"translate(220 220)\" fill=\"rgb(255, 99, 93)\" stroke=\"#fff\"></polygon><polygon points=\"-7.52866506548115,79.6449571682464 -10.02665868514435,79.36917610515822 -25.38189804275854,200.91841149670796 -19.058373790387932,201.61653507358795 \" transform=\"translate(220 220)\" fill=\"rgb(255, 101, 90)\" stroke=\"#fff\"></polygon><polygon points=\"-10.02665868514435,79.36917610515822 -12.514757203218483,79.01506724761101 -28.330892799990238,178.87421732803443 -22.698338268828852,179.6758485478648 \" transform=\"translate(220 220)\" fill=\"rgb(255, 103, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-12.514757203218483,79.01506724761101 -14.990505166857986,78.58298005829509 -38.36139502499522,201.09747514862642 -32.02584164915066,202.2032062210678 \" transform=\"translate(220 220)\" fill=\"rgb(255, 106, 84)\" stroke=\"#fff\"></polygon><polygon points=\"-14.990505166857986,78.58298005829509 -17.451459311723422,78.07334095509978 -41.41745059870284,185.29102262017042 -35.576881916164886,186.50054624812165 \" transform=\"translate(220 220)\" fill=\"rgb(255, 109, 81)\" stroke=\"#fff\"></polygon><polygon points=\"-17.451459311723404,78.0733409550998 -19.895190973188388,77.48665289029049 -47.68844164895628,185.73421737501192 -41.83085752721897,187.14049890216603 \" transform=\"translate(220 220)\" fill=\"rgb(255, 111, 78)\" stroke=\"#fff\"></polygon><polygon points=\"-19.895190973188388,77.48665289029049 -22.319288483138347,76.82349485415544 -48.04099753631824,165.35819812571762 -42.823265681143695,166.7856080363974 \" transform=\"translate(220 220)\" fill=\"rgb(255, 114, 76)\" stroke=\"#fff\"></polygon><polygon points=\"-22.319288483138347,76.82349485415544 -24.721359549995803,76.08452130361228 -61.287354988121024,188.62308348395564 -55.33231914620219,190.45509172069433 \" transform=\"translate(220 220)\" fill=\"rgb(255, 117, 73)\" stroke=\"#fff\"></polygon><polygon points=\"-24.721359549995803,76.08452130361228 -27.099033619623324,75.27046151633803 -59.316553743386834,164.75806622824715 -54.11210868032785,166.53994604728308 \" transform=\"translate(220 220)\" fill=\"rgb(255, 120, 71)\" stroke=\"#fff\"></polygon><polygon points=\"-27.099033619623324,75.27046151633803 -29.449964214774255,74.3821188710601 -66.12965523692048,167.02444325101013 -60.85065969691007,169.01920943938507 \" transform=\"translate(220 220)\" fill=\"rgb(255, 122, 68)\" stroke=\"#fff\"></polygon><polygon points=\"-29.449964214774237,74.38211887106011 -31.771831250782455,73.42037005471849 -68.47740726558668,158.24195156214753 -63.473117982218426,160.31479605335701 \" transform=\"translate(220 220)\" fill=\"rgb(255, 125, 66)\" stroke=\"#fff\"></polygon><polygon points=\"-31.771831250782455,73.42037005471849 -34.062343325205816,72.38616419728156 -75.57964517316711,160.6149216818187 -70.49731457139467,162.90968193935075 \" transform=\"translate(220 220)\" fill=\"rgb(255, 128, 63)\" stroke=\"#fff\"></polygon><polygon points=\"-34.062343325205816,72.38616419728156 -36.31923997916374,71.28052193506943 -76.37859610011758,149.9014351018255 -71.63239001014288,152.22657747333898 \" transform=\"translate(220 220)\" fill=\"rgb(255, 131, 61)\" stroke=\"#fff\"></polygon><polygon points=\"-36.31923997916374,71.28052193506943 -38.5402939281372,70.10453440350909 -92.1990899521376,167.709522028398 -86.88571187536971,170.52281090489424 \" transform=\"translate(220 220)\" fill=\"rgb(255, 135, 59)\" stroke=\"#fff\"></polygon><polygon points=\"-38.54029392813723,70.10453440350908 -40.723313260029705,68.8593621603155 -102.73868219782746,173.7216242735697 -97.23125877334034,176.86300313334394 \" transform=\"translate(220 220)\" fill=\"rgb(255, 138, 57)\" stroke=\"#fff\"></polygon><polygon points=\"-40.723313260029705,68.8593621603155 -42.86614359831972,67.54623404016121 -103.54956310639612,163.16800246559254 -98.37323683314212,166.34005928551204 \" transform=\"translate(220 220)\" fill=\"rgb(255, 141, 56)\" stroke=\"#fff\"></polygon><polygon points=\"-42.86614359831975,67.5462340401612 -44.96667022817046,66.16644594196494 -114.69220136020336,168.76444937456546 -109.33458822205331,172.28374341145408 \" transform=\"translate(220 220)\" fill=\"rgb(255, 144, 54)\" stroke=\"#fff\"></polygon><polygon points=\"-44.96667022817046,66.16644594196494 -47.02282018339784,64.7213595499958 -108.72627520006638,149.64887946554472 -103.97204044739225,152.99021161296412 \" transform=\"translate(220 220)\" fill=\"rgb(253, 147, 52)\" stroke=\"#fff\"></polygon><polygon points=\"-47.02282018339784,64.7213595499958 -49.0325642922381,63.212400990055244 -115.66207319589782,149.11064627630734 -110.92132235863224,152.6701026891764 \" transform=\"translate(220 220)\" fill=\"rgb(251, 150, 51)\" stroke=\"#fff\"></polygon><polygon points=\"-49.03256429223813,63.21240099005522 -50.99391917989518,61.64105942206314 -125.96647047042111,152.26730591274296 -121.1214819598013,156.1488736448709 \" transform=\"translate(220 220)\" fill=\"rgb(249, 154, 50)\" stroke=\"#fff\"></polygon><polygon points=\"-50.99391917989518,61.64105942206314 -52.90494922589214,60.00888557043677 -121.52860309603943,137.84714177848792 -117.13875270656193,141.59642820821495 \" transform=\"translate(220 220)\" fill=\"rgb(246, 157, 49)\" stroke=\"#fff\"></polygon><polygon points=\"-52.90494922589217,60.008885570436746 -54.7637684742951,58.31749019371291 -136.97214738833355,145.86052210560112 -132.32297018315228,150.09094786494794 \" transform=\"translate(220 220)\" fill=\"rgb(244, 160, 48)\" stroke=\"#fff\"></polygon><polygon points=\"-54.7637684742951,58.31749019371291 -56.5685424949238,56.568542494923804 -143.3210640721091,143.3210640721091 -138.7485203642804,147.7521671930604 \" transform=\"translate(220 220)\" fill=\"rgb(242, 164, 47)\" stroke=\"#fff\"></polygon><polygon points=\"-56.5685424949238,56.568542494923804 -58.317490193712906,54.763768474295105 -128.13122324503618,120.32322757394427 -124.28855430827184,124.28855430827187 \" transform=\"translate(220 220)\" fill=\"rgb(239, 167, 47)\" stroke=\"#fff\"></polygon><polygon points=\"-58.317490193712935,54.76376847429508 -60.00888557043676,52.904949225892146 -134.59120367270788,118.6581075264 -130.7976498102135,122.82716878581789 \" transform=\"translate(220 220)\" fill=\"rgb(237, 170, 46)\" stroke=\"#fff\"></polygon><polygon points=\"-60.00888557043676,52.904949225892146 -61.64105942206313,50.99391917989519 -154.30789095894022,127.65458923251111 -150.2220217820609,132.43852738545286 \" transform=\"translate(220 220)\" fill=\"rgb(234, 173, 46)\" stroke=\"#fff\"></polygon><polygon points=\"-61.64105942206315,50.99391917989516 -63.21240099005523,49.032564292238106 -146.4753954926509,113.61796315653812 -142.83429225941202,118.16280290904504 \" transform=\"translate(220 220)\" fill=\"rgb(231, 177, 46)\" stroke=\"#fff\"></polygon><polygon points=\"-63.21240099005523,49.032564292238106 -64.72135954999578,47.02282018339786 -158.71367676282185,115.31223594428633 -155.01331628220038,120.24065337995619 \" transform=\"translate(220 220)\" fill=\"rgb(229, 180, 46)\" stroke=\"#fff\"></polygon><polygon points=\"-64.72135954999578,47.02282018339786 -66.16644594196494,44.966670228170464 -154.95345891440994,105.30626193569604 -151.56924911323415,110.12150541860348 \" transform=\"translate(220 220)\" fill=\"rgb(226, 183, 47)\" stroke=\"#fff\"></polygon><polygon points=\"-66.16644594196495,44.966670228170436 -67.54623404016121,42.86614359831973 -142.6487165386208,90.52762828531382 -139.73478648611876,94.96366283352033 \" transform=\"translate(220 220)\" fill=\"rgb(223, 187, 47)\" stroke=\"#fff\"></polygon><polygon points=\"-67.54623404016121,42.86614359831973 -68.85936216031548,40.72331326002971 -150.5346646746369,89.0259525170525 -147.6640121585411,93.71043166860392 \" transform=\"translate(220 220)\" fill=\"rgb(220, 190, 48)\" stroke=\"#fff\"></polygon><polygon points=\"-68.8593621603155,40.723313260029684 -70.10453440350909,38.54029392813722 -156.11661304025537,85.82583430345886 -153.34372431182828,90.6872257554702 \" transform=\"translate(220 220)\" fill=\"rgb(218, 193, 49)\" stroke=\"#fff\"></polygon><polygon points=\"-70.10453440350909,38.54029392813722 -71.28052193506943,36.31923997916375 -163.919494773939,83.52115425559096 -161.21514754413874,88.62877736633409 \" transform=\"translate(220 220)\" fill=\"rgb(215, 196, 50)\" stroke=\"#fff\"></polygon><polygon points=\"-71.28052193506944,36.31923997916372 -72.38616419728157,34.0623433252058 -157.8432352580145,74.27538854340386 -155.43230281476582,79.19671395764766 \" transform=\"translate(220 220)\" fill=\"rgb(212, 199, 51)\" stroke=\"#fff\"></polygon><polygon points=\"-72.38616419728157,34.0623433252058 -73.42037005471849,31.771831250782448 -167.15722355708456,72.33538996394222 -164.8026320508474,77.55023209289413 \" transform=\"translate(220 220)\" fill=\"rgb(209, 202, 52)\" stroke=\"#fff\"></polygon><polygon points=\"-73.42037005471849,31.771831250782448 -74.3821188710601,29.44996421477425 -161.78110854455574,64.053672167134 -159.68930486901272,69.10373297045183 \" transform=\"translate(220 220)\" fill=\"rgb(206, 205, 54)\" stroke=\"#fff\"></polygon><polygon points=\"-74.38211887106011,29.44996421477422 -75.27046151633803,27.099033619623306 -166.60861564679723,59.98279252946329 -164.64229930745017,65.18649772867715 \" transform=\"translate(220 220)\" fill=\"rgb(204, 208, 56)\" stroke=\"#fff\"></polygon><polygon points=\"-75.27046151633803,27.099033619623306 -76.08452130361228,24.7213595499958 -194.38310738343233,63.15890020383326 -192.30332205607493,69.23345605409479 \" transform=\"translate(220 220)\" fill=\"rgb(201, 211, 58)\" stroke=\"#fff\"></polygon><polygon points=\"-76.08452130361229,24.721359549995768 -76.82349485415544,22.31928848313833 -191.13475130854744,55.529778509908816 -189.2962053523292,61.5060655411206 \" transform=\"translate(220 220)\" fill=\"rgb(198, 214, 60)\" stroke=\"#fff\"></polygon><polygon points=\"-76.82349485415544,22.31928848313833 -77.48665289029049,19.895190973188384 -197.9653168803071,50.82885424123137 -196.27106005195924,57.02201414433691 \" transform=\"translate(220 220)\" fill=\"rgb(196, 217, 62)\" stroke=\"#fff\"></polygon><polygon points=\"-77.48665289029049,19.895190973188384 -78.07334095509978,17.451459311723422 -169.37242737764456,37.85922299147773 -168.09966537675373,43.160658261168074 \" transform=\"translate(220 220)\" fill=\"rgb(193, 220, 65)\" stroke=\"#fff\"></polygon><polygon points=\"-78.0733409550998,17.451459311723386 -78.58298005829509,14.990505166857966 -173.72803508114842,33.140395103114116 -172.6013458167179,38.580971773725466 \" transform=\"translate(220 220)\" fill=\"rgb(191, 223, 67)\" stroke=\"#fff\"></polygon><polygon points=\"-78.58298005829509,14.990505166857966 -79.01506724761101,12.514757203218478 -193.4079693647948,30.63281298214811 -192.35033429865925,36.69278866762114 \" transform=\"translate(220 220)\" fill=\"rgb(188, 225, 70)\" stroke=\"#fff\"></polygon><polygon points=\"-79.01506724761103,12.514757203218442 -79.36917610515823,10.026658685144326 -168.08442551692661,21.234001002024474 -167.33450990973398,26.503182699033733 \" transform=\"translate(220 220)\" fill=\"rgb(186, 228, 73)\" stroke=\"#fff\"></polygon><polygon points=\"-79.36917610515823,10.026658685144326 -79.6449571682464,7.528665065481148 -193.31354693802226,18.27351032962559 -192.64417354164647,24.336618704780367 \" transform=\"translate(220 220)\" fill=\"rgb(183, 230, 76)\" stroke=\"#fff\"></polygon><polygon points=\"-79.6449571682464,7.528665065481148 -79.84213827426173,5.023241562345087 -188.72314941726341,11.873454148647992 -188.25707172774858,17.795532694586615 \" transform=\"translate(220 220)\" fill=\"rgb(181, 233, 80)\" stroke=\"#fff\"></polygon><polygon points=\"-79.84213827426173,5.023241562345051 -79.96052482925853,2.512860726250259 -198.93959597588625,6.251928669694979 -198.64505346918895,12.49768744059744 \" transform=\"translate(220 220)\" fill=\"rgb(179, 235, 83)\" stroke=\"#fff\"></polygon><polygon points=\"-79.96052482925853,2.512860726250259 -80,9.797174393178826e-15 -164.5931439302264,2.0156846687575137e-14 -164.51192714948237,5.169995589904026 \" transform=\"translate(220 220)\" fill=\"rgb(177, 238, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-80,-2.5729962394826185e-14 -79.96052482925853,-2.512860726250275 -202.0722502050806,-6.35037629492351 -202.1720098876989,-6.50234776462115e-14 \" transform=\"translate(220 220)\" fill=\"rgb(175, 240, 91)\" stroke=\"#fff\"></polygon><polygon points=\"-79.96052482925853,-2.512860726250275 -79.84213827426173,-5.023241562345068 -199.34724399666794,-12.541865523982487 -199.64282768186192,-6.27402861637713 \" transform=\"translate(220 220)\" fill=\"rgb(170, 240, 89)\" stroke=\"#fff\"></polygon><polygon points=\"-79.84213827426173,-5.023241562345068 -79.6449571682464,-7.528665065481128 -186.71300642181225,-17.649575550017232 -187.17526138964314,-11.776069288444308 \" transform=\"translate(220 220)\" fill=\"rgb(166, 241, 89)\" stroke=\"#fff\"></polygon><polygon points=\"-79.6449571682464,-7.528665065481164 -79.36917610515823,-10.026658685144342 -193.73379704423462,-24.474270164602636 -194.40695651402902,-18.376867965436208 \" transform=\"translate(220 220)\" fill=\"rgb(161, 242, 88)\" stroke=\"#fff\"></polygon><polygon points=\"-79.36917610515823,-10.026658685144342 -79.01506724761103,-12.514757203218458 -182.30290308079083,-28.87394327398921 -183.1199000787834,-23.133423158066147 \" transform=\"translate(220 220)\" fill=\"rgb(156, 243, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-79.01506724761101,-12.514757203218494 -78.58298005829509,-14.990505166857982 -173.30114559635058,-33.05896157866914 -174.2540390199699,-27.599128444467894 \" transform=\"translate(220 220)\" fill=\"rgb(151, 243, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-78.58298005829509,-14.990505166857982 -78.0733409550998,-17.4514593117234 -188.23528153015053,-42.07557043758923 -189.4640243877658,-36.14219560535369 \" transform=\"translate(220 220)\" fill=\"rgb(146, 244, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-78.0733409550998,-17.4514593117234 -77.4866528902905,-19.895190973188367 -176.21564155536228,-45.24448676561873 -177.54985344704923,-39.68709427992317 \" transform=\"translate(220 220)\" fill=\"rgb(141, 244, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-77.48665289029049,-19.895190973188402 -76.82349485415544,-22.319288483138344 -174.11219365147898,-50.58426834026293 -175.6151700603013,-45.090311890042386 \" transform=\"translate(220 220)\" fill=\"rgb(136, 245, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-76.82349485415544,-22.319288483138344 -76.08452130361229,-24.721359549995782 -184.32127132675444,-59.88961148875213 -186.11149806379896,-54.070388534143675 \" transform=\"translate(220 220)\" fill=\"rgb(131, 245, 87)\" stroke=\"#fff\"></polygon><polygon points=\"-76.08452130361228,-24.721359549995817 -75.27046151633803,-27.09903361962332 -171.75547916423557,-61.83577741470147 -173.61303691019512,-56.41029521493301 \" transform=\"translate(220 220)\" fill=\"rgb(127, 246, 88)\" stroke=\"#fff\"></polygon><polygon points=\"-75.27046151633803,-27.09903361962332 -74.38211887106011,-29.449964214774234 -167.22019622995276,-66.2071593240894 -169.21730028825897,-60.921976790830215 \" transform=\"translate(220 220)\" fill=\"rgb(122, 246, 89)\" stroke=\"#fff\"></polygon><polygon points=\"-74.3821188710601,-29.449964214774266 -73.42037005471849,-31.771831250782462 -169.7627519728913,-73.46290279293555 -171.98650984345423,-68.0942763823886 \" transform=\"translate(220 220)\" fill=\"rgb(117, 246, 90)\" stroke=\"#fff\"></polygon><polygon points=\"-73.42037005471849,-31.771831250782462 -72.38616419728156,-34.062343325205816 -182.77506459813594,-86.00741689614468 -185.38643438816416,-80.22387390822571 \" transform=\"translate(220 220)\" fill=\"rgb(113, 246, 91)\" stroke=\"#fff\"></polygon><polygon points=\"-72.38616419728156,-34.062343325205816 -71.28052193506943,-36.31923997916373 -159.87184488535445,-81.4587736267138 -162.35163969387287,-76.39688263617774 \" transform=\"translate(220 220)\" fill=\"rgb(108, 246, 92)\" stroke=\"#fff\"></polygon><polygon points=\"-71.28052193506942,-36.31923997916377 -70.10453440350909,-38.54029392813723 -170.47895233488353,-93.72159714705174 -173.3386977713963,-88.32047789674974 \" transform=\"translate(220 220)\" fill=\"rgb(103, 247, 94)\" stroke=\"#fff\"></polygon><polygon points=\"-70.10453440350909,-38.54029392813723 -68.8593621603155,-40.7233132600297 -162.92866077434493,-96.35574137767125 -165.87487229376907,-91.19048272538119 \" transform=\"translate(220 220)\" fill=\"rgb(99, 247, 95)\" stroke=\"#fff\"></polygon><polygon points=\"-68.85936216031547,-40.723313260029734 -67.5462340401612,-42.86614359831974 -139.17988304914786,-88.32623961292693 -141.88560041131723,-83.9109101705772 \" transform=\"translate(220 220)\" fill=\"rgb(95, 247, 97)\" stroke=\"#fff\"></polygon><polygon points=\"-67.5462340401612,-42.86614359831974 -66.16644594196495,-44.96667022817044 -136.94830881608894,-93.06997456444978 -139.80413164112448,-88.72239981586006 \" transform=\"translate(220 220)\" fill=\"rgb(90, 246, 99)\" stroke=\"#fff\"></polygon><polygon points=\"-66.16644594196495,-44.96667022817044 -64.7213595499958,-47.02282018339784 -161.16758685842078,-117.09510598864058 -164.76610654674252,-111.97493038035377 \" transform=\"translate(220 220)\" fill=\"rgb(86, 246, 101)\" stroke=\"#fff\"></polygon><polygon points=\"-64.72135954999578,-47.02282018339787 -63.21240099005522,-49.03256429223813 -127.04401621181599,-98.54544037696057 -130.07671474484917,-94.50626516535498 \" transform=\"translate(220 220)\" fill=\"rgb(82, 246, 103)\" stroke=\"#fff\"></polygon><polygon points=\"-63.21240099005522,-49.03256429223813 -61.64105942206314,-50.99391917989517 -131.97334615130384,-109.17784688708825 -135.33758431688486,-104.97859122955707 \" transform=\"translate(220 220)\" fill=\"rgb(78, 246, 105)\" stroke=\"#fff\"></polygon><polygon points=\"-61.64105942206312,-50.9939191798952 -60.008885570436746,-52.90494922589217 -140.97224818286824,-124.28375500525452 -144.80653397407806,-119.79438315026505 \" transform=\"translate(220 220)\" fill=\"rgb(74, 245, 108)\" stroke=\"#fff\"></polygon><polygon points=\"-60.008885570436746,-52.90494922589217 -58.31749019371293,-54.7637684742951 -140.87459528916483,-132.2900504582682 -144.96041308376567,-127.79979533129598 \" transform=\"translate(220 220)\" fill=\"rgb(71, 245, 110)\" stroke=\"#fff\"></polygon><polygon points=\"-58.31749019371293,-54.7637684742951 -56.56854249492382,-56.5685424949238 -140.7409845409997,-140.74098454099965 -145.0923185188971,-136.25075620322525 \" transform=\"translate(220 220)\" fill=\"rgb(67, 244, 113)\" stroke=\"#fff\"></polygon><polygon points=\"-56.56854249492379,-56.56854249492382 -54.76376847429509,-58.31749019371293 -137.21120847005173,-146.11509630086206 -141.73308910911058,-141.73308910911067 \" transform=\"translate(220 220)\" fill=\"rgb(64, 243, 115)\" stroke=\"#fff\"></polygon><polygon points=\"-54.76376847429509,-58.31749019371293 -52.90494922589215,-60.00888557043676 -131.74264352431805,-149.43269648066328 -136.37143091002903,-145.22082402950602 \" transform=\"translate(220 220)\" fill=\"rgb(60, 242, 118)\" stroke=\"#fff\"></polygon><polygon points=\"-52.904949225892125,-60.00888557043679 -50.99391917989516,-61.64105942206315 -117.13875270656189,-141.59642820821497 -121.52860309603942,-137.84714177848795 \" transform=\"translate(220 220)\" fill=\"rgb(57, 242, 121)\" stroke=\"#fff\"></polygon><polygon points=\"-50.99391917989516,-61.64105942206315 -49.03256429223812,-63.21240099005523 -115.54357048199093,-148.95787349809305 -120.1654365820691,-145.2550605240362 \" transform=\"translate(220 220)\" fill=\"rgb(54, 241, 124)\" stroke=\"#fff\"></polygon><polygon points=\"-49.03256429223812,-63.21240099005523 -47.02282018339786,-64.72135954999578 -115.09941688687026,-158.42075645986264 -120.01873848683265,-154.72722532586806 \" transform=\"translate(220 220)\" fill=\"rgb(51, 240, 127)\" stroke=\"#fff\"></polygon><polygon points=\"-47.02282018339786,-64.72135954999578 -44.96667022817047,-66.16644594196492 -103.63374414128262,-152.49242371501677 -108.37250992702789,-149.16196333964393 \" transform=\"translate(220 220)\" fill=\"rgb(48, 239, 130)\" stroke=\"#fff\"></polygon><polygon points=\"-44.966670228170415,-66.16644594196498 -42.86614359831971,-67.54623404016122 -108.32918009258765,-170.69947370305374 -113.63752622483204,-167.21254204016046 \" transform=\"translate(220 220)\" fill=\"rgb(46, 237, 133)\" stroke=\"#fff\"></polygon><polygon points=\"-42.86614359831971,-67.54623404016122 -40.723313260029684,-68.8593621603155 -82.89087358970745,-140.16081274754399 -87.2525294687669,-137.48798658726122 \" transform=\"translate(220 220)\" fill=\"rgb(43, 236, 137)\" stroke=\"#fff\"></polygon><polygon points=\"-40.723313260029684,-68.8593621603155 -38.540293928137224,-70.10453440350909 -91.65131507170626,-166.7131232198631 -96.84267642893846,-163.75202298040278 \" transform=\"translate(220 220)\" fill=\"rgb(41, 235, 140)\" stroke=\"#fff\"></polygon><polygon points=\"-38.540293928137224,-70.10453440350909 -36.319239979163754,-71.28052193506943 -78.38140465432885,-153.83216821083604 -83.17471333681942,-151.29424190421298 \" transform=\"translate(220 220)\" fill=\"rgb(39, 233, 143)\" stroke=\"#fff\"></polygon><polygon points=\"-36.319239979163754,-71.28052193506943 -34.06234332520584,-72.38616419728154 -76.84415838427756,-163.3021490418147 -81.93568489136177,-160.8078359435462 \" transform=\"translate(220 220)\" fill=\"rgb(37, 232, 146)\" stroke=\"#fff\"></polygon><polygon points=\"-34.062343325205774,-72.38616419728159 -31.771831250782423,-73.4203700547185 -66.62594284566629,-153.9634697276972 -71.4291764192451,-151.79472661042573 \" transform=\"translate(220 220)\" fill=\"rgb(35, 230, 150)\" stroke=\"#fff\"></polygon><polygon points=\"-31.771831250782423,-73.4203700547185 -29.449964214774226,-74.38211887106011 -66.89747844097643,-168.9637432929233 -72.17174800719373,-166.77906930698444 \" transform=\"translate(220 220)\" fill=\"rgb(33, 228, 153)\" stroke=\"#fff\"></polygon><polygon points=\"-29.449964214774226,-74.38211887106011 -27.09903361962331,-75.27046151633803 -56.98869647944581,-158.29219393698887 -61.93265396560065,-156.4240280794126 \" transform=\"translate(220 220)\" fill=\"rgb(32, 226, 156)\" stroke=\"#fff\"></polygon><polygon points=\"-27.09903361962331,-75.27046151633803 -24.721359549995803,-76.08452130361228 -59.14035988254762,-182.01531199313652 -64.82841679854342,-180.06785482809087 \" transform=\"translate(220 220)\" fill=\"rgb(30, 225, 160)\" stroke=\"#fff\"></polygon><polygon points=\"-24.721359549995803,-76.08452130361228 -22.31928848313837,-76.82349485415544 -51.55084706148724,-177.43917943206085 -57.098909146528186,-175.73237267093523 \" transform=\"translate(220 220)\" fill=\"rgb(29, 223, 163)\" stroke=\"#fff\"></polygon><polygon points=\"-22.319288483138298,-76.82349485415546 -19.895190973188356,-77.4866528902905 -40.93265039211665,-159.42214764803848 -45.92002327156783,-158.0577568219127 \" transform=\"translate(220 220)\" fill=\"rgb(28, 221, 166)\" stroke=\"#fff\"></polygon><polygon points=\"-19.895190973188356,-77.4866528902905 -17.45145931172339,-78.0733409550998 -37.21239561878944,-166.47868805734288 -42.423255510117095,-165.22767128089257 \" transform=\"translate(220 220)\" fill=\"rgb(27, 219, 170)\" stroke=\"#fff\"></polygon><polygon points=\"-17.45145931172339,-78.0733409550998 -14.99050516685797,-78.58298005829509 -36.00229312553877,-188.73062990512312 -41.91270051379926,-187.50664337650105 \" transform=\"translate(220 220)\" fill=\"rgb(27, 216, 173)\" stroke=\"#fff\"></polygon><polygon points=\"-14.99050516685797,-78.58298005829509 -12.514757203218483,-79.01506724761101 -27.32407016774919,-172.5173894087134 -32.7294895440636,-171.5739927061056 \" transform=\"translate(220 220)\" fill=\"rgb(26, 214, 176)\" stroke=\"#fff\"></polygon><polygon points=\"-12.514757203218483,-79.01506724761101 -10.026658685144367,-79.36917610515822 -20.086163543967178,-158.9983564475134 -25.070511302965368,-158.28897871277522 \" transform=\"translate(220 220)\" fill=\"rgb(26, 212, 179)\" stroke=\"#fff\"></polygon><polygon points=\"-10.026658685144298,-79.36917610515823 -7.528665065481118,-79.6449571682464 -19.234468257183227,-203.47941994673604 -25.616420245505243,-202.77484588775408 \" transform=\"translate(220 220)\" fill=\"rgb(25, 209, 182)\" stroke=\"#fff\"></polygon><polygon points=\"-7.528665065481118,-79.6449571682464 -5.023241562345056,-79.84213827426173 -11.726846354454345,-186.39288525799344 -17.575801876394088,-185.9325624752755 \" transform=\"translate(220 220)\" fill=\"rgb(25, 207, 185)\" stroke=\"#fff\"></polygon><polygon points=\"-5.023241562345056,-79.84213827426173 -2.512860726250264,-79.96052482925853 -5.050336861812901,-160.7043246832501 -10.095689650877723,-160.46639188562324 \" transform=\"translate(220 220)\" fill=\"rgb(25, 205, 188)\" stroke=\"#fff\"></polygon><polygon points=\"-2.512860726250264,-79.96052482925853 -1.4695761589768237e-14,-80 -3.49824341104218e-14,-190.43550153822818 -5.981723658739816,-190.34153311399743 \" transform=\"translate(220 220)\" fill=\"rgb(25, 202, 191)\" stroke=\"#fff\"></polygon><polygon points=\"-1.4695761589768237e-14,-80 2.5128607262502345,-79.96052482925853 5.46547207959426,-173.9141415036373 -3.196328145774592e-14,-174 \" transform=\"translate(220 220)\" fill=\"rgb(26, 199, 194)\" stroke=\"#fff\"></polygon><polygon points=\"2.5128607262503055,-79.96052482925852 5.023241562345097,-79.84213827426173 10.897428063286771,-173.20965903470685 5.451403970424863,-173.46648701136814 \" transform=\"translate(220 220)\" fill=\"rgb(26, 197, 197)\" stroke=\"#fff\"></polygon><polygon points=\"5.023241562345097,-79.84213827426173 7.528665065481159,-79.6449571682464 15.854990824656857,-167.7282830554544 10.578694654140051,-168.14353656978628 \" transform=\"translate(220 220)\" fill=\"rgb(27, 194, 199)\" stroke=\"#fff\"></polygon><polygon points=\"7.528665065481159,-79.6449571682464 10.026658685144339,-79.36917610515823 22.724344186363254,-179.88170658226906 17.06291014626076,-180.50673471920783 \" transform=\"translate(220 220)\" fill=\"rgb(27, 191, 202)\" stroke=\"#fff\"></polygon><polygon points=\"10.026658685144339,-79.36917610515823 12.514757203218455,-79.01506724761103 25.591780261419924,-161.58014138877112 20.503797369754885,-162.30426858707108 \" transform=\"translate(220 220)\" fill=\"rgb(28, 188, 204)\" stroke=\"#fff\"></polygon><polygon points=\"12.514757203218455,-79.01506724761103 14.990505166857941,-78.58298005829509 30.795094364160374,-161.43353805463275 25.709148873096165,-162.3211776385173 \" transform=\"translate(220 220)\" fill=\"rgb(29, 186, 206)\" stroke=\"#fff\"></polygon><polygon points=\"14.99050516685801,-78.58298005829509 17.451459311723433,-78.07334095509978 35.017070485410656,-156.65736798410126 30.079064831394916,-157.67997979437678 \" transform=\"translate(220 220)\" fill=\"rgb(30, 183, 209)\" stroke=\"#fff\"></polygon><polygon points=\"17.451459311723433,-78.07334095509978 19.895190973188395,-77.48665289029049 46.882341024680166,-182.594662728258 41.12377045956193,-183.97717320360684 \" transform=\"translate(220 220)\" fill=\"rgb(31, 180, 211)\" stroke=\"#fff\"></polygon><polygon points=\"19.895190973188395,-77.48665289029049 22.319288483138337,-76.82349485415544 56.974880452573125,-196.10882482078648 50.78683973885957,-197.80168119739102 \" transform=\"translate(220 220)\" fill=\"rgb(33, 177, 213)\" stroke=\"#fff\"></polygon><polygon points=\"22.319288483138337,-76.82349485415544 24.72135954999578,-76.08452130361229 56.346950460813545,-173.41808180327553 50.871953054872215,-175.10241093412682 \" transform=\"translate(220 220)\" fill=\"rgb(34, 174, 214)\" stroke=\"#fff\"></polygon><polygon points=\"24.72135954999578,-76.08452130361229 27.099033619623285,-75.27046151633805 65.14640494236144,-180.95110087582376 59.43044768960022,-182.9081104612378 \" transform=\"translate(220 220)\" fill=\"rgb(35, 171, 216)\" stroke=\"#fff\"></polygon><polygon points=\"27.09903361962335,-75.27046151633803 29.449964214774262,-74.3821188710601 71.41293393383839,-180.36848201442356 65.7121850279933,-182.52261551948288 \" transform=\"translate(220 220)\" fill=\"rgb(37, 168, 218)\" stroke=\"#fff\"></polygon><polygon points=\"29.449964214774262,-74.3821188710601 31.77183125078246,-73.42037005471849 74.86923999297811,-173.01260549357244 69.39783927394019,-175.27893387657585 \" transform=\"translate(220 220)\" fill=\"rgb(39, 165, 219)\" stroke=\"#fff\"></polygon><polygon points=\"31.77183125078246,-73.42037005471849 34.06234332520581,-72.38616419728157 87.02353680971989,-184.93442933138243 81.17166514256458,-187.57665070306624 \" transform=\"translate(220 220)\" fill=\"rgb(40, 162, 220)\" stroke=\"#fff\"></polygon><polygon points=\"34.06234332520581,-72.38616419728157 36.31923997916373,-71.28052193506944 84.33933263500836,-165.5252602567609 79.09844219428892,-168.09274599108596 \" transform=\"translate(220 220)\" fill=\"rgb(42, 159, 222)\" stroke=\"#fff\"></polygon><polygon points=\"36.3192399791638,-71.2805219350694 38.54029392813726,-70.10453440350906 91.74300254544436,-166.87990211545278 86.45590851149156,-169.67927430764522 \" transform=\"translate(220 220)\" fill=\"rgb(44, 156, 223)\" stroke=\"#fff\"></polygon><polygon points=\"38.54029392813726,-70.10453440350906 40.72331326002973,-68.85936216031547 100.95820786119836,-170.7110065868347 95.54622878015114,-173.7979449542666 \" transform=\"translate(220 220)\" fill=\"rgb(46, 152, 223)\" stroke=\"#fff\"></polygon><polygon points=\"40.72331326002973,-68.85936216031547 42.86614359831974,-67.5462340401612 97.26246066634543,-153.26111425027887 92.4004195775652,-156.2405768614521 \" transform=\"translate(220 220)\" fill=\"rgb(48, 149, 224)\" stroke=\"#fff\"></polygon><polygon points=\"42.86614359831974,-67.5462340401612 44.96667022817044,-66.16644594196495 102.83669589579226,-151.31960283722512 98.03288860566195,-154.47511442691692 \" transform=\"translate(220 220)\" fill=\"rgb(50, 146, 225)\" stroke=\"#fff\"></polygon><polygon points=\"44.96667022817044,-66.16644594196495 47.02282018339783,-64.72135954999581 109.19483103608412,-150.29379124697084 104.4201079107966,-153.64952286383647 \" transform=\"translate(220 220)\" fill=\"rgb(52, 143, 225)\" stroke=\"#fff\"></polygon><polygon points=\"47.0228201833979,-64.72135954999575 49.032564292238156,-63.21240099005521 103.6948028006031,-133.68253424702175 99.44456579884682,-136.87370245463856 \" transform=\"translate(220 220)\" fill=\"rgb(54, 140, 225)\" stroke=\"#fff\"></polygon><polygon points=\"49.032564292238156,-63.21240099005521 50.9939191798952,-61.64105942206312 118.03565207088154,-142.68059329889167 113.49570286065719,-146.31777846894528 \" transform=\"translate(220 220)\" fill=\"rgb(56, 137, 225)\" stroke=\"#fff\"></polygon><polygon points=\"50.9939191798952,-61.64105942206312 52.90494922589215,-60.00888557043676 127.43101155892212,-144.5421100039891 122.82795465320444,-148.4734920012518 \" transform=\"translate(220 220)\" fill=\"rgb(58, 134, 225)\" stroke=\"#fff\"></polygon><polygon points=\"52.90494922589215,-60.00888557043676 54.76376847429509,-58.31749019371293 135.88765504209434,-144.70565505519636 131.2752882191073,-148.90258594390835 \" transform=\"translate(220 220)\" fill=\"rgb(61, 131, 225)\" stroke=\"#fff\"></polygon><polygon points=\"54.76376847429509,-58.31749019371293 56.56854249492379,-56.56854249492382 138.8485522178206,-138.84855221782067 134.41870041693468,-143.14137726105645 \" transform=\"translate(220 220)\" fill=\"rgb(63, 128, 225)\" stroke=\"#fff\"></polygon><polygon points=\"56.56854249492384,-56.56854249492376 58.31749019371295,-54.76376847429506 132.01906646799847,-123.97415537312459 128.05980070178438,-128.0598007017842 \" transform=\"translate(220 220)\" fill=\"rgb(65, 125, 224)\" stroke=\"#fff\"></polygon><polygon points=\"58.31749019371295,-54.76376847429506 60.00888557043679,-52.904949225892125 126.37570164722842,-111.4151681951398 122.81370786140054,-115.32974825306412 \" transform=\"translate(220 220)\" fill=\"rgb(67, 122, 224)\" stroke=\"#fff\"></polygon><polygon points=\"60.00888557043679,-52.904949225892125 61.64105942206315,-50.99391917989517 145.70119386818243,-120.53451018184418 141.84321866444557,-125.05161877521243 \" transform=\"translate(220 220)\" fill=\"rgb(70, 119, 223)\" stroke=\"#fff\"></polygon><polygon points=\"61.64105942206315,-50.99391917989517 63.21240099005522,-49.03256429223812 147.41490201776844,-114.34671911856925 143.7504444168233,-118.92070988711359 \" transform=\"translate(220 220)\" fill=\"rgb(72, 116, 222)\" stroke=\"#fff\"></polygon><polygon points=\"63.21240099005522,-49.03256429223812 64.72135954999578,-47.02282018339787 158.71367676282185,-115.31223594428636 155.01331628220035,-120.24065337995621 \" transform=\"translate(220 220)\" fill=\"rgb(74, 113, 221)\" stroke=\"#fff\"></polygon><polygon points=\"64.72135954999582,-47.022820183397805 66.16644594196497,-44.966670228170415 161.20516592926407,-109.5549176356961 157.68441778746674,-114.56443552635943 \" transform=\"translate(220 220)\" fill=\"rgb(76, 110, 219)\" stroke=\"#fff\"></polygon><polygon points=\"66.16644594196497,-44.966670228170415 67.54623404016121,-42.86614359831971 168.79519999217908,-107.1206912478606 165.34716752535957,-112.36981901364747 \" transform=\"translate(220 220)\" fill=\"rgb(79, 108, 218)\" stroke=\"#fff\"></polygon><polygon points=\"67.54623404016121,-42.86614359831971 68.8593621603155,-40.7233132600297 150.53466467463696,-89.02595251705246 147.66401215854114,-93.71043166860386 \" transform=\"translate(220 220)\" fill=\"rgb(81, 105, 217)\" stroke=\"#fff\"></polygon><polygon points=\"68.8593621603155,-40.7233132600297 70.10453440350909,-38.540293928137224 175.64766181587385,-96.56311923005904 172.52786942389938,-102.03269754775728 \" transform=\"translate(220 220)\" fill=\"rgb(83, 102, 215)\" stroke=\"#fff\"></polygon><polygon points=\"70.10453440350909,-38.540293928137224 71.28052193506943,-36.319239979163754 149.04860038620535,-75.94405510829681 146.58959348091975,-80.5883109791826 \" transform=\"translate(220 220)\" fill=\"rgb(85, 99, 213)\" stroke=\"#fff\"></polygon><polygon points=\"71.28052193506944,-36.3192399791637 72.38616419728157,-34.062343325205774 147.56852657445404,-69.44047763705892 145.31453230134383,-74.04145238891479 \" transform=\"translate(220 220)\" fill=\"rgb(87, 97, 211)\" stroke=\"#fff\"></polygon><polygon points=\"72.38616419728157,-34.062343325205774 73.4203700547185,-31.771831250782427 166.968337511524,-72.25365167304679 164.61640667091083,-77.46260108084076 \" transform=\"translate(220 220)\" fill=\"rgb(89, 94, 209)\" stroke=\"#fff\"></polygon><polygon points=\"73.4203700547185,-31.771831250782427 74.38211887106011,-29.44996421477423 155.5340843546401,-61.58030031870945 153.52305369567011,-66.4353578099429 \" transform=\"translate(220 220)\" fill=\"rgb(91, 92, 207)\" stroke=\"#fff\"></polygon><polygon points=\"74.38211887106011,-29.44996421477423 75.27046151633803,-27.099033619623313 168.62176670776228,-60.70757150893896 166.6316911419828,-65.97415367644211 \" transform=\"translate(220 220)\" fill=\"rgb(93, 89, 205)\" stroke=\"#fff\"></polygon><polygon points=\"75.27046151633803,-27.099033619623313 76.08452130361228,-24.72135954999581 162.67768178227917,-52.857182948571584 160.93712592733075,-57.940930589400544 \" transform=\"translate(220 220)\" fill=\"rgb(95, 87, 202)\" stroke=\"#fff\"></polygon><polygon points=\"76.0845213036123,-24.721359549995743 76.82349485415546,-22.3192884831383 182.3247698720654,-52.97024229530108 180.57096808525387,-58.67106409874237 \" transform=\"translate(220 220)\" fill=\"rgb(96, 84, 200)\" stroke=\"#fff\"></polygon><polygon points=\"76.82349485415546,-22.3192884831383 77.4866528902905,-19.89519097318836 172.55593961198255,-44.304835014605835 171.07914517360956,-49.70308629967191 \" transform=\"translate(220 220)\" fill=\"rgb(98, 82, 197)\" stroke=\"#fff\"></polygon><polygon points=\"77.4866528902905,-19.89519097318836 78.0733409550998,-17.451459311723394 188.9591318557745,-42.237370155019896 187.53918407282686,-48.151878328872115 \" transform=\"translate(220 220)\" fill=\"rgb(100, 80, 195)\" stroke=\"#fff\"></polygon><polygon points=\"78.0733409550998,-17.451459311723394 78.58298005829509,-14.990505166857975 178.70884506923755,-34.09053542365428 177.54985344704923,-39.68709427992316 \" transform=\"translate(220 220)\" fill=\"rgb(101, 78, 192)\" stroke=\"#fff\"></polygon><polygon points=\"78.58298005829509,-14.990505166857975 79.01506724761101,-12.51475720321849 186.0050134159481,-29.460299947442856 184.98786078613753,-35.28832173154368 \" transform=\"translate(220 220)\" fill=\"rgb(103, 75, 189)\" stroke=\"#fff\"></polygon><polygon points=\"79.01506724761103,-12.51475720321842 79.36917610515823,-10.026658685144303 188.74504122255374,-23.84404374243019 187.9029474250011,-29.760903163239437 \" transform=\"translate(220 220)\" fill=\"rgb(104, 73, 186)\" stroke=\"#fff\"></polygon><polygon points=\"79.36917610515823,-10.026658685144303 79.6449571682464,-7.528665065481123 185.14634537163255,-17.501482478750678 184.50525197703612,-23.308433802301458 \" transform=\"translate(220 220)\" fill=\"rgb(105, 71, 183)\" stroke=\"#fff\"></polygon><polygon points=\"79.6449571682464,-7.528665065481123 79.84213827426173,-5.023241562345061 168.14353656978628,-10.578694654139975 167.7282830554544,-15.85499082465678 \" transform=\"translate(220 220)\" fill=\"rgb(107, 69, 180)\" stroke=\"#fff\"></polygon><polygon points=\"79.84213827426173,-5.023241562345061 79.96052482925853,-2.5128607262502687 204.11678206111984,-6.41462829696549 203.81457440681982,-12.822926130249284 \" transform=\"translate(220 220)\" fill=\"rgb(108, 67, 177)\" stroke=\"#fff\"></polygon><polygon points=\"79.96052482925853,-2.5128607262502687 80,-1.9594348786357652e-14 204.8919533036456,-5.018405495687171e-14 204.79085149314292,-6.435811782267939 \" transform=\"translate(220 220)\" fill=\"rgb(109, 66, 173)\" stroke=\"#fff\"></polygon></svg></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scaleordinal-서수\">scaleOrdinal (서수)<a href=\"https://alvin.ing/blog/d3-scale#scaleordinal-%EC%84%9C%EC%88%98\" class=\"hash-link\" aria-label=\"scaleOrdinal (서수)에 대한 직접 링크\" title=\"scaleOrdinal (서수)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>지정된 domain과 range를 갖는 순서를 나타내는 스케일을 생성하고 반환하는 데 사용됩니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> func </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleOrdinal</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">,</span><span class=\"token generic-function generic class-name\"> </span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token string\" style=\"color:#e3116c\">'white'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'pink'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'red'</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// white</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">1</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// pink</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// red</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">func</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">3</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// white</span><br></div></code></pre></div></div>\n<div class=\"scale\"><div class=\"box-list\"><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:pink\" title=\"1\"></div><div class=\"box\" style=\"background-color:red\" title=\"2\"></div><div class=\"box\" style=\"background-color:white\" title=\"3\"></div><div class=\"box\" style=\"background-color:pink\" title=\"4\"></div><div class=\"box\" style=\"background-color:red\" title=\"5\"></div><div class=\"box\" style=\"background-color:white\" title=\"6\"></div><div class=\"box\" style=\"background-color:pink\" title=\"7\"></div><div class=\"box\" style=\"background-color:red\" title=\"8\"></div><div class=\"box\" style=\"background-color:white\" title=\"9\"></div><div class=\"box\" style=\"background-color:pink\" title=\"10\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalethreshold-임계점\">scaleThreshold (임계점)<a href=\"https://alvin.ing/blog/d3-scale#scalethreshold-%EC%9E%84%EA%B3%84%EC%A0%90\" class=\"hash-link\" aria-label=\"scaleThreshold (임계점)에 대한 직접 링크\" title=\"scaleThreshold (임계점)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>결과 값을 구분하는 절단 값(=domain)을 직접 지정할 수 있습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> linear </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleLinear</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100000</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token string\" style=\"color:#e3116c\">'white'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'red'</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 10000보다 작으면 white, 100000보다 크면 red, 나머지는 pink로 구분</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> threshold </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleThreshold</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">number</span><span class=\"token generic-function generic class-name punctuation\" style=\"color:#393A34\">,</span><span class=\"token generic-function generic class-name\"> </span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">10000</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">100000</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token string\" style=\"color:#e3116c\">'white'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'pink'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'red'</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><h3>linear</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:rgb(255, 246, 246)\" title=\"11002\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"29017\"></div><div class=\"box\" style=\"background-color:rgb(255, 216, 216)\" title=\"45793\"></div><div class=\"box\" style=\"background-color:rgb(255, 249, 249)\" title=\"7000\"></div><div class=\"box\" style=\"background-color:rgb(255, 153, 153)\" title=\"120040\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"30138\"></div><div class=\"box\" style=\"background-color:rgb(255, 237, 237)\" title=\"21699\"></div><div class=\"box\" style=\"background-color:rgb(255, 215, 215)\" title=\"47058\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"24001\"></div><div class=\"box\" style=\"background-color:rgb(255, 250, 250)\" title=\"6000\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"69007\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40000\"></div><div class=\"box\" style=\"background-color:rgb(255, 208, 208)\" title=\"55001\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30001\"></div><div class=\"box\" style=\"background-color:rgb(255, 203, 203)\" title=\"61150\"></div><div class=\"box\" style=\"background-color:rgb(255, 245, 245)\" title=\"12000\"></div><div class=\"box\" style=\"background-color:rgb(255, 182, 182)\" title=\"85530\"></div><div class=\"box\" style=\"background-color:rgb(255, 185, 185)\" title=\"83000\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"23100\"></div><div class=\"box\" style=\"background-color:rgb(255, 173, 173)\" title=\"96225\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"45003\"></div><div class=\"box\" style=\"background-color:rgb(255, 226, 226)\" title=\"34300\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"43000\"></div><div class=\"box\" style=\"background-color:rgb(255, 201, 201)\" title=\"63131\"></div><div class=\"box\" style=\"background-color:rgb(255, 211, 211)\" title=\"52001\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"36000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"10001\"></div><div class=\"box\" style=\"background-color:rgb(255, 63, 63)\" title=\"225786\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"75000\"></div><div class=\"box\" style=\"background-color:rgb(255, 89, 89)\" title=\"195100\"></div><div class=\"box\" style=\"background-color:rgb(255, 227, 227)\" title=\"33010\"></div><div class=\"box\" style=\"background-color:rgb(255, 251, 251)\" title=\"5000\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"31213\"></div><div class=\"box\" style=\"background-color:rgb(255, 188, 188)\" title=\"79050\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40010\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"37002\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50000\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60000\"></div><div class=\"box\" style=\"background-color:rgb(255, 199, 199)\" title=\"66529\"></div><div class=\"box\" style=\"background-color:rgb(255, 222, 222)\" title=\"39048\"></div><div class=\"box\" style=\"background-color:rgb(255, 232, 232)\" title=\"27276\"></div><div class=\"box\" style=\"background-color:rgb(255, 231, 231)\" title=\"28007\"></div><div class=\"box\" style=\"background-color:rgb(255, 125, 125)\" title=\"153420\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"44500\"></div><div class=\"box\" style=\"background-color:rgb(255, 132, 132)\" title=\"145443\"></div><div class=\"box\" style=\"background-color:rgb(255, 179, 179)\" title=\"89550\"></div><div class=\"box\" style=\"background-color:rgb(255, 241, 241)\" title=\"16024\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"50\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25001\"></div><div class=\"box\" style=\"background-color:rgb(255, 0, 0)\" title=\"300577\"></div><div class=\"box\" style=\"background-color:rgb(255, 168, 168)\" title=\"102035\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20581\"></div><div class=\"box\" style=\"background-color:rgb(255, 111, 111)\" title=\"170240\"></div><div class=\"box\" style=\"background-color:rgb(255, 148, 148)\" title=\"126101\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"18001\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15000\"></div><div class=\"box\" style=\"background-color:rgb(255, 252, 252)\" title=\"4000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 170, 170)\" title=\"100003\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35000\"></div><div class=\"box\" style=\"background-color:rgb(255, 243, 243)\" title=\"14001\"></div><div class=\"box\" style=\"background-color:rgb(255, 194, 194)\" title=\"72046\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 200, 200)\" title=\"65006\"></div><div class=\"box\" style=\"background-color:rgb(255, 207, 207)\" title=\"56000\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"42000\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"17158\"></div><div class=\"box\" style=\"background-color:rgb(255, 140, 140)\" title=\"135096\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"70040\"></div><div class=\"box\" style=\"background-color:rgb(255, 158, 158)\" title=\"114068\"></div><div class=\"box\" style=\"background-color:rgb(255, 236, 236)\" title=\"22216\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60020\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"2742\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35030\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25000\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"76005\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40600\"></div><div class=\"box\" style=\"background-color:rgb(255, 214, 214)\" title=\"48335\"></div><div class=\"box\" style=\"background-color:rgb(255, 206, 206)\" title=\"58000\"></div><div class=\"box\" style=\"background-color:rgb(255, 254, 254)\" title=\"900\"></div><div class=\"box\" style=\"background-color:rgb(255, 248, 248)\" title=\"8000\"></div><div class=\"box\" style=\"background-color:rgb(255, 239, 239)\" title=\"19002\"></div><div class=\"box\" style=\"background-color:rgb(255, 177, 177)\" title=\"92000\"></div><div class=\"box\" style=\"background-color:rgb(255, 244, 244)\" title=\"13000\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50008\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15100\"></div><div class=\"box\" style=\"background-color:rgb(255, 163, 163)\" title=\"108023\"></div><div class=\"box\" style=\"background-color:rgb(255, 212, 212)\" title=\"50600\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"26483\"></div><div class=\"box\" style=\"background-color:rgb(255, 223, 223)\" title=\"38002\"></div><div class=\"box\" style=\"background-color:rgb(255, 210, 210)\" title=\"53440\"></div><div class=\"box\" style=\"background-color:rgb(255, 228, 228)\" title=\"32007\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"25654\"></div><div class=\"box\" style=\"background-color:rgb(255, 187, 187)\" title=\"80130\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"9500\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"1968\"></div></div><h3>threshold</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:pink\" title=\"11002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"29017\"></div><div class=\"box\" style=\"background-color:pink\" title=\"45793\"></div><div class=\"box\" style=\"background-color:white\" title=\"7000\"></div><div class=\"box\" style=\"background-color:red\" title=\"120040\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30138\"></div><div class=\"box\" style=\"background-color:pink\" title=\"21699\"></div><div class=\"box\" style=\"background-color:pink\" title=\"47058\"></div><div class=\"box\" style=\"background-color:pink\" title=\"24001\"></div><div class=\"box\" style=\"background-color:white\" title=\"6000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"69007\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"55001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"61150\"></div><div class=\"box\" style=\"background-color:pink\" title=\"12000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"85530\"></div><div class=\"box\" style=\"background-color:pink\" title=\"83000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"23100\"></div><div class=\"box\" style=\"background-color:pink\" title=\"96225\"></div><div class=\"box\" style=\"background-color:pink\" title=\"45003\"></div><div class=\"box\" style=\"background-color:pink\" title=\"34300\"></div><div class=\"box\" style=\"background-color:pink\" title=\"43000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"63131\"></div><div class=\"box\" style=\"background-color:pink\" title=\"52001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"36000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"10001\"></div><div class=\"box\" style=\"background-color:red\" title=\"225786\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:pink\" title=\"75000\"></div><div class=\"box\" style=\"background-color:red\" title=\"195100\"></div><div class=\"box\" style=\"background-color:pink\" title=\"33010\"></div><div class=\"box\" style=\"background-color:white\" title=\"5000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"31213\"></div><div class=\"box\" style=\"background-color:pink\" title=\"79050\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40010\"></div><div class=\"box\" style=\"background-color:pink\" title=\"37002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"60000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"66529\"></div><div class=\"box\" style=\"background-color:pink\" title=\"39048\"></div><div class=\"box\" style=\"background-color:pink\" title=\"27276\"></div><div class=\"box\" style=\"background-color:pink\" title=\"28007\"></div><div class=\"box\" style=\"background-color:red\" title=\"153420\"></div><div class=\"box\" style=\"background-color:pink\" title=\"44500\"></div><div class=\"box\" style=\"background-color:red\" title=\"145443\"></div><div class=\"box\" style=\"background-color:pink\" title=\"89550\"></div><div class=\"box\" style=\"background-color:pink\" title=\"16024\"></div><div class=\"box\" style=\"background-color:white\" title=\"50\"></div><div class=\"box\" style=\"background-color:pink\" title=\"25001\"></div><div class=\"box\" style=\"background-color:red\" title=\"300577\"></div><div class=\"box\" style=\"background-color:red\" title=\"102035\"></div><div class=\"box\" style=\"background-color:pink\" title=\"20581\"></div><div class=\"box\" style=\"background-color:red\" title=\"170240\"></div><div class=\"box\" style=\"background-color:red\" title=\"126101\"></div><div class=\"box\" style=\"background-color:pink\" title=\"18001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"15000\"></div><div class=\"box\" style=\"background-color:white\" title=\"4000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:red\" title=\"100003\"></div><div class=\"box\" style=\"background-color:pink\" title=\"35000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"14001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"72046\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:pink\" title=\"65006\"></div><div class=\"box\" style=\"background-color:pink\" title=\"56000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"42000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"17158\"></div><div class=\"box\" style=\"background-color:red\" title=\"135096\"></div><div class=\"box\" style=\"background-color:pink\" title=\"70040\"></div><div class=\"box\" style=\"background-color:red\" title=\"114068\"></div><div class=\"box\" style=\"background-color:pink\" title=\"22216\"></div><div class=\"box\" style=\"background-color:pink\" title=\"60020\"></div><div class=\"box\" style=\"background-color:white\" title=\"2742\"></div><div class=\"box\" style=\"background-color:pink\" title=\"35030\"></div><div class=\"box\" style=\"background-color:pink\" title=\"25000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"76005\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40600\"></div><div class=\"box\" style=\"background-color:pink\" title=\"48335\"></div><div class=\"box\" style=\"background-color:pink\" title=\"58000\"></div><div class=\"box\" style=\"background-color:white\" title=\"900\"></div><div class=\"box\" style=\"background-color:white\" title=\"8000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"19002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"92000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"13000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50008\"></div><div class=\"box\" style=\"background-color:pink\" title=\"20000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"15100\"></div><div class=\"box\" style=\"background-color:red\" title=\"108023\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50600\"></div><div class=\"box\" style=\"background-color:pink\" title=\"26483\"></div><div class=\"box\" style=\"background-color:pink\" title=\"38002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"53440\"></div><div class=\"box\" style=\"background-color:pink\" title=\"32007\"></div><div class=\"box\" style=\"background-color:pink\" title=\"25654\"></div><div class=\"box\" style=\"background-color:pink\" title=\"80130\"></div><div class=\"box\" style=\"background-color:pink\" title=\"20000\"></div><div class=\"box\" style=\"background-color:white\" title=\"9500\"></div><div class=\"box\" style=\"background-color:white\" title=\"1968\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalequantile-분위수\">scaleQuantile (분위수)<a href=\"https://alvin.ing/blog/d3-scale#scalequantile-%EB%B6%84%EC%9C%84%EC%88%98\" class=\"hash-link\" aria-label=\"scaleQuantile (분위수)에 대한 직접 링크\" title=\"scaleQuantile (분위수)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>domain을 동일한 절대 빈도의 간격으로 분할합니다. 분할 수는 range에 정의된 값들의 수와 같습니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 100개의 데이터를 균등하게 나눠서 값의 크기에 맞게 분류함</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> sampleData</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\">number</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">11002</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">29017</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">21699</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">47058</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">24001</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">6000</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> quantile </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleQuantile</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">sampleData</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token string\" style=\"color:#e3116c\">'white'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'pink'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'red'</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><h3>linear</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:rgb(255, 246, 246)\" title=\"11002\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"29017\"></div><div class=\"box\" style=\"background-color:rgb(255, 216, 216)\" title=\"45793\"></div><div class=\"box\" style=\"background-color:rgb(255, 249, 249)\" title=\"7000\"></div><div class=\"box\" style=\"background-color:rgb(255, 153, 153)\" title=\"120040\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"30138\"></div><div class=\"box\" style=\"background-color:rgb(255, 237, 237)\" title=\"21699\"></div><div class=\"box\" style=\"background-color:rgb(255, 215, 215)\" title=\"47058\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"24001\"></div><div class=\"box\" style=\"background-color:rgb(255, 250, 250)\" title=\"6000\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"69007\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40000\"></div><div class=\"box\" style=\"background-color:rgb(255, 208, 208)\" title=\"55001\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30001\"></div><div class=\"box\" style=\"background-color:rgb(255, 203, 203)\" title=\"61150\"></div><div class=\"box\" style=\"background-color:rgb(255, 245, 245)\" title=\"12000\"></div><div class=\"box\" style=\"background-color:rgb(255, 182, 182)\" title=\"85530\"></div><div class=\"box\" style=\"background-color:rgb(255, 185, 185)\" title=\"83000\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"23100\"></div><div class=\"box\" style=\"background-color:rgb(255, 173, 173)\" title=\"96225\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"45003\"></div><div class=\"box\" style=\"background-color:rgb(255, 226, 226)\" title=\"34300\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"43000\"></div><div class=\"box\" style=\"background-color:rgb(255, 201, 201)\" title=\"63131\"></div><div class=\"box\" style=\"background-color:rgb(255, 211, 211)\" title=\"52001\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"36000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"10001\"></div><div class=\"box\" style=\"background-color:rgb(255, 63, 63)\" title=\"225786\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"75000\"></div><div class=\"box\" style=\"background-color:rgb(255, 89, 89)\" title=\"195100\"></div><div class=\"box\" style=\"background-color:rgb(255, 227, 227)\" title=\"33010\"></div><div class=\"box\" style=\"background-color:rgb(255, 251, 251)\" title=\"5000\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"31213\"></div><div class=\"box\" style=\"background-color:rgb(255, 188, 188)\" title=\"79050\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40010\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"37002\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50000\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60000\"></div><div class=\"box\" style=\"background-color:rgb(255, 199, 199)\" title=\"66529\"></div><div class=\"box\" style=\"background-color:rgb(255, 222, 222)\" title=\"39048\"></div><div class=\"box\" style=\"background-color:rgb(255, 232, 232)\" title=\"27276\"></div><div class=\"box\" style=\"background-color:rgb(255, 231, 231)\" title=\"28007\"></div><div class=\"box\" style=\"background-color:rgb(255, 125, 125)\" title=\"153420\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"44500\"></div><div class=\"box\" style=\"background-color:rgb(255, 132, 132)\" title=\"145443\"></div><div class=\"box\" style=\"background-color:rgb(255, 179, 179)\" title=\"89550\"></div><div class=\"box\" style=\"background-color:rgb(255, 241, 241)\" title=\"16024\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"50\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25001\"></div><div class=\"box\" style=\"background-color:rgb(255, 0, 0)\" title=\"300577\"></div><div class=\"box\" style=\"background-color:rgb(255, 168, 168)\" title=\"102035\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20581\"></div><div class=\"box\" style=\"background-color:rgb(255, 111, 111)\" title=\"170240\"></div><div class=\"box\" style=\"background-color:rgb(255, 148, 148)\" title=\"126101\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"18001\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15000\"></div><div class=\"box\" style=\"background-color:rgb(255, 252, 252)\" title=\"4000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 170, 170)\" title=\"100003\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35000\"></div><div class=\"box\" style=\"background-color:rgb(255, 243, 243)\" title=\"14001\"></div><div class=\"box\" style=\"background-color:rgb(255, 194, 194)\" title=\"72046\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 200, 200)\" title=\"65006\"></div><div class=\"box\" style=\"background-color:rgb(255, 207, 207)\" title=\"56000\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"42000\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"17158\"></div><div class=\"box\" style=\"background-color:rgb(255, 140, 140)\" title=\"135096\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"70040\"></div><div class=\"box\" style=\"background-color:rgb(255, 158, 158)\" title=\"114068\"></div><div class=\"box\" style=\"background-color:rgb(255, 236, 236)\" title=\"22216\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60020\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"2742\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35030\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25000\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"76005\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40600\"></div><div class=\"box\" style=\"background-color:rgb(255, 214, 214)\" title=\"48335\"></div><div class=\"box\" style=\"background-color:rgb(255, 206, 206)\" title=\"58000\"></div><div class=\"box\" style=\"background-color:rgb(255, 254, 254)\" title=\"900\"></div><div class=\"box\" style=\"background-color:rgb(255, 248, 248)\" title=\"8000\"></div><div class=\"box\" style=\"background-color:rgb(255, 239, 239)\" title=\"19002\"></div><div class=\"box\" style=\"background-color:rgb(255, 177, 177)\" title=\"92000\"></div><div class=\"box\" style=\"background-color:rgb(255, 244, 244)\" title=\"13000\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50008\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15100\"></div><div class=\"box\" style=\"background-color:rgb(255, 163, 163)\" title=\"108023\"></div><div class=\"box\" style=\"background-color:rgb(255, 212, 212)\" title=\"50600\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"26483\"></div><div class=\"box\" style=\"background-color:rgb(255, 223, 223)\" title=\"38002\"></div><div class=\"box\" style=\"background-color:rgb(255, 210, 210)\" title=\"53440\"></div><div class=\"box\" style=\"background-color:rgb(255, 228, 228)\" title=\"32007\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"25654\"></div><div class=\"box\" style=\"background-color:rgb(255, 187, 187)\" title=\"80130\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"9500\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"1968\"></div></div><h3>quantile</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:white\" title=\"11002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"29017\"></div><div class=\"box\" style=\"background-color:pink\" title=\"45793\"></div><div class=\"box\" style=\"background-color:white\" title=\"7000\"></div><div class=\"box\" style=\"background-color:red\" title=\"120040\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30138\"></div><div class=\"box\" style=\"background-color:white\" title=\"21699\"></div><div class=\"box\" style=\"background-color:pink\" title=\"47058\"></div><div class=\"box\" style=\"background-color:white\" title=\"24001\"></div><div class=\"box\" style=\"background-color:white\" title=\"6000\"></div><div class=\"box\" style=\"background-color:red\" title=\"69007\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40000\"></div><div class=\"box\" style=\"background-color:red\" title=\"55001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30001\"></div><div class=\"box\" style=\"background-color:red\" title=\"61150\"></div><div class=\"box\" style=\"background-color:white\" title=\"12000\"></div><div class=\"box\" style=\"background-color:red\" title=\"85530\"></div><div class=\"box\" style=\"background-color:red\" title=\"83000\"></div><div class=\"box\" style=\"background-color:white\" title=\"23100\"></div><div class=\"box\" style=\"background-color:red\" title=\"96225\"></div><div class=\"box\" style=\"background-color:pink\" title=\"45003\"></div><div class=\"box\" style=\"background-color:pink\" title=\"34300\"></div><div class=\"box\" style=\"background-color:pink\" title=\"43000\"></div><div class=\"box\" style=\"background-color:red\" title=\"63131\"></div><div class=\"box\" style=\"background-color:pink\" title=\"52001\"></div><div class=\"box\" style=\"background-color:pink\" title=\"36000\"></div><div class=\"box\" style=\"background-color:white\" title=\"10001\"></div><div class=\"box\" style=\"background-color:red\" title=\"225786\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:red\" title=\"75000\"></div><div class=\"box\" style=\"background-color:red\" title=\"195100\"></div><div class=\"box\" style=\"background-color:pink\" title=\"33010\"></div><div class=\"box\" style=\"background-color:white\" title=\"5000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"31213\"></div><div class=\"box\" style=\"background-color:red\" title=\"79050\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40010\"></div><div class=\"box\" style=\"background-color:pink\" title=\"37002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50000\"></div><div class=\"box\" style=\"background-color:red\" title=\"60000\"></div><div class=\"box\" style=\"background-color:red\" title=\"66529\"></div><div class=\"box\" style=\"background-color:pink\" title=\"39048\"></div><div class=\"box\" style=\"background-color:pink\" title=\"27276\"></div><div class=\"box\" style=\"background-color:pink\" title=\"28007\"></div><div class=\"box\" style=\"background-color:red\" title=\"153420\"></div><div class=\"box\" style=\"background-color:pink\" title=\"44500\"></div><div class=\"box\" style=\"background-color:red\" title=\"145443\"></div><div class=\"box\" style=\"background-color:red\" title=\"89550\"></div><div class=\"box\" style=\"background-color:white\" title=\"16024\"></div><div class=\"box\" style=\"background-color:white\" title=\"50\"></div><div class=\"box\" style=\"background-color:white\" title=\"25001\"></div><div class=\"box\" style=\"background-color:red\" title=\"300577\"></div><div class=\"box\" style=\"background-color:red\" title=\"102035\"></div><div class=\"box\" style=\"background-color:white\" title=\"20581\"></div><div class=\"box\" style=\"background-color:red\" title=\"170240\"></div><div class=\"box\" style=\"background-color:red\" title=\"126101\"></div><div class=\"box\" style=\"background-color:white\" title=\"18001\"></div><div class=\"box\" style=\"background-color:white\" title=\"15000\"></div><div class=\"box\" style=\"background-color:white\" title=\"4000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:red\" title=\"100003\"></div><div class=\"box\" style=\"background-color:pink\" title=\"35000\"></div><div class=\"box\" style=\"background-color:white\" title=\"14001\"></div><div class=\"box\" style=\"background-color:red\" title=\"72046\"></div><div class=\"box\" style=\"background-color:pink\" title=\"30000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:red\" title=\"65006\"></div><div class=\"box\" style=\"background-color:red\" title=\"56000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"42000\"></div><div class=\"box\" style=\"background-color:white\" title=\"17158\"></div><div class=\"box\" style=\"background-color:red\" title=\"135096\"></div><div class=\"box\" style=\"background-color:red\" title=\"70040\"></div><div class=\"box\" style=\"background-color:red\" title=\"114068\"></div><div class=\"box\" style=\"background-color:white\" title=\"22216\"></div><div class=\"box\" style=\"background-color:red\" title=\"60020\"></div><div class=\"box\" style=\"background-color:white\" title=\"2742\"></div><div class=\"box\" style=\"background-color:pink\" title=\"35030\"></div><div class=\"box\" style=\"background-color:white\" title=\"25000\"></div><div class=\"box\" style=\"background-color:red\" title=\"76005\"></div><div class=\"box\" style=\"background-color:pink\" title=\"40600\"></div><div class=\"box\" style=\"background-color:pink\" title=\"48335\"></div><div class=\"box\" style=\"background-color:red\" title=\"58000\"></div><div class=\"box\" style=\"background-color:white\" title=\"900\"></div><div class=\"box\" style=\"background-color:white\" title=\"8000\"></div><div class=\"box\" style=\"background-color:white\" title=\"19002\"></div><div class=\"box\" style=\"background-color:red\" title=\"92000\"></div><div class=\"box\" style=\"background-color:white\" title=\"13000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50008\"></div><div class=\"box\" style=\"background-color:white\" title=\"20000\"></div><div class=\"box\" style=\"background-color:white\" title=\"15100\"></div><div class=\"box\" style=\"background-color:red\" title=\"108023\"></div><div class=\"box\" style=\"background-color:pink\" title=\"50600\"></div><div class=\"box\" style=\"background-color:pink\" title=\"26483\"></div><div class=\"box\" style=\"background-color:pink\" title=\"38002\"></div><div class=\"box\" style=\"background-color:pink\" title=\"53440\"></div><div class=\"box\" style=\"background-color:pink\" title=\"32007\"></div><div class=\"box\" style=\"background-color:pink\" title=\"25654\"></div><div class=\"box\" style=\"background-color:red\" title=\"80130\"></div><div class=\"box\" style=\"background-color:white\" title=\"20000\"></div><div class=\"box\" style=\"background-color:white\" title=\"9500\"></div><div class=\"box\" style=\"background-color:white\" title=\"1968\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"scalequantize-양자화\">scaleQuantize (양자화)<a href=\"https://alvin.ing/blog/d3-scale#scalequantize-%EC%96%91%EC%9E%90%ED%99%94\" class=\"hash-link\" aria-label=\"scaleQuantize (양자화)에 대한 직접 링크\" title=\"scaleQuantize (양자화)에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>domain 범위에서 임계값 선택을 처리하고, range에 정의된 값들의 수만큼 규칙적인 간격으로 세분화합니다.</p>\n<div class=\"language-typescript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-typescript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 0~100192 white, 100193~200384 pink, 200385~300577 red</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> quantize </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token generic-function function\" style=\"color:#d73a49\">scaleQuantize</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&lt;</span><span class=\"token generic-function generic class-name builtin\">string</span><span class=\"token generic-function generic class-name operator\" style=\"color:#393A34\">&gt;</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">domain</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">0</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">300577</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token function\" style=\"color:#d73a49\">range</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token string\" style=\"color:#e3116c\">'white'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'pink'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'red'</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"scale\"><h3>linear</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:rgb(255, 246, 246)\" title=\"11002\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"29017\"></div><div class=\"box\" style=\"background-color:rgb(255, 216, 216)\" title=\"45793\"></div><div class=\"box\" style=\"background-color:rgb(255, 249, 249)\" title=\"7000\"></div><div class=\"box\" style=\"background-color:rgb(255, 153, 153)\" title=\"120040\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"30138\"></div><div class=\"box\" style=\"background-color:rgb(255, 237, 237)\" title=\"21699\"></div><div class=\"box\" style=\"background-color:rgb(255, 215, 215)\" title=\"47058\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"24001\"></div><div class=\"box\" style=\"background-color:rgb(255, 250, 250)\" title=\"6000\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"69007\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40000\"></div><div class=\"box\" style=\"background-color:rgb(255, 208, 208)\" title=\"55001\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30001\"></div><div class=\"box\" style=\"background-color:rgb(255, 203, 203)\" title=\"61150\"></div><div class=\"box\" style=\"background-color:rgb(255, 245, 245)\" title=\"12000\"></div><div class=\"box\" style=\"background-color:rgb(255, 182, 182)\" title=\"85530\"></div><div class=\"box\" style=\"background-color:rgb(255, 185, 185)\" title=\"83000\"></div><div class=\"box\" style=\"background-color:rgb(255, 235, 235)\" title=\"23100\"></div><div class=\"box\" style=\"background-color:rgb(255, 173, 173)\" title=\"96225\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"45003\"></div><div class=\"box\" style=\"background-color:rgb(255, 226, 226)\" title=\"34300\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"43000\"></div><div class=\"box\" style=\"background-color:rgb(255, 201, 201)\" title=\"63131\"></div><div class=\"box\" style=\"background-color:rgb(255, 211, 211)\" title=\"52001\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"36000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"10001\"></div><div class=\"box\" style=\"background-color:rgb(255, 63, 63)\" title=\"225786\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"75000\"></div><div class=\"box\" style=\"background-color:rgb(255, 89, 89)\" title=\"195100\"></div><div class=\"box\" style=\"background-color:rgb(255, 227, 227)\" title=\"33010\"></div><div class=\"box\" style=\"background-color:rgb(255, 251, 251)\" title=\"5000\"></div><div class=\"box\" style=\"background-color:rgb(255, 229, 229)\" title=\"31213\"></div><div class=\"box\" style=\"background-color:rgb(255, 188, 188)\" title=\"79050\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40010\"></div><div class=\"box\" style=\"background-color:rgb(255, 224, 224)\" title=\"37002\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50000\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60000\"></div><div class=\"box\" style=\"background-color:rgb(255, 199, 199)\" title=\"66529\"></div><div class=\"box\" style=\"background-color:rgb(255, 222, 222)\" title=\"39048\"></div><div class=\"box\" style=\"background-color:rgb(255, 232, 232)\" title=\"27276\"></div><div class=\"box\" style=\"background-color:rgb(255, 231, 231)\" title=\"28007\"></div><div class=\"box\" style=\"background-color:rgb(255, 125, 125)\" title=\"153420\"></div><div class=\"box\" style=\"background-color:rgb(255, 217, 217)\" title=\"44500\"></div><div class=\"box\" style=\"background-color:rgb(255, 132, 132)\" title=\"145443\"></div><div class=\"box\" style=\"background-color:rgb(255, 179, 179)\" title=\"89550\"></div><div class=\"box\" style=\"background-color:rgb(255, 241, 241)\" title=\"16024\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"50\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25001\"></div><div class=\"box\" style=\"background-color:rgb(255, 0, 0)\" title=\"300577\"></div><div class=\"box\" style=\"background-color:rgb(255, 168, 168)\" title=\"102035\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20581\"></div><div class=\"box\" style=\"background-color:rgb(255, 111, 111)\" title=\"170240\"></div><div class=\"box\" style=\"background-color:rgb(255, 148, 148)\" title=\"126101\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"18001\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15000\"></div><div class=\"box\" style=\"background-color:rgb(255, 252, 252)\" title=\"4000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 170, 170)\" title=\"100003\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35000\"></div><div class=\"box\" style=\"background-color:rgb(255, 243, 243)\" title=\"14001\"></div><div class=\"box\" style=\"background-color:rgb(255, 194, 194)\" title=\"72046\"></div><div class=\"box\" style=\"background-color:rgb(255, 230, 230)\" title=\"30000\"></div><div class=\"box\" style=\"background-color:rgb(255, 255, 255)\" title=\"0\"></div><div class=\"box\" style=\"background-color:rgb(255, 200, 200)\" title=\"65006\"></div><div class=\"box\" style=\"background-color:rgb(255, 207, 207)\" title=\"56000\"></div><div class=\"box\" style=\"background-color:rgb(255, 219, 219)\" title=\"42000\"></div><div class=\"box\" style=\"background-color:rgb(255, 240, 240)\" title=\"17158\"></div><div class=\"box\" style=\"background-color:rgb(255, 140, 140)\" title=\"135096\"></div><div class=\"box\" style=\"background-color:rgb(255, 196, 196)\" title=\"70040\"></div><div class=\"box\" style=\"background-color:rgb(255, 158, 158)\" title=\"114068\"></div><div class=\"box\" style=\"background-color:rgb(255, 236, 236)\" title=\"22216\"></div><div class=\"box\" style=\"background-color:rgb(255, 204, 204)\" title=\"60020\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"2742\"></div><div class=\"box\" style=\"background-color:rgb(255, 225, 225)\" title=\"35030\"></div><div class=\"box\" style=\"background-color:rgb(255, 234, 234)\" title=\"25000\"></div><div class=\"box\" style=\"background-color:rgb(255, 191, 191)\" title=\"76005\"></div><div class=\"box\" style=\"background-color:rgb(255, 221, 221)\" title=\"40600\"></div><div class=\"box\" style=\"background-color:rgb(255, 214, 214)\" title=\"48335\"></div><div class=\"box\" style=\"background-color:rgb(255, 206, 206)\" title=\"58000\"></div><div class=\"box\" style=\"background-color:rgb(255, 254, 254)\" title=\"900\"></div><div class=\"box\" style=\"background-color:rgb(255, 248, 248)\" title=\"8000\"></div><div class=\"box\" style=\"background-color:rgb(255, 239, 239)\" title=\"19002\"></div><div class=\"box\" style=\"background-color:rgb(255, 177, 177)\" title=\"92000\"></div><div class=\"box\" style=\"background-color:rgb(255, 244, 244)\" title=\"13000\"></div><div class=\"box\" style=\"background-color:rgb(255, 213, 213)\" title=\"50008\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 242, 242)\" title=\"15100\"></div><div class=\"box\" style=\"background-color:rgb(255, 163, 163)\" title=\"108023\"></div><div class=\"box\" style=\"background-color:rgb(255, 212, 212)\" title=\"50600\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"26483\"></div><div class=\"box\" style=\"background-color:rgb(255, 223, 223)\" title=\"38002\"></div><div class=\"box\" style=\"background-color:rgb(255, 210, 210)\" title=\"53440\"></div><div class=\"box\" style=\"background-color:rgb(255, 228, 228)\" title=\"32007\"></div><div class=\"box\" style=\"background-color:rgb(255, 233, 233)\" title=\"25654\"></div><div class=\"box\" style=\"background-color:rgb(255, 187, 187)\" title=\"80130\"></div><div class=\"box\" style=\"background-color:rgb(255, 238, 238)\" title=\"20000\"></div><div class=\"box\" style=\"background-color:rgb(255, 247, 247)\" title=\"9500\"></div><div class=\"box\" style=\"background-color:rgb(255, 253, 253)\" title=\"1968\"></div></div><h3>quantize</h3><div class=\"box-list\"><div class=\"box\" style=\"background-color:white\" title=\"11002\"></div><div class=\"box\" style=\"background-color:white\" title=\"29017\"></div><div class=\"box\" style=\"background-color:white\" title=\"45793\"></div><div class=\"box\" style=\"background-color:white\" title=\"7000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"120040\"></div><div class=\"box\" style=\"background-color:white\" title=\"30138\"></div><div class=\"box\" style=\"background-color:white\" title=\"21699\"></div><div class=\"box\" style=\"background-color:white\" title=\"47058\"></div><div class=\"box\" style=\"background-color:white\" title=\"24001\"></div><div class=\"box\" style=\"background-color:white\" title=\"6000\"></div><div class=\"box\" style=\"background-color:white\" title=\"69007\"></div><div class=\"box\" style=\"background-color:white\" title=\"40000\"></div><div class=\"box\" style=\"background-color:white\" title=\"55001\"></div><div class=\"box\" style=\"background-color:white\" title=\"30001\"></div><div class=\"box\" style=\"background-color:white\" title=\"61150\"></div><div class=\"box\" style=\"background-color:white\" title=\"12000\"></div><div class=\"box\" style=\"background-color:white\" title=\"85530\"></div><div class=\"box\" style=\"background-color:white\" title=\"83000\"></div><div class=\"box\" style=\"background-color:white\" title=\"23100\"></div><div class=\"box\" style=\"background-color:white\" title=\"96225\"></div><div class=\"box\" style=\"background-color:white\" title=\"45003\"></div><div class=\"box\" style=\"background-color:white\" title=\"34300\"></div><div class=\"box\" style=\"background-color:white\" title=\"43000\"></div><div class=\"box\" style=\"background-color:white\" title=\"63131\"></div><div class=\"box\" style=\"background-color:white\" title=\"52001\"></div><div class=\"box\" style=\"background-color:white\" title=\"36000\"></div><div class=\"box\" style=\"background-color:white\" title=\"10001\"></div><div class=\"box\" style=\"background-color:red\" title=\"225786\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:white\" title=\"75000\"></div><div class=\"box\" style=\"background-color:pink\" title=\"195100\"></div><div class=\"box\" style=\"background-color:white\" title=\"33010\"></div><div class=\"box\" style=\"background-color:white\" title=\"5000\"></div><div class=\"box\" style=\"background-color:white\" title=\"31213\"></div><div class=\"box\" style=\"background-color:white\" title=\"79050\"></div><div class=\"box\" style=\"background-color:white\" title=\"40010\"></div><div class=\"box\" style=\"background-color:white\" title=\"37002\"></div><div class=\"box\" style=\"background-color:white\" title=\"50000\"></div><div class=\"box\" style=\"background-color:white\" title=\"60000\"></div><div class=\"box\" style=\"background-color:white\" title=\"66529\"></div><div class=\"box\" style=\"background-color:white\" title=\"39048\"></div><div class=\"box\" style=\"background-color:white\" title=\"27276\"></div><div class=\"box\" style=\"background-color:white\" title=\"28007\"></div><div class=\"box\" style=\"background-color:pink\" title=\"153420\"></div><div class=\"box\" style=\"background-color:white\" title=\"44500\"></div><div class=\"box\" style=\"background-color:pink\" title=\"145443\"></div><div class=\"box\" style=\"background-color:white\" title=\"89550\"></div><div class=\"box\" style=\"background-color:white\" title=\"16024\"></div><div class=\"box\" style=\"background-color:white\" title=\"50\"></div><div class=\"box\" style=\"background-color:white\" title=\"25001\"></div><div class=\"box\" style=\"background-color:red\" title=\"300577\"></div><div class=\"box\" style=\"background-color:pink\" title=\"102035\"></div><div class=\"box\" style=\"background-color:white\" title=\"20581\"></div><div class=\"box\" style=\"background-color:pink\" title=\"170240\"></div><div class=\"box\" style=\"background-color:pink\" title=\"126101\"></div><div class=\"box\" style=\"background-color:white\" title=\"18001\"></div><div class=\"box\" style=\"background-color:white\" title=\"15000\"></div><div class=\"box\" style=\"background-color:white\" title=\"4000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:white\" title=\"100003\"></div><div class=\"box\" style=\"background-color:white\" title=\"35000\"></div><div class=\"box\" style=\"background-color:white\" title=\"14001\"></div><div class=\"box\" style=\"background-color:white\" title=\"72046\"></div><div class=\"box\" style=\"background-color:white\" title=\"30000\"></div><div class=\"box\" style=\"background-color:white\" title=\"0\"></div><div class=\"box\" style=\"background-color:white\" title=\"65006\"></div><div class=\"box\" style=\"background-color:white\" title=\"56000\"></div><div class=\"box\" style=\"background-color:white\" title=\"42000\"></div><div class=\"box\" style=\"background-color:white\" title=\"17158\"></div><div class=\"box\" style=\"background-color:pink\" title=\"135096\"></div><div class=\"box\" style=\"background-color:white\" title=\"70040\"></div><div class=\"box\" style=\"background-color:pink\" title=\"114068\"></div><div class=\"box\" style=\"background-color:white\" title=\"22216\"></div><div class=\"box\" style=\"background-color:white\" title=\"60020\"></div><div class=\"box\" style=\"background-color:white\" title=\"2742\"></div><div class=\"box\" style=\"background-color:white\" title=\"35030\"></div><div class=\"box\" style=\"background-color:white\" title=\"25000\"></div><div class=\"box\" style=\"background-color:white\" title=\"76005\"></div><div class=\"box\" style=\"background-color:white\" title=\"40600\"></div><div class=\"box\" style=\"background-color:white\" title=\"48335\"></div><div class=\"box\" style=\"background-color:white\" title=\"58000\"></div><div class=\"box\" style=\"background-color:white\" title=\"900\"></div><div class=\"box\" style=\"background-color:white\" title=\"8000\"></div><div class=\"box\" style=\"background-color:white\" title=\"19002\"></div><div class=\"box\" style=\"background-color:white\" title=\"92000\"></div><div class=\"box\" style=\"background-color:white\" title=\"13000\"></div><div class=\"box\" style=\"background-color:white\" title=\"50008\"></div><div class=\"box\" style=\"background-color:white\" title=\"20000\"></div><div class=\"box\" style=\"background-color:white\" title=\"15100\"></div><div class=\"box\" style=\"background-color:pink\" title=\"108023\"></div><div class=\"box\" style=\"background-color:white\" title=\"50600\"></div><div class=\"box\" style=\"background-color:white\" title=\"26483\"></div><div class=\"box\" style=\"background-color:white\" title=\"38002\"></div><div class=\"box\" style=\"background-color:white\" title=\"53440\"></div><div class=\"box\" style=\"background-color:white\" title=\"32007\"></div><div class=\"box\" style=\"background-color:white\" title=\"25654\"></div><div class=\"box\" style=\"background-color:white\" title=\"80130\"></div><div class=\"box\" style=\"background-color:white\" title=\"20000\"></div><div class=\"box\" style=\"background-color:white\" title=\"9500\"></div><div class=\"box\" style=\"background-color:white\" title=\"1968\"></div></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결론\">결론<a href=\"https://alvin.ing/blog/d3-scale#%EA%B2%B0%EB%A1%A0\" class=\"hash-link\" aria-label=\"결론에 대한 직접 링크\" title=\"결론에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>제니퍼5 안에는 한정된 스케일 종류로 구현된 차트와 컴포넌트 등이 존재합니다.\n다만 그때그때 상황에 맞게 구현했으며, 어떤 스케일이다라고 정의하지 않았을 뿐입니다. 지난 모니터링 스터디 준비를 하면서 몇가지 모니터링 제품을 살펴보았는데, 분위수나 로그 스케일 등을 사용하는 것을 목격한 적이 있습니다.\n그동안 데이터를 표현하는데, 데이터를 왜곡하면 안된다는 이유로 여러가지 시도를 해보지 못한 것에 대해 아쉬움이 있었습니다.\n이번에 D3 스케일을 살펴보고, 이해하는 과정에서 데이터 시각화에 대한 본질적인 목적, 이유에 대해 다시 한번 생각해보는 계기가 되었습니다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고\">참고<a href=\"https://alvin.ing/blog/d3-scale#%EC%B0%B8%EA%B3%A0\" class=\"hash-link\" aria-label=\"참고에 대한 직접 링크\" title=\"참고에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>대부분의 데이터는 본질적으로 계층 구조를 가지고 있습니다. D3는 이런 계층적 구조를 시각화하기 위한 다양한 기능을 제공합니다.\n해당 모듈이 제공하는 계층형 데이터 다이어그램의 종류는 3가지입니다. (노드-링크형, 인접형, 포함형)</p>\n<p>노드-링크 형은 제니퍼5의 콜-트리와 같은 Indented Tree나 Tiny Tree, Dendrogram이 있다. 아래는 인접형과 포함형 다이어그램입니다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/d3-hierarchy-4d9b00bb32f9ff9d1b8124aa048d20ec.png\" width=\"2214\" height=\"460\" class=\"img_ev3q\"></p>",
            "url": "https://alvin.ing/blog/d3-scale",
            "title": "데이터 시각화를 위한 D3 스케일에 대해 알아보자",
            "summary": "개요",
            "date_modified": "2022-06-28T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "D3.js"
            ]
        },
        {
            "id": "https://alvin.ing/blog/vuejs-springboot-starter",
            "content_html": "<p>최근에 SVN에서 Git으로 형상 관리 시스템을 변경하면서 GitLab을 접하게 되었는데, 필자는 GitLab의 명성(?)만 들어봤지 직접 사용해본 것은 이번이 처음이었다. GitHub에서 오픈소스 프로젝트를 수년간 진행하고 있어서 GitLab이랑 얼마나 차이가 있겠어라는 생각을 했던 것이 사실이다. 하지만 GitLab CI 기능을 접하게 되면서 새로운 세계에 눈을 뜨게 되었다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"gitlab-vs-github\">GitLab vs GitHub<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#gitlab-vs-github\" class=\"hash-link\" aria-label=\"GitLab vs GitHub에 대한 직접 링크\" title=\"GitLab vs GitHub에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>진행 중인 프로젝트의 특성에 따라 선택하면 된다. 필자처럼 범용적인 프레임워크나 라이브러리를 개발한다면 아무거나 사용해도 상관없지만 아무래도 개발자 유입이 많고, 필자처럼 늘어나는 별을 보며 즐거움을 얻고자 한다면 GitHub를 추천한다. 다만 프로덕트나 서비스 개발을 해야한다면 GitLab을 선택하는 것이 좋다. 프라이빗 프로젝트를 기본적으로 생성할 수 있고, 몇년전부터 이슈가 되고 있는 DevOps를 실현하기 위해서 GitLab CI 기능을 사용하여 테스트 및 빌드, 배포를 자동화할 수 있다.</p>\n<blockquote>\n<p>GitHub 프로젝트는 Travis CI를 통해 테스트 및 빌드, 배포를 자동화할 수 있다.</p>\n</blockquote>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"개발환경-설정\">개발환경 설정<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95\" class=\"hash-link\" aria-label=\"개발환경 설정에 대한 직접 링크\" title=\"개발환경 설정에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>본문에서는 “Webpack+SpringBoot 기반의 프론트엔드 개발환경 구축하기”에서 다루지 않는 몇가지 추가 설정에 대한 내용만 설명할 것이기 때문에 해당 글을 먼저 읽는 것을 권장한다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"babel-7\">Babel 7<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#babel-7\" class=\"hash-link\" aria-label=\"Babel 7에 대한 직접 링크\" title=\"Babel 7에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저 babel 6버전을 7버전으로 업그레이드 했기 때문에 웹팩 설정 파일에 있는 babel-loader의 preset 설정을 babel.config.js로 이전해야 한다. 테스트를 위해 Jest 프레임워크를 사용하거나 polyfill을 사용할 때도 필요한 설정이니 기억해두자.</p>\n<blockquote>\n<p>npm i -D @babel/core @babel/preset-env babel-core@7.0.0-bridge.0</p>\n</blockquote>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"presets\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:#e3116c\">\"@babel/preset-env\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"useBuiltIns\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"entry\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"env\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"test\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"presets\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:#e3116c\">\"@babel/preset-env\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"targets\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">              </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"node\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"polyfill\">Polyfill<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#polyfill\" class=\"hash-link\" aria-label=\"Polyfill에 대한 직접 링크\" title=\"Polyfill에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>서버에서 데이터를 비동기로 가져오기 위해 Promise 대신 async/await 키워드를 사용했기 때문에 polyfill을 로드해야 한다. 설정 방법은 여러가지가 있는데, 필자는 먼저 babel.config.js에서 useBuiltIns 값을 entry로 설정하고, 엔트리 js 파일에서 import ‘@babel/polifill’ 구문을 추가하는 방법을 택했다.</p>\n<blockquote>\n<p>npm i @babel/polyfill</p>\n</blockquote>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"jest\">Jest<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#jest\" class=\"hash-link\" aria-label=\"Jest에 대한 직접 링크\" title=\"Jest에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>Jest 프레임워크의 테스트는 노드 환경에서 동작하기 때문에 babel.config.js 파일에서 targets.node 값을 true로 설정해야 한다. 뷰 컴포넌트를 테스트하기 위해 다음 모듈을 추가로 설치하자.</p>\n<blockquote>\n<p>npm i -D babel-jest jest jest-serializer-vue vue-jest vue-template-compiler vue-test-utils sinon</p>\n</blockquote>\n<p>다음은 Jest 설정 파일이다. 여기서 중요한 부분은 transformIgnorePatterns 값을 빈 배열로 설정해야 한다. 기본값이 node_modules라서 NPM에 배포된 모듈을 사용한다면 테스트 실행시 에러가 발생한다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"setupFiles\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"./src/test/client/setup.js\"</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"verbose\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"moduleFileExtensions\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string\" style=\"color:#e3116c\">\"js\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string\" style=\"color:#e3116c\">\"json\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string\" style=\"color:#e3116c\">\"vue\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"moduleNameMapper\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"^@/(.*)$\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"&lt;rootDir&gt;/src/main/client/$1\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"transform\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"^.+\\\\.js$\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"&lt;rootDir&gt;/node_modules/babel-jest\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string-property property\" style=\"color:#36acaa\">\".*\\\\.(vue)$\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"&lt;rootDir&gt;/node_modules/vue-jest\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"snapshotSerializers\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token string\" style=\"color:#e3116c\">\"&lt;rootDir&gt;/node_modules/jest-serializer-vue\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token string-property property\" style=\"color:#36acaa\">\"transformIgnorePatterns\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>Jest 프레임워크는 브라우저가 아닌 노드 환경에서 실행되기 때문에 사용할 수 없는 객체에 대한 처리가 필요하다. 화면을 구성하기 위해 차트 모듈을 사용하였고, 차트 모듈 내부적으로 캔버스 객체를 생성하기 때문에 아래와 같이 처리하였다. 참고로 sinon은 테스트 스텁을 위한 프레임워크인데, 본문에서 관련 내용은 다루지 않을 것이다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports\">sinon</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'sinon'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> createElement </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> global</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">document</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">createElement</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">FAKECanvasElement</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">getContext</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> jest</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">fn</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">fillStyle</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword null nil\" style=\"color:#00009f\">null</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">fillRect</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> jest</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">fn</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">drawImage</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> jest</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">fn</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">getImageData</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> jest</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">fn</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">sinon</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">stub</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">global</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">document</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'createElement'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">callsFake</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">createElement</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">withArgs</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'canvas'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">returns</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token maybe-class-name\">FAKECanvasElement</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"vuejs\">Vue.js<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#vuejs\" class=\"hash-link\" aria-label=\"Vue.js에 대한 직접 링크\" title=\"Vue.js에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>사실 Vue.js 관련 설정은 특별할 것이 없어서 본문에서 다루지 않을것이다. 다만 Jest 프레임워크와 vue-test-utils를 사용하여 뷰 컴포넌트 단위의 테스트 방법에 대해 간략하게 알아보자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:#393A34\">{</span><span class=\"token imports\"> shallow </span><span class=\"token imports punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'vue-test-utils'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">DetailMarketComp</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'@/detailMarket'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:#393A34\">{</span><span class=\"token imports\"> data </span><span class=\"token imports punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'../samples.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">describe</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'detailMarket.vue'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> cmp </span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">beforeEach</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        cmp </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">shallow</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token maybe-class-name\">DetailMarketComp</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">propsData</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">title</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'Min Market Cap'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">data</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> data</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token number\" style=\"color:#36acaa\">2</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">it</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'snapshot'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        cmp</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">vm</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">$nextTick</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token function\" style=\"color:#d73a49\">expect</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">cmp</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">vm</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">$el</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">toMatchSnapshot</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">it</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'computed'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token function\" style=\"color:#d73a49\">expect</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">cmp</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">vm</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">maxYear</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">toEqual</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'2017'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token function\" style=\"color:#d73a49\">expect</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">cmp</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">vm</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">minYear</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">toEqual</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'2015'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>detailMarket.spec.js는 기업의 시가총액이 최대인 연도와 최소인 연도를 테이블로 보여주는 뷰 컴포넌트에 대한 테스트 코드이다. 샘플 데이터에 대한 computed properties를 검증하고, 실제 마크업 코드로 출력될 텍스트를 스냅샷 한다.</p>\n<div class=\"language-html codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-html codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">// Jest Snapshot v1, https://goo.gl/fbAQLP</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">exports[`detailMarket.vue snapshot 1`] = `</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">h5</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    Min Market Cap</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">h5</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">table</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">thead</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">tr</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          Company</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          Max Year</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          Min Year</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">th</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">tr</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">thead</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">tbody</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">tr</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          Facebook</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          2017</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          2015</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">td</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">tr</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">tbody</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">table</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">`;</span><br></div></code></pre></div></div>\n<p>필자의 경험상 간단한 마크업 구조의 뷰 컴포넌트나 SVG 기반의 뷰 컴포넌트는 이미지 스냅샷 테스트를 하지 않는 것이 정신 건강에 좋다고 생각한다. 특히 SVG는 마크업과 달리 엘리먼트 속성에 대부분의 스타일이 들어가기 때문에 텍스트 스냅샷만으로도 충분히 검증할 수 있다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-스펙\">프로젝트 스펙<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8A%A4%ED%8E%99\" class=\"hash-link\" aria-label=\"프로젝트 스펙에 대한 직접 링크\" title=\"프로젝트 스펙에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>본문을 잘 이해시키기 위해 샘플 프로젝트를 GitLab에 생성해두었으며, 프로젝트 스펙은 다음과 같다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기능-스펙\">기능 스펙<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B8%B0%EB%8A%A5-%EC%8A%A4%ED%8E%99\" class=\"hash-link\" aria-label=\"기능 스펙에 대한 직접 링크\" title=\"기능 스펙에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>서버는 글로벌 기업에 대한 마켓 데이터를 JSON 형태로 전달해주며, 클라이언트는 서버로부터 전달받은 데이터를 각각의 뷰 컴포넌트에 맞게 가공하여 화면을 구현한다. 좌측은 기업별 시가총액에 대한 비율을 차트로 보여주며, 우측은 최대/최소 기업에 대한 정보를 테이블로 보여준다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/1-42227cb972f6c9cf2fec0010492b432f.webp\" width=\"1038\" height=\"831\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"기술-스펙\">기술 스펙<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%8E%99\" class=\"hash-link\" aria-label=\"기술 스펙에 대한 직접 링크\" title=\"기술 스펙에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<ol>\n<li class=\"\">모듈 번들러 : Webpack 4</li>\n<li class=\"\">개발환경 서버 : Webpack Dev Server</li>\n<li class=\"\">JavaScript 컴파일러 : Babel 7</li>\n<li class=\"\">JavaScript 프레임워크 : Vue.js 2</li>\n<li class=\"\">Java 프레임워크 : Spring Boot 1.5</li>\n<li class=\"\">서버 사이드 템플릿 : Thymeleaf</li>\n<li class=\"\">CSS 컴파일러 : Sass</li>\n<li class=\"\">JavaScript 테스트 도구 : Jest, Sinon</li>\n<li class=\"\">Java 테스트 도구 : JUnit</li>\n<li class=\"\">프로젝트 빌드 도구 : Maven 3</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ci-프로세스-요약\">CI 프로세스 요약<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#ci-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%9A%94%EC%95%BD\" class=\"hash-link\" aria-label=\"CI 프로세스 요약에 대한 직접 링크\" title=\"CI 프로세스 요약에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>스프링부트는 간단하게 하나의 JAR 파일로 배포할 수 있다. 물론 프로젝트 규모에 따라 번들 파일이나 이미지 등은 JAR 파일에서 분리하여 별도의 CDN 서버에 배포할 수도 있다. 참고로 클라이언트 번들 파일들과 최종 프로젝트 아웃풋 파일은 버전 관리 대상에 포함되지 않는다. 해당 파일들은 CI 환경에서만 생성해야하며 최종 아웃풋 파일은 다른 레파지토리에 전달하는 형태로 진행해야 한다.</p>\n<ol>\n<li class=\"\">클라이언트 테스트</li>\n<li class=\"\">클라이언트 빌드</li>\n<li class=\"\">서버 테스트</li>\n<li class=\"\">서버 빌드</li>\n<li class=\"\">JAR 파일 배포</li>\n<li class=\"\">Git 태그 생성</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ci-프로세스-상세\">CI 프로세스 상세<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#ci-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%83%81%EC%84%B8\" class=\"hash-link\" aria-label=\"CI 프로세스 상세에 대한 직접 링크\" title=\"CI 프로세스 상세에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>먼저 GitLab에서 프로젝트를 생성하면 Set up CI/CD 버튼을 클릭하여 .gitlab-ci.yml 파일을 쉽게 생성할 수 있다. 본문에서는 샘플 프로젝트에 작성되어 있는 .gitlab-ci.yml의 내용을 앞에서 요약한 CI 프로세스의 단계 별로 자세히 알아볼 것이다. 참고로 각각의 단계를 잡(Job) 단위로 구성할 수 있는데, 실행 순서를 임의로 설정할 수 있다. 이를 스테이지(Stage)라고 말하며 모든 스테이지가 순차적으로 실행되는 일련의 과정을 파이프라인(Pipeline)이라 한다.</p>\n<blockquote>\n<p>GitLab에서 개인 프로젝트는 그룹당 파이프라인 수행시간이 월 2000분(약 33시간)으로 제한되어 있다. 물론 돈으로 해결할 수 있다.</p>\n</blockquote>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공통-설정-variables\">공통 설정 (variables)<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B3%B5%ED%86%B5-%EC%84%A4%EC%A0%95-variables\" class=\"hash-link\" aria-label=\"공통 설정 (variables)에 대한 직접 링크\" title=\"공통 설정 (variables)에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>.gitlab-ci.yml에서 사용할 수 있는 변수들을 정의할 수 있다. 참고로 $ACCESS_TOKEN는 ‘GitLab 프로젝트 &gt; Settings &gt; CI / CD &gt; Variables 설정’에서 추가한 변수인데, (6) Git 태그 생성에서 자세히 다룰 것이다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공통-설정-cache\">공통 설정 (cache)<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B3%B5%ED%86%B5-%EC%84%A4%EC%A0%95-cache\" class=\"hash-link\" aria-label=\"공통 설정 (cache)에 대한 직접 링크\" title=\"공통 설정 (cache)에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>스테이지가 진행될 때, 생성되는 파일들은 다음 스테이지에서 사용할 수 없기 때문에 이미 설치된 모듈들을 다시 설치해야 하거나 생성된 파일들을 다음 스테이지에서 사용해야 하는 경우에 필요한 설정이다. 참고로 key에 설정된 $CI_COMMIT_REF_NAME은 GitLab CI 환경에서 미리 정의해둔 변수인데, 파이프라인이 동작할 때 대상이 되는 브랜치 이름이다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공통-설정-stages\">공통 설정 (stages)<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B3%B5%ED%86%B5-%EC%84%A4%EC%A0%95-stages\" class=\"hash-link\" aria-label=\"공통 설정 (stages)에 대한 직접 링크\" title=\"공통 설정 (stages)에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>각각의 잡(Job)들의 실행 순서를 정할 수 있다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"공통-설정-only\">공통 설정 (only)<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B3%B5%ED%86%B5-%EC%84%A4%EC%A0%95-only\" class=\"hash-link\" aria-label=\"공통 설정 (only)에 대한 직접 링크\" title=\"공통 설정 (only)에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>파이프라인의 동작 조건을 설정할 수 있다. 특정 디렉토리나 파일이 변경될 때 동작되도록 설정하기 위해서는 changes 설정을 사용하면 되고, refs 설정을 통해 동작 조건의 기본 정책을 정할 수 있다. 필자는 머지 요청(MR)이 발생할 때만 동작하도록 설정했다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"job_only\">.Job_Only<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#job_only\" class=\"hash-link\" aria-label=\".Job_Only에 대한 직접 링크\" title=\".Job_Only에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>사용자가 임의로 만들 수 있는 일종의 클래스라고 볼 수 있으며, 잡(Job)들은 상속받을 수 있다. 중복 설정을 막을 수 있는 효과가 있기 때문에 설정 파일을 간결하게 작성할 수 있다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token key atrule\" style=\"color:#00a4db\">variables</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">MAVEN_CLI_OPTS</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"--batch-mode\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">MAVEN_OPTS</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"-Dmaven.repo.local=.m2/repository\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">CI_REPOSITORY_URL</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> https</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">//alvin.h</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">$ACCESS_TOKEN@gitlab.com/$CI_PROJECT_PATH.git</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">cache</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">key</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"$CI_COMMIT_REF_NAME\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">paths</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> src/main/resources/static/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> dist/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> node_modules/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> .m2/repository/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">stages</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> fetest</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> febuild</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> betest</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> bebuild</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> deploy</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> patch</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">.Job_Only</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">only</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token key atrule\" style=\"color:#00a4db\">changes</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"src/**/*\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token key atrule\" style=\"color:#00a4db\">refs</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> merge_requests</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-클라이언트-테스트\">(1) 클라이언트 테스트<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#1-%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8-%ED%85%8C%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"(1) 클라이언트 테스트에 대한 직접 링크\" title=\"(1) 클라이언트 테스트에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>npm install 명령어를 통해 테스트에 필요한 모듈들을 설치하고, Jest 테스트를 실행한다. 참고로 실행 결과 텍스트를 정규식으로 파싱해서 커버리지 값으로 사용할 수 있다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">FE_Test</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">extends</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> .Job_Only</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> node</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> fetest</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">before_script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> npm install</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> npm test</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">coverage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> /All files\\s</span><span class=\"token important\">*\\|\\s*(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\">\\d\\.</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\">+)/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<p>커버리지 텍스트 중에서 All files 부분을 파싱하며, ‘GitLab 프로젝트 &gt; Settings &gt; CI / CD 설정’에서 Pipeline status와 Coverage report를 마크다운이나 HTML 코드로 가져올 수 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/2-2d459144afd2175ab257307e64633b6a.webp\" width=\"1400\" height=\"1058\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-클라이언트-빌드\">(2) 클라이언트 빌드<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#2-%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8-%EB%B9%8C%EB%93%9C\" class=\"hash-link\" aria-label=\"(2) 클라이언트 빌드에 대한 직접 링크\" title=\"(2) 클라이언트 빌드에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>fetest 스테이지에서 node_modules 디렉토리를 캐시해두었기 때문에 before_script 명령어는 조금 빨리 실행될 것이다. 웹팩 빌드를 하고 생성되는 번들 파일들은 공통 설정에서 캐시 처리를 해두었기 때문에 BE_Build 스테이지에서 메이븐 빌드시 최종 아웃풋 파일에 포함된다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">FE_Build</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">extends</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> .Job_Only</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> node</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> febuild</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">before_script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> npm install</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> npm run dist</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> ls </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">all ./src/main/resources/static</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-서버-테스트\">(3) 서버 테스트<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#3-%EC%84%9C%EB%B2%84-%ED%85%8C%EC%8A%A4%ED%8A%B8\" class=\"hash-link\" aria-label=\"(3) 서버 테스트에 대한 직접 링크\" title=\"(3) 서버 테스트에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>메이븐 테스트를 실행하며, 테스트에 필요한 모듈들은 알아서 설치된다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">BE_Test</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">extends</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> .Job_Only</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> maven</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">3.3.9</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> betest</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> mvn test $MAVEN_OPTS</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-서버-빌드\">(4) 서버 빌드<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#4-%EC%84%9C%EB%B2%84-%EB%B9%8C%EB%93%9C\" class=\"hash-link\" aria-label=\"(4) 서버 빌드에 대한 직접 링크\" title=\"(4) 서버 빌드에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>betest 스테이지에서 .m2/repository 디렉토리를 캐시해두었기 때문에 메이븐 빌드가 조금 빨리 실행될 것이다. 참고로 클라이언트는 테스트와 빌드를 분리했기 때문에 서버도 분리하기 위해 -DskipTests=true를 통해 메이븐 빌드만 실행되게 설정했다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">BE_Build</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">extends</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> .Job_Only</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> maven</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">3.3.9</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> bebuild</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> mvn install </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">DskipTests=true $MAVEN_OPTS $MAVEN_CLI_OPTS</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<p>(5) JAR 파일 배포\nbebuild 스테이지에서 dist 디렉토리를 캐시해두었기 때문에 최종 아웃풋 파일을 가져와서 별도의 서버에 배포할 수 있다. 배포 방법은 자신의 환경에 맞게 정하면 되는데, 필자는 sshpass+scp 명령어를 사용하여 지인에게 대여(?) 받은 서버에 전송하는 형태로 구현하였다.</p>\n<blockquote>\n<p>처음에는 expect를 사용하여 scp 명령어를 수행하였는데, GitLab CI 환경에서는 잘 동작하지 않는다.</p>\n</blockquote>\n<p>deploy 스테이지에서는 $POM_VERSION과 $SSH_PASSWORD 변수를 사용하는데, 먼저 메이븐 명령어를 통해 프로젝트의 pom.xml에 명시된 버전을 가져와서 $POM_VERSION 변수에 값을 할당한다. 프로젝트의 버전이 변경되면 배포 서버에 전송할 파일의 이름도 변경되는 문제를 해결할 수 있다. 그리고 SSH 계정의 비밀번호를 .gitlab-ci.yml 파일에 공개할 수 없기 때문에 ‘GitLab 프로젝트 &gt; Settings &gt; CI / CD &gt; Variables 설정'에 $SSH_PASSWORD 변수를 추가하였다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">Deploy</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">extends</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> .Job_Only</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> maven</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">3.3.9</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> deploy</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">before_script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> POM_VERSION=$(mvn </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">q </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">Dexec.executable=echo </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">Dexec.args='$</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">project.version</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\">' </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">non</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">recursive exec</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">exec)</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> apt</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">get update </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">qq </span><span class=\"token important\">&amp;&amp;</span><span class=\"token plain\"> apt</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">get install </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">y </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">qq sshpass</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> ls </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">all ./dist</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> sshpass </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">V</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> export SSHPASS=$SSH_PASSWORD</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> sshpass </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">e scp </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">r </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">oStrictHostKeyChecking=no </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">P51022 ./dist/vuejs</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">springboot</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">starter</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">$POM_VERSION.jar root@61.37.50.64</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">/opt/public</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6-git-태그-생성\">(6) Git 태그 생성<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#6-git-%ED%83%9C%EA%B7%B8-%EC%83%9D%EC%84%B1\" class=\"hash-link\" aria-label=\"(6) Git 태그 생성에 대한 직접 링크\" title=\"(6) Git 태그 생성에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>필자는 배포 서버에 최종 아웃풋 파일이 전송되면 프로젝트의 pom.xml에 명시된 버전을 Git 태그 이름으로 샘플 프로젝트에 생성하고 싶었다. 공통 설정에서 variables에 정의한 $CI_REPOSITORY_URL 변수를 풀어쓰면 다음과 같다.</p>\n<blockquote>\n<p><a href=\"https://%EC%95%84%EC%9D%B4%EB%94%94:%ED%8C%A8%EC%8A%A4%EC%9B%8C%EB%93%9C@gitlab.com/alvin.h/vuejs-springboot-starter.git\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://아이디:패스워드@gitlab.com/alvin.h/vuejs-springboot-starter.git</a></p>\n</blockquote>\n<p>샘플 프로젝트에서 필자의 아이디는 alvin.h이며, 패스워드는 우측 상단의 ‘프로필 메뉴 &gt; Settings &gt; Access Tokens &gt; Personal Access Tokens 설정'에서 발급한 토큰을 ‘GitLab 프로젝트 &gt; Settings &gt; CI / CD &gt; Variables 설정’에 $ACCESS_TOKEN 변수 값으로 추가한 것이다.</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token key atrule\" style=\"color:#00a4db\">Patch</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> maven</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">3.3.9</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">only</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token key atrule\" style=\"color:#00a4db\">changes</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"pom.xml\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token key atrule\" style=\"color:#00a4db\">refs</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> merge_requests</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">stage</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> patch</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">before_script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> POM_VERSION=$(mvn </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">q </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">Dexec.executable=echo </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">Dexec.args='$</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">project.version</span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\">' </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">non</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">recursive exec</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\">exec)</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> echo $POM_VERSION</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git config </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">global user.name \"alvin.h\"</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git config </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">global user.email \"seogi777@gmail.com\"</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token key atrule\" style=\"color:#00a4db\">script</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git checkout $CI_COMMIT_REF_NAME</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git remote remove origin</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git remote add origin $CI_REPOSITORY_URL</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git tag </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">a $POM_VERSION </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">m \"Version created by gitlab</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">ci Build\"</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\"> git push origin </span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token punctuation\" style=\"color:#393A34\">-</span><span class=\"token plain\">tags</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"파이프라인-동작-화면\">파이프라인 동작 화면<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-%EB%8F%99%EC%9E%91-%ED%99%94%EB%A9%B4\" class=\"hash-link\" aria-label=\"파이프라인 동작 화면에 대한 직접 링크\" title=\"파이프라인 동작 화면에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>스테이지 진행 상태와 현재 실행 중인 잡(Job)의 콘솔 화면을 볼 수 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/3-c4992681ce11b06ee0ab05a408570f51.webp\" width=\"1400\" height=\"763\" class=\"img_ev3q\"></p>\n<p>아래는 배포 서버에 전송된 최종 아웃풋 파일 목록이다. 그리고 파이프라인 동작 실패시 필자가 사용하고 있는 슬랙 채널에 메시지가 전송되게 설정했다. 참고로 ‘GitLab 프로젝트 &gt; Settings &gt; Integrations 설정'에서는 슬랙 뿐만이 아니라 다른 서비스와도 연동할 수 있는 기능을 제공한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/4-92c7419d26a322054a41bfcefe7b3a00.webp\" width=\"1400\" height=\"857\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며…<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며…에 대한 직접 링크\" title=\"글을 마치며…에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>처음에는 프론트엔드 개발환경을 최신화하기 위해 알아본 내용들을 정리하기 위해 글을 썼다. 그러다보니 실제 업무에 적용해보고 싶어서 레거시 시스템에 적용하는 방법에 대해 연구하기 시작했다. 운이 좋게도 작년 연말에 기회가 생겨서 일을 진행하였고, 현재는 어느 정도 마무리가 된 상태이다.</p>\n<p>게다가 형상 관리 시스템을 SVN에서 Git으로 변경하면서 사내에 GitLab 서버를 구축해서 사용하기 시작했다. 사실 프론트엔드 개발환경을 최신화하면서 번들 파일을 버전 관리하기가 애매했었는데, GitLab CI 기능을 통해 해결되면서 필자가 그동안 진행했던 모든 일들이 하나의 연결고리로 이어졌다.</p>\n<p>사실 처음부터 GitLab CI에 관심을 가졌던 것은 아니었다. 최근에 참여하고 있는 스터디에서 교재로 사용하고 있는 테스트 주도 개발로 배우는 객체 지향 설계와 실천이라는 책에 이런 구절이 나온다.</p>\n<blockquote>\n<p>우선 동작하는 골격을 대상으로 테스트하라</p>\n</blockquote>\n<blockquote>\n<p>‘동작하는 골격'이란 전 구간을 대상으로 자동 빌드, 배포, 테스트를 할 수 있는 실제 기능을 가장 얇게 구현한 조각을 말한다. 여기엔 첫 기능을 구현할 수 있을 정도의 자동화, 주요 컴포넌트, 통신 매커니즘이 포함될 것이다. 골격에 포함된 애플리케이션 기능을 단순하게 유지하면 골격은 신경 쓰지 않고도 기반 구조에만 마음껏 집중할 수 있다.</p>\n</blockquote>\n<p>필자가 공개한 샘플 프로젝트는 책에서 말한 ‘동작하는 골격'과 동일하다고 보면 된다. 다만 요즘 시대에 맞게 트렌디함을 더했을 뿐이다. 이 글을 읽는 사람들에게 단순한 레퍼런스로써 도움이 되길 바랄 뿐이다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"참고-링크\">참고 링크<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%EC%B0%B8%EA%B3%A0-%EB%A7%81%ED%81%AC\" class=\"hash-link\" aria-label=\"참고 링크에 대한 직접 링크\" title=\"참고 링크에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>아래 링크들은 본문에서 자세히 다루지 않는 특정 기술들에 대한 개발가이드와 샘플 프로젝트의 산출물이다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-링크\">프로젝트 링크<a href=\"https://alvin.ing/blog/vuejs-springboot-starter#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%81%ED%81%AC\" class=\"hash-link\" aria-label=\"프로젝트 링크에 대한 직접 링크\" title=\"프로젝트 링크에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p><a href=\"https://gitlab.com/alvin.h/vuejs-springboot-starter\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://gitlab.com/alvin.h/vuejs-springboot-starter</a></p>",
            "url": "https://alvin.ing/blog/vuejs-springboot-starter",
            "title": "Vue.js+SpringBoot 개발환경에서 테스트/빌드/배포 자동화하기",
            "summary": "최근에 SVN에서 Git으로 형상 관리 시스템을 변경하면서 GitLab을 접하게 되었는데, 필자는 GitLab의 명성(?)만 들어봤지 직접 사용해본 것은 이번이 처음이었다. GitHub에서 오픈소스 프로젝트를 수년간 진행하고 있어서 GitLab이랑 얼마나 차이가 있겠어라는 생각을 했던 것이 사실이다. 하지만 GitLab CI 기능을 접하게 되면서 새로운 세계에 눈을 뜨게 되었다.",
            "date_modified": "2019-01-09T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Vue.js",
                "Webpack",
                "Spring Boot"
            ]
        },
        {
            "id": "https://alvin.ing/blog/applied-webpack-to-legacy",
            "content_html": "<p>필자의 올해 목표 중 하나는 오랜기간 조금씩 진행해왔던 제니퍼 뷰서버 플랫폼화를 마무리하는 것이었다. 기획했던 플랫폼 요소는 여러가지가 있지만 그 중에서도 제니퍼 화면을 독립적인 개발환경에서 구현할 수 있게 하는 기능이 제일 중요했다. 그래서 생각해낸 것이 서버 환경은 스프링부트로 심플하게 구성하고, 모던한 프론트엔드 개발을 위해 모듈 번들러로 웹팩을 선택했다. 관련해서는 필자가 쓴 <a class=\"\" href=\"https://alvin.ing/blog/webpack-springboot-starter\">“Webpack+SpringBoot 기반의 프론트엔드 개발 환경 구축하기”</a>를 참고하자.</p>\n<p>새로 갖춰진 개발환경에서 기존의 제니퍼 뷰서버 플러그인 중 일부를 테스트 삼아 마이그레이션 해보니까 나름 신선하더라. 기존의 JSP 템플릿에 마크업과 공존하고 있던 자바스크립트 코드는 ES6 스펙에 맞춰서 수정하고, 모듈 별로 분리를 하고나니 필자가 사용하고 있는 IntelliJ IDEA의 정적 코드 분석이나 메소드 힌트 같은 기능들을 제대로 활용할 수 있게 되었다. 요즘 같은 세상에서는 너무 당연한 것이지만 수년간 쌓아온 레거시란 벽은 이미 넘을 수 없을만큼 높아진 상태였다.</p>\n<p>필자는 지난 8월에 <a class=\"\" href=\"https://alvin.ing/blog/applying-webpack-to-legacy\">“레거시(Legacy) 시스템에 웹팩 개발환경 적용하기”</a>를 쓰면서 언젠가는 실무에 꼭 적용해보겠다는 다짐을 했었다. 그리고 얼마지나지 않아 여유 일정이 생겼고, 더 이상 미룰 수 없는 일이기에 바로 시작했다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-마이그레이션-대상-선택하기\">(1) 마이그레이션 대상 선택하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#1-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EB%8C%80%EC%83%81-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(1) 마이그레이션 대상 선택하기에 대한 직접 링크\" title=\"(1) 마이그레이션 대상 선택하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>제니퍼 화면은 크게 메인 대시보드와 사용자정의 대시보드, 리얼타임, 분석, 통계, 관리, 보고서 템플릿, 사용자 메뉴로 나눌 수 있다. 참고로 사용자정의 대시보드와 보고서 템플릿은 화면 단위가 아니라 컴포넌트 단위의 기능으로 복잡하게 얽혀있어서 마이그레이션 대상에서 제외했다. 다음은 제니퍼에서 제공하는 타입 별 화면 개수이다.</p>\n<blockquote>\n<p>메인 대시보드 6종, 리얼타임 8종, 분석 21종, 통계 6종, 관리 44종</p>\n</blockquote>\n<p>제니퍼는 한달에 최소 두번 이상의 마이너 버전이 릴리즈 되는 온-프레미스(On-premise) 제품이다보니 문제가 되는 버전이 고객사에 설치되면 되돌리기가 쉽지 않다. 서비스형 제품처럼 피드백이 즉각적으로 나타나진 않지만 수없이 많은 과거 버전들 속에서 다양한 문제에 직면하게 된다. 필자는 지난 수년간 수많은 고객사에 설치되어 어느 정도 안정성이 확보된 85종의 화면들을 마이그레이션 해야한다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-목표-설정하기\">(2) 목표 설정하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#2-%EB%AA%A9%ED%91%9C-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(2) 목표 설정하기에 대한 직접 링크\" title=\"(2) 목표 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>모든 일의 시작은 목표를 잘 정하는 것이다. 너무 당연한 말이지만 일의 규모가 크거나 앞에서 말한 것처럼 이미 검증된 일을 뒤엎고 새로운 것을 적용하는 일은 진행하는 사람이나 직책자 또는 구성원들에게 큰 부담을 안겨준다. 그래서 필자는 다음과 같은 목표를 정하고, 일의 당위성을 확보하기 위한 논리를 정리했다.</p>\n<ol>\n<li class=\"\">유닛 테스트와 스냅샷 테스트가 가능해야 함</li>\n<li class=\"\">툴에서 디버깅이 가능한 코드를 개발할 수 있어야 함</li>\n<li class=\"\">화면 단위로 프레임워크나 라이브러리를 자유롭게 사용할 수 있어야 함</li>\n<li class=\"\">마이그레이션 된 화면과 기존의 화면이 모두 잘 동작해야 함</li>\n</ol>\n<p>4번에 대해 조금 더 설명을 하자면 한번에 모든 화면을 마이그레이션 할 수 있다면 정말 좋겠지만 현실적으로 불가능한 일이기 때문에 새로 갖춰진 개발환경에서는 기존의 화면과 마이그레이션 된 화면이 모두 잘 동작해야 한다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-기술-스펙-정하기\">(3) 기술 스펙 정하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#3-%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%8E%99-%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(3) 기술 스펙 정하기에 대한 직접 링크\" title=\"(3) 기술 스펙 정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>목표 설정이 끝났으니 이제는 새로 갖춰질 개발환경의 기술 스펙을 정해야 한다. 본문에서는 각각의 기술 스펙에 대한 설명은 생략하겠으며, 서론에서도 언급한 필자가 작성한 글을 참고하면 도움이 될 것이다.</p>\n<ol>\n<li class=\"\">모듈 번들러 : webpack 4</li>\n<li class=\"\">개발환경 서버 : webpack-dev-server</li>\n<li class=\"\">JavaScript 컴파일러 : babel 6</li>\n<li class=\"\">JavaScript 프레임워크 : vuejs 2</li>\n<li class=\"\">CSS 컴파일러 : sass</li>\n<li class=\"\">테스트 도구 : jest</li>\n<li class=\"\">기타 : eslint, prettier</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-레이어-기반의-화면-정리하기\">(4) 레이어 기반의 화면 정리하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#4-%EB%A0%88%EC%9D%B4%EC%96%B4-%EA%B8%B0%EB%B0%98%EC%9D%98-%ED%99%94%EB%A9%B4-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(4) 레이어 기반의 화면 정리하기에 대한 직접 링크\" title=\"(4) 레이어 기반의 화면 정리하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>목표와 기술 스펙이 정해졌으니 현재 시점에서 바로 본론으로 넘어가야 하는데, 뜬금없이 레이어 기반의 화면에 대한 설명을 보게 되서 당혹스럽겠지만 제니퍼는 언제 어디서든 관리 화면을 띄울 수 있도록 레이어 기반으로 구현되었다.</p>\n<p>즉, 마이그레이션 대상 화면의 절반이 레이어 기반인 것이다. 필자의 계획은 화면 단위(URL 별)로 엔트리를 설정하고, 공통 모듈을 제외한 아웃풋 파일들을 화면 별 디렉토리 안에 생성해두려고 했었다. 하지만 관리 화면들이 레이어 기반이기 때문에 시작부터 큰 난관에 부딪치게 되었다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/1-c4185a3f03f3b1e3bb21f8e016c73063.webp\" width=\"1400\" height=\"763\" class=\"img_ev3q\"></p>\n<p>고민 끝에 필자는 모든 관리 화면을 iFrame 기반으로 변경하기로 했다. 물론 리소스 중복 로드에 따른 로딩 속도 문제나 컨텐츠에 따라 iFrame 크기를 유동적으로 변경해야 하는 등의 몇가지 문제점이 있었지만 어렵지 않게 해결할 수 있었다. 간단하게 정리하자면 다음과 같다.</p>\n<ol>\n<li class=\"\">관리 화면 특성상 다른 종류의 화면에 비해 공통 모듈이나 라이브러리를 적게 사용하기 때문에 마이그레이션이 완료되면 로딩 속도 문제가 어느 정도 개선될 것이다.</li>\n<li class=\"\"><a href=\"https://github.com/davidjbradshaw/iframe-resizer\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">“iFrame Resizer”</a>라는 완성도가 높은 라이브러리를 사용했기 때문에 컨텐츠에 따른 iFrame 크기 조절을 자연스럽게 처리 할 수 있었다.</li>\n</ol>\n<p>참고로 페이지 기반으로 화면이 변경되면서 고정 크기의 윈도우 컴포넌트에서 벗어나 별도의 팝업이나 URL로 접근할 수 있게 되어 사용성이 많이 개선되었다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-레이아웃-구조-살펴보기\">(5) 레이아웃 구조 살펴보기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#5-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EA%B5%AC%EC%A1%B0-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0\" class=\"hash-link\" aria-label=\"(5) 레이아웃 구조 살펴보기에 대한 직접 링크\" title=\"(5) 레이아웃 구조 살펴보기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>제니퍼 화면은 JSTL 커스텀 태그로 공통 레이아웃을 화면 별로 구성하는데, 화면 타입 별로 조금씩 다르게 처리되어 있다. 문제는 마크업 뿐만이 아니라 템플릿, 자바스크립트, 스타일까지 함께 포함되어 있기 때문에 우선 자바스크립트를 분리하면서 ES6 모듈로 마이그레이션을 진행해야 한다.</p>\n<p>일단 기존의 화면 타입 별 레이아웃에 대한 설명을 하자면 다음과 같다.</p>\n<ol>\n<li class=\"\">화면_타입_header.jsp : default_css.jsp와 default_js.jsp를 로드함</li>\n<li class=\"\">화면_타입_body_start.jsp : toolbar.jsp를 로드함</li>\n<li class=\"\">화면_타입_body.end.jsp : 화면 타입 별로 공통으로 사용되는 마크업과 스크립트가 들어가고, footer.jsp를 로드함</li>\n<li class=\"\">common_ui.jsp : 제니퍼에서 사용되는 모든 컴포넌트들에 대한 템플릿과 스크립트가 포함되어 있음</li>\n</ol>\n<p>다음은 화면 타입 별 레이아웃 내부에서 로드하는 공통 레이아웃에 대한 설명이다.</p>\n<ol>\n<li class=\"\">default_css.jsp : 제니퍼 화면 구성에 필요한 css 파일과 JUI 라이브러리의 css 파일들을 로드함</li>\n<li class=\"\">default_js.jsp : 제니퍼 캔버스 차트와 유틸리티 js 파일과 jQuery나 JUI 같은 라이브러리의 js 파일들을 로드함</li>\n<li class=\"\">toolbar.jsp : 제니퍼 화면 상단에 보이는 툴바 영역에 대한 마크업과 스크립트가 포함되어 있음</li>\n</ol>\n<p>예를 들어 EVENT 분석 화면은 /analysis/event으로 접근할 수 있는데, 해당 JSP 템플릿 파일은 /WEB-INF/jsp/analysis/event.jsp에 위치한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/2-b1203c0b15473c7923d9457933fb75fd.webp\" width=\"564\" height=\"586\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6-레이아웃-구조-분리하기\">(6) 레이아웃 구조 분리하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#6-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83-%EA%B5%AC%EC%A1%B0-%EB%B6%84%EB%A6%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(6) 레이아웃 구조 분리하기에 대한 직접 링크\" title=\"(6) 레이아웃 구조 분리하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>일단 default_css.jsp는 화면 별 스타일과 ES6로 마이그레이션 된 컴포넌트 스타일만 분리했기 때문에 생각보다 간단하게 끝났다. 하지만 문제는 default_js.jsp와 toolbar.jsp, analysis_body_end.jsp, common_ui.jsp였다.</p>\n<p>기존의 화면들은 잘 동작해야하므로 그대로 두고, 마이그레이션 대상 화면에 대해서만 레이아웃을 다르게 구성하기로 했다. 필자는 모듈 번들러로 웹팩을 선택했기 때문에 development 모드와 production 모드에 따라 output.path를 다르게 생성했다.</p>\n<ol>\n<li class=\"\">development 모드 : $프로젝트_디렉토리/.webpack/bundles</li>\n<li class=\"\">production 모드 : $프로젝트_디렉토리/src/main/webapp/bundles</li>\n</ol>\n<p>JSP 템플릿에서는 pageConext 내장 객체를 사용할 수 있는데, 요청 헤더 정보 중에 request.getServletPath() 메소드를 사용하여, 화면 타입과 화면 이름을 분류했다. 제니퍼 뷰서버는 다음과 같이 단순한 URL 구조를 가진다.</p>\n<blockquote>\n<p>URL : <a href=\"http://127.0.0.1:8080/analysis/event\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8080/analysis/event</a><br>\n(화면 타입은 analysis, 화면 이름은 event)</p>\n</blockquote>\n<p>만약에 development 모드이고, EVENT 분석 화면이라면 $프로젝트_디렉토리/.webpack/bundles/analysis/event에 디렉토리가 생성된다. 사용자가 특정 화면에 접근했을 때, 앞에서 말한 pageContext 내장 객체를 사용하여 화면 타입과 화면 이름을 분류하고, output.path에 해당 디렉토리가 존재하는지 확인한다. 만약에 디렉토리가 존재한다면 마이그레이션 대상 화면이라고 간주하고, 다음과 같은 레이아웃 구조로 변경한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/3-9a2de2327e991003c284f6dd94ca3f5f.webp\" width=\"564\" height=\"586\" class=\"img_ev3q\"></p>\n<p>기존에는 모든 화면에서 default_js.jsp에 정의된 js 파일들을 로드했었다. jquery나 moment, lodash 같은 유명한 라이브러리도 포함되어 있고, 제니퍼 캔버스 차트나 유틸리티, JUI 등 내부에서 사용되는 모듈들도 포함된다. 필자는 마이그레이션 대상 화면에서 의존성이 너무 높은 jquery를 제외하고, 번들 파일들만 로드할 수 있도록 제니퍼 뷰서버를 대대적으로 수정하였다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"7-웹팩-기본-설정하기\">(7) 웹팩 기본 설정하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#7-%EC%9B%B9%ED%8C%A9-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(7) 웹팩 기본 설정하기에 대한 직접 링크\" title=\"(7) 웹팩 기본 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>본문에서는 웹팩 설정 방법에 대해서 자세히 다루지는 않고, 중요하다고 생각하는 부분만 짚고 넘어가려고 한다. 먼저 모드에 따라 output.path를 다르게 설정해주고, 마이그레이션 대상 화면은 계속 늘어날 것이기 때문에 entry를 멀티로 설정해야 한다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> path </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'path'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'production'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                                  </span><span class=\"token string-property property\" style=\"color:#36acaa\">'src/main/webapp'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'.webpack'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> publicPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/bundles'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">mode</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> env</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">entry</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token string-property property\" style=\"color:#36acaa\">'analysis/event/app'</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">${</span><span class=\"token template-string interpolation\">clientPath</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">}</span><span class=\"token template-string string\" style=\"color:#e3116c\">/analysis/event/index.js</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token string-property property\" style=\"color:#36acaa\">'realtime/event/app'</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">${</span><span class=\"token template-string interpolation\">clientPath</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:#393A34\">}</span><span class=\"token template-string string\" style=\"color:#e3116c\">/realtime/event/index.js</span><span class=\"token template-string template-punctuation string\" style=\"color:#e3116c\">`</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">output</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> publicPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">publicPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> publicPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>먼저 clientPath에는 JSP 템플릿 파일에서 분리한 자바스크립트 코드를 ES6 모듈로 마이그레이션 한 index.js 파일들이 위치한다. 화면 별 index.js 파일들은 entry가 되는데, 여기서 entry 키에 주목하자.</p>\n<p>output.filename이 [name].js로 설정되어 있는데, [name]은 entry 키로 치환되어 output.path 디렉토리에 생성된다. 만약에 analysis/event/index.js 파일을 production 모드에서 빌드를 하면 번들링 된 파일 경로는 다음과 같다.</p>\n<blockquote>\n<p>$프로젝트_디렉토리/src/main/webapp/bundles/analysis/event/app.js</p>\n</blockquote>\n<p>참고로 output.publicPath를 /bundles로 설정했기 때문에 웹에서는 다음과 같이 접근할 수 있다.</p>\n<blockquote>\n<p><a href=\"http://127.0.0.1:8080/bundles/analysis/event/app.js\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8080/bundles/analysis/event/app.js</a></p>\n</blockquote>\n<p>이제 entry 모듈에서 화면 별로 필요한 라이브러리만 import해서 사용할 수 있게 되었다. 물론 jquery는 여전히 webpack_default_js.jsp에서 로드되고 있기 때문에 다음 설정을 통해서 번들 파일에 포함되지 않게 해야한다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">externals</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">jquery</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jQuery'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"8-웹팩-개발서버-설정하기\">(8) 웹팩 개발서버 설정하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#8-%EC%9B%B9%ED%8C%A9-%EA%B0%9C%EB%B0%9C%EC%84%9C%EB%B2%84-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(8) 웹팩 개발서버 설정하기에 대한 직접 링크\" title=\"(8) 웹팩 개발서버 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>필자는 development 모드일 때, webpack-dev-server를 사용하기로 결정했는데, 이유는 HMR(Hot Module Replacement)를 적용해보고 싶었기 때문이다. 하지만 몇가지 문제로 인해 현재는 Live-Reload만 적용한 상태이다.</p>\n<p>webpack-dev-server는 번들 파일을 메모리 상에서 제공하기 때문에 output.path로 설정한 .webpack 디렉토리가 필요없다. 하지만 특정 화면으로 접근했을 때, 제니퍼 뷰서버가 마이그레이션 대상 화면인지 판단하기 위해서는 실제 파일이 필요했고, JSP 템플릿에서 로드해야 하는 파일들은 화면 별로 조금씩 다르기 때문에 구분이 필요했다. 그래서 마음에 들진 않지만 webpack 명령어를 함께 사용했다.</p>\n<blockquote>\n<p>webpack --watch --env=development &amp; webpack-dev-server --env=development</p>\n</blockquote>\n<p>실은 webpack-dev-server가 컴파일 할 때, 번들 파일 경로를 얻어오는 방법을 열심히 알아봤으나 아직까지도 답을 찾지 못했다. 하지만 Express는 webpack-dev-server를 미들웨어로 추가하면, 번들 파일 경로를 가지고 올 수 있어서 참 아쉬웠다. (제니퍼 뷰서버는 자바 스프링을 사용함 ㅜㅜ)</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">devServer</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">host</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'127.0.0.1'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">port</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">8081</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">progress</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">inline</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">hot</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">false</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">proxy</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">context</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'**'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'!/ws/**'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">target</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'http://127.0.0.1:8080'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">context</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/ws/**'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">target</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'ws://127.0.0.1:8080'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">ws</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>webpack-dev-server 포트로 제니퍼 화면에 접근했을 때, 웹소켓으로 데이터를 가져오는 대시보드가 제대로 동작하지 않았다. 그래서 조금 헤맸었는데, http와 ws 프록시 컨텍스트만 겹치지 않게 설정하면 해결되는 문제였다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"9-공통-모듈-청크하기\">(9) 공통 모듈 청크하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#9-%EA%B3%B5%ED%86%B5-%EB%AA%A8%EB%93%88-%EC%B2%AD%ED%81%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(9) 공통 모듈 청크하기에 대한 직접 링크\" title=\"(9) 공통 모듈 청크하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>앞에서 entry를 멀티로 설정하여 화면 별로 번들 파일을 생성하는 방법에 대해 알아봤다. 하지만 네비게이션 바나 사용자 메뉴, 알림 등 모든 화면에서 공통으로 사용되는 기능이나 유틸리티 모듈들은 어떻게 번들링 될까? 웹팩 기반으로 개발하는 사람은 누구나 알고 있는 splitChunks 옵션을 사용하면 되는데, 일단 다음 설정을 보자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">optimization</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token literal-property property\" style=\"color:#36acaa\">splitChunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token literal-property property\" style=\"color:#36acaa\">cacheGroups</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">              </span><span class=\"token literal-property property\" style=\"color:#36acaa\">common</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/common'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">chunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'all'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'base/common'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">              </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">              </span><span class=\"token literal-property property\" style=\"color:#36acaa\">modules</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/modules'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">chunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'all'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'base/modules'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">              </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">          </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">      </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>여기서 중요한 부분은 cacheGroups 모듈의 name 설정 부분인데, 앞에서 설명한 output.filename의 [name]과 치환되어 output.path 디렉토리에 번들 파일이 생성되는 것이다. production 모드일 때, 번들링 된 파일 경로는 다음과 같다.</p>\n<blockquote>\n<p>$프로젝트_디렉토리/src/main/webapp/bundles/base/common.js<br>\n$프로젝트_디렉토리/src/main/webapp/bundles/base/modules.js</p>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"10-이미지-파일-관리하기\">(10) 이미지 파일 관리하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#10-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(10) 이미지 파일 관리하기에 대한 직접 링크\" title=\"(10) 이미지 파일 관리하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>보통은 스프라이트 이미지를 사용하는데, 부득이하게 특정 스타일에 단일 이미지를 사용해야 하는 경우가 종종 발생한다. 그래서 필자는 웹팩으로 번들링 할 때, development 모드에서는 url-loader를 사용하고, production 모드에서는 file-loader를 사용했다.</p>\n<p>이미지가 base64로 인코딩되서 CSS 파일에 포함되기 때문에 개발할 때는 매우 편리하지만 용량이 많이 커지는 문제가 있다. 그래서 개발이 완료되면 file-loader를 사용하기로 했다. 다만 여기서 주의할 점은 이미지 파일들은 화면 별 디렉토리에 포함되어 있지만 배포 할때는 다른 화면의 이미지 파일과 함께 동일한 디렉토리에 복사된다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token literal-property property\" style=\"color:#36acaa\">module</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">rules</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">concat</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> env </span><span class=\"token operator\" style=\"color:#393A34\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'production'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">jpe</span><span class=\"token regex regex-source language-regex quantifier number\" style=\"color:#36acaa\">?</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">g</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">png</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">gif</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">svg</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'file-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[hash].[ext]'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">outputPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/images'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">publicPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/bundles/images'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">jpe</span><span class=\"token regex regex-source language-regex quantifier number\" style=\"color:#36acaa\">?</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">g</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">png</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">gif</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">svg</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'url-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">limit</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1024</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1024</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>이미지가 복사되는 디렉토리는 앞에서 설명한 output.path에 options.outputPath가 더해진 경로이므로 다소 헷갈릴 수도 있기 때문에 주의해서 설정해야 한다.</p>\n<blockquote>\n<p>$프로젝트_디렉토리/src/main/webapp/bundles/images</p>\n</blockquote>\n<p>모든 화면의 이미지 파일이 동일한 디렉토리에 복사되기 때문에 파일명이 겹치지 않도록 options.name을 [name] 대신 [hash]로 변경하였다. 그리고 options.publicPath를 /bundles/images로 설정했기 때문에 웹에서는 다음과 같이 접근할 수 있다.</p>\n<blockquote>\n<p><a href=\"http://127.0.0.1:8080/bundles/images/%5Bhash%5D.jpg\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8080/bundles/images/[hash].jpg</a></p>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"11-javascript-프레임워크-선택하기\">(11) JavaScript 프레임워크 선택하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#11-javascript-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(11) JavaScript 프레임워크 선택하기에 대한 직접 링크\" title=\"(11) JavaScript 프레임워크 선택하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>Vue.js를 선택한 이유는 여러가지가 있는데, 일단 필자는 템플릿 방식을 선호한다. 2.x 버전부터 render 함수를 지원하지만 이건 개인 취향이니 그냥 넘어가고, 가장 큰 이유는 기존의 레거시 화면과 공존해야 하는 특수한 경우라서 경량 프레임워크를 선택하는 것이 옳은 판단이라고 생각했다.</p>\n<p>JSP 템플릿에 포함된 자바스크립트 코드는 ES6 모듈로 마이그레이션 했지만 여전히 마크업 코드는 남아있었다. 하지만 싱글 파일 컴포넌트에 거의 수정하지 않고 옮길 수 있었기 때문에 마이그레이션 속도가 많이 향상되었다. 참고로 제니퍼 화면은 서버에서 넘겨주는 필수 데이터들이 많아서 JSP 같은 서버 템플릿을 완전히 제거할 수는 없었다. 그래서 최소한의 마크업만 남겨두고, 최대한 뷰 컴포넌트 단위로 화면을 분리해서 개발했다.</p>\n<p>어차피 테스트가 가능한 코드를 만드는 것이 최종 목표이기 때문에 뷰 컴포넌트 단위로 테스트를 진행하기로 결정했다. 그리고 필자는 Vue.js 하위 프로젝트인 “vue-test-utils”를 아주 잘 사용하고 있다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"12-뷰-컴포넌트로-마이그레이션-하기\">(12) 뷰 컴포넌트로 마이그레이션 하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#12-%EB%B7%B0-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(12) 뷰 컴포넌트로 마이그레이션 하기에 대한 직접 링크\" title=\"(12) 뷰 컴포넌트로 마이그레이션 하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>제니퍼 화면에서는 자체 개발한 수많은 컴포넌트들을 사용한다. 크게 대시보드와 리얼타임 화면에서 사용되는 캔버스 차트가 있고, 분석이나 통계, 보고서 템플릿 화면에서 사용되는 SVG 차트가 있다. 그리고 모든 화면에서 그리드, 달력, 콤보박스 등등 수많은 컴포넌트들을 두루 사용하고 있다. JUI 라이브러리는 그 중에서 일부를 공개한 것이다.</p>\n<p>막상 Vue.js로 화면 개발을 하다보니 ES6 모듈로 마이그레이션 된 기존의 컴포넌트들을 사용하기가 어려웠다. 아무래도 제니퍼 화면은 컴포넌트 비중이 높기 때문에 Vue.js가 제공하는 기능들을 제대로 활용하지 못했다. 그래서 먼저 JUI 라이브러리를 뷰 컴포넌트로 마이그레이션 하기로 결정했다. 불행(?) 중 다행으로 차트는 몇달 전부터 시작해서 어느 정도 마무리가 된 상태였다.</p>\n<p>JUI 라이브러리가 가지는 기존의 색은 모두 버리고, 최대한 Vue.js 특성에 맞게 마이그레이션 하려고 신경썼다. 쉽지 않은 일이었지만 결국 차트(23종), 그리드(2종), UI(13종)의 뷰 컴포넌트를 제공하게 되었고, GitHub에 프로젝트를 공개했다. 현재는 제니퍼 화면에 의존성이 높은 전용 컴포넌트들을 마이그레이션 하고 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/4-5d17de0056ea9ba1e9a7d7d143bf2664.webp\" width=\"1400\" height=\"766\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"13-jest-설정시-주의사항\">(13) Jest 설정시 주의사항<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#13-jest-%EC%84%A4%EC%A0%95%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD\" class=\"hash-link\" aria-label=\"(13) Jest 설정시 주의사항에 대한 직접 링크\" title=\"(13) Jest 설정시 주의사항에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>테스트 프레임워크는 요즘 많이 사용하고 있는 Jest를 선택했는데, 기본 설정을 하는 과정에서 몇일동안 삽질한 부분만 짧막하게 짚고 넘어가려고 한다. 만약에 테스트 대상 모듈에서 NPM으로 설치한 모듈을 사용하고 있다면 SyntaxError: Unexpected identifier 에러가 발생한다.</p>\n<p>필자가 공식 매뉴얼만 제대로 읽었다면 쉽게 해결할 수 있는 간단한 문제였다. 그것은 바로 transformIgnorePatterns 옵션의 기본값이 [“/node_modules/”]로 설정되어 있기 때문이다. 간단하게 빈 배열로 변경하거나 각자의 프로젝트에 맞는 패턴을 설정하면 된다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"14-번들-파일-배포하기\">(14) 번들 파일 배포하기<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#14-%EB%B2%88%EB%93%A4-%ED%8C%8C%EC%9D%BC-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(14) 번들 파일 배포하기에 대한 직접 링크\" title=\"(14) 번들 파일 배포하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>일반적인 서비스라면 CDN에 번들 파일들을 업로드하는 형태의 배포 방법을 선택할 수 있지만 제니퍼 뷰서버는 정적 리소스를 WAR 파일에 묶어서 배포한다. 참고로 제니퍼는 모든 프로젝트를 메이븐으로 관리하기 때문에 빌드시 NPM 명령어를 실행할 수 있는 frontend-maven-plugin을 사용하기로 결정했다.</p>\n<p>다음은 package.json에 명시된 모듈들을 먼저 설치하고, 웹팩을 production 모드로 빌드하게 하는 설정이다.</p>\n<div class=\"language-xml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-xml codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">plugin</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">groupId</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">com.github.eirslett</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">groupId</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">artifactId</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">frontend-maven-plugin</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">artifactId</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">version</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">1.6</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">version</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">executions</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">install node and npm</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">install-node-and-npm</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">phase</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">generate-resources</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">phase</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">npm install</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">npm</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">arguments</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">install</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">arguments</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">npm build</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">id</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">npm</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goal</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">goals</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">arguments</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">run dist</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">arguments</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">execution</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">executions</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">nodeVersion</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">v10.10.0</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">nodeVersion</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">npmVersion</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">6.4.1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">npmVersion</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">configuration</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">plugin</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며…<a href=\"https://alvin.ing/blog/applied-webpack-to-legacy#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며…에 대한 직접 링크\" title=\"글을 마치며…에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>결과는 만족스러웠지만 조금만 더 빨리 시작했으면 좋았을텐데, 후회도 아쉬움도 많이 남는 일이었다. 일을 진행하면서 문제가 생겨 몇번의 핫픽스 버전을 릴리즈 했었다. 그만큼 레거시 시스템을 엎는다는건 조심스럽고 예민한 일이다. 하지만 앞으로 몇년을 생각하면 언젠가는 해야만 하는 일이다. 늦으면 늦을수록 위험부담이 커지기 때문에 기회가 오면 바로 시작해야 한다.</p>",
            "url": "https://alvin.ing/blog/applied-webpack-to-legacy",
            "title": "레거시 시스템의 프론트엔드 개발환경 최신화 후기",
            "summary": "필자의 올해 목표 중 하나는 오랜기간 조금씩 진행해왔던 제니퍼 뷰서버 플랫폼화를 마무리하는 것이었다. 기획했던 플랫폼 요소는 여러가지가 있지만 그 중에서도 제니퍼 화면을 독립적인 개발환경에서 구현할 수 있게 하는 기능이 제일 중요했다. 그래서 생각해낸 것이 서버 환경은 스프링부트로 심플하게 구성하고, 모던한 프론트엔드 개발을 위해 모듈 번들러로 웹팩을 선택했다. 관련해서는 필자가 쓴 “Webpack+SpringBoot 기반의 프론트엔드 개발 환경 구축하기”를 참고하자.",
            "date_modified": "2018-11-25T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Webpack",
                "Legacy"
            ]
        },
        {
            "id": "https://alvin.ing/blog/applying-webpack-to-legacy",
            "content_html": "<p><a class=\"\" href=\"https://alvin.ing/blog/webpack-springboot-starter\">“Webpack+SpringBoot 기반의 프론트엔드 개발 환경 구축하기”</a> 편에서 스프링부트 프로젝트를 생성하고, 서버와 클라이언트 코드를 통합 빌드/배포할 수 있는 개발 환경을 구축해봤다. 모던한 개발 환경에서 코드를 구현한다는 것은 프로그래머에게 축복이나 다름없다. 바벨(Babel)의 등장으로 브라우저가 지원하지 않더라도 최신 자바스크립트 스펙을 적용한다는 것이 얼마나 행복한 일인지는 클라이언트 개발을 해본 사람이라면 누구나 공감할 것이다.</p>\n<p>하지만 현실은 우리의 앞을 가로막고 있는 레거시(Legacy)라는 커다란 벽이다. 개인 프로젝트가 아니라면 기존의 시스템을 새롭게 바꾼다는 것이 얼마나 어려운 일인지 다 알고 있으리라 생각된다. 그렇다면 왜 어려울까? 필자가 생각하는 가장 큰 이유는 공감을 얻기가 어렵기 때문이다. 이미 안정적으로 잘 돌아가고 있는 시스템을 괜히 건들여서 장애가 생긴다면 앞으로의 개발 일정에 차질이 생길 수 있는데, 과연 누가 이해해줄 수 있을까?</p>\n<p>앞에서 말한 문제만으로도 글 한편은 쓸 수 있을 것 같은데, 할 말은 많지만 일단 이 정도로 하겠다. 지난 글에 이어 이번에도 서론이 길었다. 그리고 지난 글과 달리 이번에는 확실한 솔루션이 아니라는 점을 참고하길 바란다. 무구한 역사와 전통이 담긴 레거시(?)는 쉽게 바꿀 수 있는 것이 아니다. 단지 필자는 조금이나마 도움이 될 수 있는 기법 몇가지를 본문에서 다룰 것이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-번들링-파일에서-모듈-제외하기\">(1) 번들링 파일에서 모듈 제외하기<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#1-%EB%B2%88%EB%93%A4%EB%A7%81-%ED%8C%8C%EC%9D%BC%EC%97%90%EC%84%9C-%EB%AA%A8%EB%93%88-%EC%A0%9C%EC%99%B8%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(1) 번들링 파일에서 모듈 제외하기에 대한 직접 링크\" title=\"(1) 번들링 파일에서 모듈 제외하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>기존의 웹 페이지에 내가 만든 새로운 기능이 번들링되서 배포되었다고 가정해보자. 해당 웹 페이지는 공통 기능 구현을 위한 라이브러리(jquery, moment)가 이미 로드되어 사용 중이었다. 하지만 내가 만든 새로운 기능에도 개발의 편의를 위해 jquery를 사용했다. 이런 상황이면 글로벌 모듈인 jquery가 로드되고, 새로운 기능의 번들링 파일에도 포함되어 있기 때문에 웹페이지는 jquery를 두번 로드하는게 된다.</p>\n<p>웹팩의 externals 옵션을 통해 개발 코드가 번들링 될 때, 특정 모듈을 제외시킬 수 있는데, 위와 같은 상황에서는 jquery를 제외하면 문제가 해결된다. 단지 번들링 되는 파일에서 제외하는 것이기 때문에 기존의 모듈 기반의 자바스크립트 코딩을 그대로 할 수 있게 된다.</p>\n<p>그럼, 먼저 이전 강좌에서 개발했던 프로젝트의 <strong>src/main/resources/templates/index.html</strong>에 CDN으로 배포된 jQuery 라이브러리를 로드하는 코드를 넣어보자.</p>\n<div class=\"language-html codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-html codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/javascript</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token script\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><br></div></code></pre></div></div>\n<p>그리고 템플릿에서 jQuery 라이브러리를 로드하기 때문에 번들링 할 필요가 없기 때문에 웹팩 설정 파일에서 entry.vendors 옵션의 jquery 값을 제거하자. 마지막으로 번들링에서 제외하기 위해 externals 옵션에 key는 모듈명, value는 글로벌 변수 이름 형태로 추가할 수 있다. 글로벌 변수 이름은 문자열 뿐만이 아니라 정규식, 콜백 함수, 객체 형태로도 설정할 수 있으니 자세한 사항은 공식 문서를참고하자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">entry</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">vendors</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">index</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/index.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">externals</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">jquery</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"jQuery\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<p>다음은 externals 옵션을 적용하고, 번들링 했을 때의 내부 구조이다. 이전 강좌에 봤던 트리맵에 jquery.js 노드가 빠진 것을 확인할 수 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/1-ddc202115f040fd3a03d0a14a62be26e.webp\" width=\"1400\" height=\"875\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-다운로드\">프로젝트 다운로드<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C\" class=\"hash-link\" aria-label=\"프로젝트 다운로드에 대한 직접 링크\" title=\"프로젝트 다운로드에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>이전 강좌에서 제공한 프로젝트에서 <strong>extenals</strong> 브랜치로 변경하여 체크아웃 받으면 된다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-레거시-코드를-모듈로-로드하기\">(2) 레거시 코드를 모듈로 로드하기<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#2-%EB%A0%88%EA%B1%B0%EC%8B%9C-%EC%BD%94%EB%93%9C%EB%A5%BC-%EB%AA%A8%EB%93%88%EB%A1%9C-%EB%A1%9C%EB%93%9C%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(2) 레거시 코드를 모듈로 로드하기에 대한 직접 링크\" title=\"(2) 레거시 코드를 모듈로 로드하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>레거시 시스템이 커지다보면 어쩔 수 없이 사용해야만 하는 자바스크립트 코드들이 존재한다. 필자의 경우, 다국어 처리를 위한 메시지를 가져오는 공통 함수를 클라이언트 개발시 사용한다.</p>\n<p>해당 자바스크립트 파일은 서버에서 특정 주기로 동기화하는 조금은 복잡한 과정을 거쳐 생성된다. 결국 레거시 코드를 모듈로 로드하여 사용해야만 하는데, externals-loader를 사용하면 이러한 문제를 해결할 수 있다.</p>\n<blockquote>\n<p>npm install — save-dev exports-loader</p>\n</blockquote>\n<p>다음 코드를 살펴보자. 오랜만에 ES5 코드를 보니 반갑기도 하다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> file </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'blah.txt'</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> helpers </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function-variable function\" style=\"color:#d73a49\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token console class-name\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'test something'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function-variable function\" style=\"color:#d73a49\">parse</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token console class-name\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'parse something'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">var</span><span class=\"token plain\"> math </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function-variable function\" style=\"color:#d73a49\">add</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">a</span><span class=\"token parameter punctuation\" style=\"color:#393A34\">,</span><span class=\"token parameter\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> a </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function-variable function\" style=\"color:#d73a49\">subtract</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">a</span><span class=\"token parameter punctuation\" style=\"color:#393A34\">,</span><span class=\"token parameter\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> a </span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token plain\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>다음 설정을 통해 lib/utils.js 파일을 모듈로 임포트해서 사용해보자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'lib'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'utils.js'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'exports-loader?file,math,parse=helpers.parse'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>콤마(,)로 구분해서 글로벌 변수 이름을 넣어주면 되고, 만약에 객체라면 특정 프로퍼티나 메소드만 설정할 수 있다. 다음은 exports-loader 설정을 통해 생성된 모듈을 임포트하여 사용하는 코드이다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">Styles</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./index.css'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports\">$</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports\">mt</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports punctuation\" style=\"color:#393A34\">{</span><span class=\"token imports\">file</span><span class=\"token imports punctuation\" style=\"color:#393A34\">,</span><span class=\"token imports\"> math</span><span class=\"token imports punctuation\" style=\"color:#393A34\">,</span><span class=\"token imports\"> parse</span><span class=\"token imports punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'../../../lib/utils.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"strong &gt; div\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">html</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token function\" style=\"color:#d73a49\">mt</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">format</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token console class-name\">console</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">log</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">file</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">parse</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">math</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">add</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">6</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-다운로드-1\">프로젝트 다운로드<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-1\" class=\"hash-link\" aria-label=\"프로젝트 다운로드에 대한 직접 링크\" title=\"프로젝트 다운로드에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>이전 강좌에서 제공한 프로젝트에서 <strong>externals-loader</strong> 브랜치로 변경하여 체크아웃 받으면 된다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-글로벌-변수로-모듈-사용하기\">(3) 글로벌 변수로 모듈 사용하기<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#3-%EA%B8%80%EB%A1%9C%EB%B2%8C-%EB%B3%80%EC%88%98%EB%A1%9C-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(3) 글로벌 변수로 모듈 사용하기에 대한 직접 링크\" title=\"(3) 글로벌 변수로 모듈 사용하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>웹팩은 모듈을 임포트(import) 하지 않아도, 글로벌 종속성을 가지는 객체(또는 변수)를 제공할 수 있는 기능을 제공한다. 웹팩에서 기본적으로 배포하는 ProvidePlugin을 사용하면 하는데, 동작 원리는 매우 심플하다. 코드 상단에 플러그인에 추가된 key 이름을 가지는 변수에 value 이름을 가지는 모듈을 require 해주기 때문에 jQuery를 임포트 하지 않아도 사용할 수 있다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> $ </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 첫번째 라인은 ProvidePlugin에서 추가함</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 실제로는 존재하지 않음</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'onload'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>다음 코드는 순수 레거시 코드를 복사하여 붙여넣기 한 것이다. 참고로 mt는 moment 라이브러리인데, 레거시 코드에서 글로벌 변수 이름 중첩으로 인해 mt로 변경해서 사용하고 있다고 가정해보자. 그리고 math는 필자가 미리 구현해둔 커스텀 모듈이다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"strong &gt; div\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">html</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token function\" style=\"color:#d73a49\">mt</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">format</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">math</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">add</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">6</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword module\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">add</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">a</span><span class=\"token parameter punctuation\" style=\"color:#393A34\">,</span><span class=\"token parameter\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> a </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">export</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">subtract</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">a</span><span class=\"token parameter punctuation\" style=\"color:#393A34\">,</span><span class=\"token parameter\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> a </span><span class=\"token operator\" style=\"color:#393A34\">-</span><span class=\"token plain\"> b</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>ProvidePlugin은 파일시스템 기반으로 동작하기 때문에 사용자가 만든 모듈의 경로만 넣어주면 얼마든지 글로벌 변수를 추가할 수 있다. 그리고 imports-loader를 사용하면 좀 더 세밀한 기능을 사용할 수 있다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token literal-property property\" style=\"color:#36acaa\">plugins</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">webpack</span><span class=\"token class-name punctuation\" style=\"color:#393A34\">.</span><span class=\"token class-name\">ProvidePlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">$</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">mt</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">math</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'lib'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'math.js'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<blockquote>\n<p>npm install — save-dev imports-loader</p>\n</blockquote>\n<p>다음은 config.size 값을 imports-loader를 통해 설정하여, 기존의 레거시 코드에서 사용하는 코드이다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"strong &gt; div\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">html</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token function\" style=\"color:#d73a49\">mt</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">format</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">math</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">add</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token number\" style=\"color:#36acaa\">6</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">4</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">', '</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> config</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">size</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>imports-loader는 다양한 표현식을 사용할 수 있는데, 자세한 사항은 공식 문서를 참고하자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/index.js'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'imports-loader?config=&gt;{size:50}'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>다음은 ProvidePlugin과 imports-loader를 사용하고, 번들링 했을 때의 내부 구조이다. 작아서 잘 보이지 않지만 필자가 구현해둔 math.js도 포함되어 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/2-250e424290360282de2ff54cdee70473.webp\" width=\"1400\" height=\"875\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-다운로드-2\">프로젝트 다운로드<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-2\" class=\"hash-link\" aria-label=\"프로젝트 다운로드에 대한 직접 링크\" title=\"프로젝트 다운로드에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>이전 강좌에서 제공한 프로젝트에서 <strong>shimming</strong> 브랜치로 변경하여 체크아웃 받으면 된다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며…<a href=\"https://alvin.ing/blog/applying-webpack-to-legacy#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며…에 대한 직접 링크\" title=\"글을 마치며…에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>그동안 프론트엔드 개발 환경은 많은 변화가 있었다. 하지만 하나의 제품을 수년간 개발하고 있는 필자는 변화의 중심에 서지 못하고, 멀찌감치 떨어져서 지켜보기만 했었다. 이제와서 고백하자면 이 글은 필자가 앞으로 해야할 일에 대한 이정표다.</p>\n<p>책 몇권 읽고, 샘플도 몇개 만들어보고, 단지 조금 안다고해서 실제 업무에 적용할 수 있는 것은 아니다. 그래서 필자는 생각을 정리하고, 누구에게나 공감을 이끌어낼 수 있는 논리를 완성하기 위해 다시 글을 썼다.</p>",
            "url": "https://alvin.ing/blog/applying-webpack-to-legacy",
            "title": "레거시(Legacy) 시스템에 웹팩 개발환경 적용하기",
            "summary": "“Webpack+SpringBoot 기반의 프론트엔드 개발 환경 구축하기” 편에서 스프링부트 프로젝트를 생성하고, 서버와 클라이언트 코드를 통합 빌드/배포할 수 있는 개발 환경을 구축해봤다. 모던한 개발 환경에서 코드를 구현한다는 것은 프로그래머에게 축복이나 다름없다. 바벨(Babel)의 등장으로 브라우저가 지원하지 않더라도 최신 자바스크립트 스펙을 적용한다는 것이 얼마나 행복한 일인지는 클라이언트 개발을 해본 사람이라면 누구나 공감할 것이다.",
            "date_modified": "2018-08-22T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Webpack",
                "Legacy"
            ]
        },
        {
            "id": "https://alvin.ing/blog/coding-the-matrix-1",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-시작하며\">글을 시작하며…<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EA%B8%80%EC%9D%84-%EC%8B%9C%EC%9E%91%ED%95%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 시작하며…에 대한 직접 링크\" title=\"글을 시작하며…에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>작년에 머신러닝에 대한 검색을 하다가 우연히 “수학을 포기한 직업 프로그래머가 기계학습을 시작하기 위한 최단경로”라는 번역 글을 보고, 처음으로 선형대수에 대해 관심을 가지고 공부를 시작했다.\n해당 글에서 프로그래머를 위한 수학책으로 “코딩 더 매트릭스”를 추천했는데, 실은 그 책 때문에 연재 글을 기획하게 되었다.\n필자는 수포자의 길을 30년 넘게 걸어온 사람으로서 “코딩 더 매트릭스”는 굉장히 이해하기가 어려운 책이었다.\n그래서 필자는 큰 흐름은 선형대수를 시각적으로 이해하는 형태로 글을 연재할 예정이며, 세부 내용은 “코딩 더 매트릭스”에서 많이 차용할 생각이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"코딩-더-매트릭스\">코딩 더 매트릭스<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EC%BD%94%EB%94%A9-%EB%8D%94-%EB%A7%A4%ED%8A%B8%EB%A6%AD%EC%8A%A4\" class=\"hash-link\" aria-label=\"코딩 더 매트릭스에 대한 직접 링크\" title=\"코딩 더 매트릭스에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>필자는 일주일에 한번 “코딩 더 매트릭스” 스터디 모임을 갖는다.\n벌써 스터디가 시작된지 1년이 넘었지만 이제 겨우 70% 정도 진행한 것 같다.\n원래 공부를 잘하는 사람이 아니지만 살면서 이렇게 난해한 책은 처음봤다.\n물론 번역서라서 원서의 의도가 제대로 전달되지 않은 것일 수도 있지만 저자가 무엇을 말하고 싶은지 어떤 의미를 말하는지 필자의 수준으로는 해석하기 어려운 부분이 너무 많았다.\n또한 “코딩 더 매트릭스” 본문에서 제공되는 각종 예제들이 제대로 동작하지 않을뿐더러 관련된 자료를 찾기가 매우 어려웠다.\n그래서 자료를 찾기 위해 열심히 검색해봤는데, 우리나라 뿐만이 아니라 외국에서도 “코딩 더 매트릭스”를 완독한 사람이 많지 않은 것으로 파악되어 1년이 넘도록 완독하지 못한 자괴감에서 조금이나마 벗어날 수 있었다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"진행-방식\">진행 방식<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EC%A7%84%ED%96%89-%EB%B0%A9%EC%8B%9D\" class=\"hash-link\" aria-label=\"진행 방식에 대한 직접 링크\" title=\"진행 방식에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>본문에서는 주제와 관련된 수학 공식이나 개념에 대해 자세히 다루지 않을 것이다.\n그래서 글을 읽기 전에 최소한 주제에 해당하는 수학적 지식은 갖추고 있어야 한다.\n필자는 수포자가 되기 전에는 왜 수학을 공부해야 하는지 몰랐었고, 개발자로 일하면서 중요성은 알았지만 수학의 필요성에 대해 제대로 이해하지 못했었다.\n그래서 필자는 본문에서 다룰 주제에 대해 어떻게 응용될 수 있는지 필요성에 대한 근본적인 질문을 해볼 것이며, 최대한 시각적으로 표현하거나 실제로 응용해볼 수 있는 방법으로 답을 찾아볼 것이다.\n그리고 본문에서 소개되는 예제에서 기하학적 요소는 자바스크립트(jui)로 구현할 것이며, 행렬이나 복소수 연산을 위해 파이썬(numpy)을 사용할 것이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"선형연립방정식\">선형연립방정식<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EC%84%A0%ED%98%95%EC%97%B0%EB%A6%BD%EB%B0%A9%EC%A0%95%EC%8B%9D\" class=\"hash-link\" aria-label=\"선형연립방정식에 대한 직접 링크\" title=\"선형연립방정식에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>2개 이상의 미지수를 포함하는 2개 이상의 방정식의 쌍이 주어지고, 미지수가 주어진 모든 방정식을 동시에 만족할 것이 요구되어 있을때, 이 방정식의 쌍을 연립방정식이라고 한다.\n아래 인용구는 이상구 교수님의 선형대수 강의에서 발췌한 내용이다. (<a href=\"https://www.youtube.com/watch?v=AAUQvdjQ-qk&amp;feature=youtu.be\" target=\"_blank\">링크</a>)</p>\n<blockquote>\n<p>역사적으로 선형대수학의 가장 중요한 주제 중 하나가 선형연립방정식과 해법이다. 21세기 우리는 수천 개의 미지수를 갖는 연립방정식을 자연과학, 공학, 경제학, 교통의 흐름, 일기예보, 의사결정 등 수많은 분야에서 만난다. 컴퓨터의 계산능력(computing power)이 향상됨에 따라 응용학문에서 선형대수학의 중요성은 날로 커져 왔다. 컴퓨터는 병렬처리와 대규모 계산을 매개로 선형대수학과 긴밀하게 연결된다. 이로 인해 현재의 과학자, 공학자들은 이전에는 상상만 하던 매우 복잡한 문제를 다를 수 있게 되었다. 또 선형대수학의 지식은 어떤 과목보다 더 넓은 과학, 경영분야의 활용도를 지닌다.</p>\n</blockquote>\n<p>예를 들어 직선의 방정식으로 그린 두 개의 직선이 있을 때, 두 직선의 교점을 선형연립방정식의 유일한 해(solution)라고 한다.\n만약에 두 직선이 평행하다면 교점이 존재하지 않으므로 해를 갖지 않는게 되며, 두 직선이 겹친다면 무수히 많은 해를 가지게 된다.\n즉, 선형연립방정식의 해집합은 앞에서 말한 세가지 가능성 중에 하나만 성립한다. 그럼, 먼저 간단하게 두 직선의 방정식의 해를 구해보도록 하자.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"144\" height=\"59\" class=\"img_ev3q\"></p>\n<p>아래 예제에서 빨간색 직선은 방정식 (1)이며, 파란색 직선은 방정식 (2)를 그린 것이다.\n두 직선이 교차하는 부분에 마우스를 올리면 나타나는 좌표가 바로 교점(3,2)이다.\n해당 좌표 값을 방정식 (1), (2)에 각각 대입해보면 방정식이 성립한다는 것을 확인할 수 있다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"690\" height=\"676\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"선형연립방정식-응용\">선형연립방정식 응용<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EC%84%A0%ED%98%95%EC%97%B0%EB%A6%BD%EB%B0%A9%EC%A0%95%EC%8B%9D-%EC%9D%91%EC%9A%A9\" class=\"hash-link\" aria-label=\"선형연립방정식 응용에 대한 직접 링크\" title=\"선형연립방정식 응용에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>앞에서 직선의 방정식이 다수가 존재하고 유일한 해가 존재할 때, 교점을 구하는 방법에 대해 알아보았다.\n지금부터는 반대로 지나는 점들을 가지고 원의 방정식과 방데르몽드 다항식을 구하여 차트로 그려볼 것이다.\n원의 방정식의 일반형은 아래와 같다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"227\" height=\"30\" class=\"img_ev3q\"></p>\n<p>지나는 점의 좌표값 (-2,2), (4,-6), (5, -5)를 알고 있다면 원의 방정식의 일반형에 각각 x와 y값을 대입한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"197\" height=\"89\" class=\"img_ev3q\"></p>\n<p>다소 복잡해졌지만 연립방정식을 풀면 각각 a=-2, b=4, c=-20가 구해지는데, 이 값들을 다시 원의 방정식에 대입한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"231\" height=\"30\" class=\"img_ev3q\"></p>\n<p>완성된 원의 방정식에 x값을 차트에서 지정된 모든 좌표를 대입하여 y값을 구하는 방식으로 그렸는데, 성능에 문제가 많고 최적의 방법은 아니라서 권장하지는 않는다.\n관련해서는 각자 기호에 맞게 구현해보는 것으로 하자.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/6-cb9e77cf17cb1a27273f4bcfe5036aa9.webp\" width=\"690\" height=\"664\" class=\"img_ev3q\"></p>\n<p>이제 어느 정도는 선형연립방정식을 어떻게 활용해야 하는지에 대한 감이 올 것 같은데, 추가로 다수의 점을 지나는 곡선을 그릴 수 있는 라그랑주(lagrange) 다항식을 구하여 차트로 그려보면 좀 더 확신이 생길것 같다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"390\" height=\"31\" class=\"img_ev3q\"></p>\n<p>일단 네 점의 좌표값 (1,3), (2,-2), (3,-5), (4,0)를 라그랑주 다항식에 각각 x와 y 값을 대입한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"263\" height=\"124\" class=\"img_ev3q\"></p>\n<p>원의 방정식과 동일하게 연립방정식을 풀면 각각 a0=3, a1=3, a2=-5, a3=1이 구해는데, 이 값들을 다시 라그랑주 다항식에 대입한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"173\" height=\"30\" class=\"img_ev3q\"></p>\n<p>완성된 라그랑주 다항식에 원의 방정식과 동일한 방법으로 x값에 지정된 모든 좌표를 대입하여 y값을 구하는 방식으로 그리면 된다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"data:image/webp;base64,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\" width=\"666\" height=\"656\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"결론\">결론<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EA%B2%B0%EB%A1%A0\" class=\"hash-link\" aria-label=\"결론에 대한 직접 링크\" title=\"결론에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>웹에서 그래픽을 표현하기 위해 SVG나 캔버스에서 제공되는 API를 사용하면 매우 쉽게 선이나 도형 같은 그래픽 요소들을 그릴 수 있다.\n예를 들어 선을 그리기 위해서 두 점의 좌표만 입력하면 쉽게 그릴 수 있는데, 내부적으로는 두 점의 관계에 대한 직선의 방정식을 구하고, 최대한 자연스러운 형태로 그려질 수 있도록 별도의 알고리즘이 적용되어 있을 것이다. 이는 직선 뿐만이 아니라 원이나 타원 등의 다양한 방정식에 적용될 수 있다. 필자는 방정식의 원형을 일종의 템플릿으로 규정하고, 지나는 점들의 좌표를 템플릿에 적용되는 입력 값이라고 생각한다.\n값이 입력이 되고 생성된 템플릿의 집합을 연립방정식으로 다시 규정하고, 구해진 유일한 해(solution)를 방정식의 계수에 대입하여 최종의 방정식을 구한다.\n조금 복잡한 과정이라고 생각할 수 있지만 입력하는 부분과 해를 구하는 부분은 공통적인 사항이고, 그려지는 모양에 따라 방정식만 다르게 적용하면 되기 때문에 일종의 템플릿이라고 규정한 것이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"글을-마치며\">글을 마치며…<a href=\"https://alvin.ing/blog/coding-the-matrix-1#%EA%B8%80%EC%9D%84-%EB%A7%88%EC%B9%98%EB%A9%B0\" class=\"hash-link\" aria-label=\"글을 마치며…에 대한 직접 링크\" title=\"글을 마치며…에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>선형대수를 공부하는 것 자체만으로도 필자에게는 매우 큰 도전이었다.\n그리고 이에 대한 글을 쓴다는 것은 상상조차 할 수 없는 일이었다.\n그래서 누군가에게 내가 알고 있는 것을 공유하겠다는 차원이 아닌 필자의 생각을 정리하고, 이게 정말 옳은 생각인지 스스로에게 묻기 위한 행동이라고 말하고 싶다.\n마지막으로 이상구 교수님의 선형대수 강의에서 소개된 응용 사례를 소개하고 글을 마치겠다.</p>\n<blockquote>\n<p>한 천문학자가 어떤 소행성 궤도를 구하려고 한다. 이를 위해 그는 태양을 원점으로 갖는 좌표평면을 설정하였다. 축의 눈금 단위들은 천문학의 측정단위(천문학 단위 1은 지구에서 태양까지의 평균거리이며 약 149,637,000km)가 사용된다. 행성은 타원형 궤도를 따라 운행한다. (케플러의 제1법칙)</p>\n</blockquote>\n<p>천문학자는 다섯 번에 걸쳐 행성의 위치를 나타내는 (8.025,8.310), (10.170,6.355), (11.202,3.212), (10.736,0.375), (9.092,2.267) 관측점을 구하고, 이를 본문에서 다룬 방법으로 타원의 방정식을 구해서 그리면 행성의 궤도를 알 수 있게 된다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/11-7ffc3c83b8bb02660760a46762ad80c8.webp\" width=\"688\" height=\"668\" class=\"img_ev3q\"></p>",
            "url": "https://alvin.ing/blog/coding-the-matrix-1",
            "title": "코딩 더 매트릭스 살펴보기 (연립 방정식)",
            "summary": "글을 시작하며…",
            "date_modified": "2017-11-27T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "선형대수",
                "Coding the Matrix"
            ]
        },
        {
            "id": "https://alvin.ing/blog/webpack-springboot-starter",
            "content_html": "<p>필자가 회사에서 개발 중인 제니퍼5의 수요가 크게 늘어남에 따라 고객의 기호에 맞게 화면에 대한 커스터마이징을 요구하는 경우가 많아졌다. 하지만 기존의 프로젝트에 커스터마이징 코드를 넣는 것은 바람직하지 않기 때문에 외부에서 구현하고, 플러그인처럼 추가하고 삭제할 수 있는 구조를 고민해야만 했다.</p>\n<p>제니퍼5 뷰서버는 개발을 시작한지 7년이 넘은 꽤 오래된 코드로 구현되어 있다. 기반 프레임워크는 스프링3 버전이었는데, 플러그인 구조를 만들기 위해 큰 용기(?)를 내서 스프링4 버전으로 업그레이드 했다</p>\n<p>어떻게 구현할까 오랫동안 고민했었는데, 그냥 단순하게 스프링 컨텍스트에 같이 올리는 방법을 택했다. 회사의 서버 개발자 분의 도움을 받아 간단한 클래스 로더를 만들었고, 외부에서 개발한 플러그인 jar 파일을 제니퍼5 뷰서버가 시작할 때, 같이 올라가는 구조였다.</p>\n<p>이렇다보니 플러그인을 수정할 때마다 jar 파일을 생성하기 위해 빌드하고, 제니퍼5 뷰서버를 재시작 해야하는 번거로운 일을 반복하게 되었다. 그래서 독립적인 개발환경 구성을 위해 스프링부트(SpringBoot)와 웹팩(Webpack)을 고려하게 되었다.</p>\n<p>서론이 많이 길어져서 독립적인 개발환경 구성에 대한 내용은 이 정도로 하고, 바로 본론으로 넘어가도록 하겠다. 본문에서는 인텔리제이(IntelliJ)에서 스프링부트 프로젝트를 생성하고, 스프링부트 재시작 없이 클래스와 리소스를 동적으로 반영해주는 핫스왑(Hot-Swap)에 대해 알아볼 것이다. 또한 웹팩 기반으로 스프링부트 프로젝트와 연계하여 프론트엔드 개발환경을 직접 구성해볼 것이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-스프링부트-핫스왑-설정하기\">(1) 스프링부트 핫스왑 설정하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#1-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%ED%95%AB%EC%8A%A4%EC%99%91-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(1) 스프링부트 핫스왑 설정하기에 대한 직접 링크\" title=\"(1) 스프링부트 핫스왑 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>그럼, 먼저 스프링부트 프로젝트를 생성해보자.</p>\n<ol>\n<li class=\"\">File &gt; New &gt; Project 클릭</li>\n<li class=\"\">Spring Initialzr &gt; Project SDK 선택 (1.8) &gt; Next 클릭</li>\n<li class=\"\">Project Metadata 입력 &gt; Type 선택 (Maven Project) &gt; Next 클릭</li>\n<li class=\"\">Dependencies 입력 &gt; Spring Boot 버전 선택 (1.5.15) &gt; 라이브러리 선택</li>\n<li class=\"\">본문에서는 화면 개발과 핫스왑을 위한 최소한의 라이브러리만 선택하지만 개발 환경에 맞게 알아서 추가로 선택하면 된다.</li>\n</ol>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/1-42b9c46ce449c1eccd3c95730707e2bc.webp\" width=\"1400\" height=\"1441\" class=\"img_ev3q\"></p>\n<p>템플릿 엔진은 기호에 맞게 다른걸 사용해도 상관없다. 이제 프로젝트가 생성되었으니 앞으로 두가지 설정만 하면 핫스왑 기능을 사용할 수 있게 된다.</p>\n<blockquote>\n<p>다시 확인해보니 DevTools 라이브러리를 사용하지 않아도 된다. 핫스왑은 인텔리제이에서 제공해주는 아주 유용한 기능이다.</p>\n</blockquote>\n<p>먼저 Preferences… 메뉴로 가서 Build, Execution, Deployment 탭의 Compiler 메뉴를 선택하고, <strong>Build project automatically</strong>를 체크해주면 된다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/2-00350aabeca1fac523cb5892363969a3.webp\" width=\"1400\" height=\"912\" class=\"img_ev3q\"></p>\n<p>마지막으로 Registry 설정 화면을 열어서 <strong>compiler.automake.allow.when.app.running</strong> 옵션을 체크해주자.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/3-820ce9d8ff6552f1c09576cf4807933b.webp\" width=\"1124\" height=\"550\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/4-76761be2d1c834b79b8bfac8c5e1447d.webp\" width=\"1400\" height=\"1057\" class=\"img_ev3q\"></p>\n<p>서버 개발환경은 이렇게 간단하게 구성하였지만 클라이언트 개발환경은 프로젝트 목적에 따라 차이가 있을 수 있다.</p>\n<blockquote>\n<p>핫스왑 기능이 동작하기 위해서는 메인 클래스를 디버그 모드로 실행해야 하며, 코드를 수정하고나서 Build Project를 직접 실행해야만 반영이 빠르다.\n참고로 순수 자바 클래스만 변경되었을 때만 동작하며, 스프링 관련 설정이나 컨텍스트에 변화가 있으면 메인 클래스를 재시작해야 한다.</p>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-웹팩-설치하기\">(2) 웹팩 설치하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#2-%EC%9B%B9%ED%8C%A9-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(2) 웹팩 설치하기에 대한 직접 링크\" title=\"(2) 웹팩 설치하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>본문에서는 React나 Vue.js와 같은 프레임워크는 다루지 않으며, 클라이언트 개발을 위한 최소한의 환경만 구성할 것이다.\n아주 당연한 얘기지만 Node.js와 NPM 패키지 관리자가 설치되어 있어야 하며, 모듈 번들링이 무엇인지에 대한 사전 이해가 필요하다.</p>\n<p>그럼, 먼저 package.json 파일을 생성해보자. 인텔리제이 하단에 있는 터미널 탭을 선택하여 콘솔에 npm init을 입력한다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/5-b2610cb72aa0fb0e7679e369127e7e16.webp\" width=\"1400\" height=\"857\" class=\"img_ev3q\"></p>\n<p>명령어를 입력하고, 패키지 이름이나 버전 등을 입력할 수 있는데, 프로젝트 특성에 맞게 적당히 입력하거나 그냥 엔터키를 눌러서 기본값으로 설정할 수도 있다.</p>\n<p>웹팩은 버전마다 설정 방식이 많이 다르므로 본문에서 다루는 내용은 최신 버전인 4.16.5를 기준으로 한다.</p>\n<blockquote>\n<p>npm install — save-dev webpack webpack-cli webpack-dev-server<br><br>\n+webpack-cli@3.1.0<br>\n+webpack-dev-server@3.1.5<br>\n+webpack@4.16.5<br></p>\n</blockquote>\n<p>webpack-cli는 웹팩 명령어 수행을 위한 패키지이고, webpack-dev-server는 스프링부트로 실행한 서버와 연계하기 위한 프록시 서버로 사용된다. 관련된 설명은 잠시 후에 나오니 일단은 넘어가도록 하자.</p>\n<p>웹팩 설치가 완료되었으니 이제 모듈 번들링을 위한 로더들을 설치해야 한다. 로더의 종류는 매우 다양하지만 본문에서는 필자가 생각했을 때, 기본이 된다고 생각하는 것들만 다룰 것이다.</p>\n<ul>\n<li class=\"\">babel-loader : 자바스크립트 모듈 번들링을 위한 로더이며, 보통 ES6 코드를 ES5로 변환하기 위해 사용한다.</li>\n<li class=\"\">css-loader : 모듈 번들링은 자바스크립트 기반으로 이뤄지기 때문에 CSS 파일을 자바스크립트로 변환하기 위해 사용한다.</li>\n<li class=\"\">style-loader : css-loader에 의해 모듈화 되고, 모듈화 된 스타일 코드를 HTML 문서의 STYLE 태그 안에 넣어주기 위해 사용된다.</li>\n<li class=\"\">url-loader : 스타일에 설정된 이미지나 글꼴 파일을 문자열 형태의 데이터(Base64)로 변환하여 해당 CSS 파일 안에 포함시켜버리기 때문에 정적 파일을 관리하기 쉬워진다. 하지만 실제 파일들보다 용량이 커지고, CSS 파일이 무거워지므로 적당히 사용하는 것을 권장한다.</li>\n<li class=\"\">file-loader : 정적 파일을 로드하는데 사용되며, 보통 프로젝트 환경에 맞게 특정 디렉토리에 파일을 복사하는 역할을 수행한다.</li>\n</ul>\n<p>참고로 바벨은 프리셋을 함께 설치해줘야 한다. 관련해서 설명할 내용이 많지만 본문의 주제에서 벗어나니 보편적으로 사용되는 것을 선택했다.</p>\n<blockquote>\n<p>npm install — save-dev babel-core babel-loader babel-preset-env css-loader style-loader url-loader file-loader</p>\n</blockquote>\n<p>마지막으로 웹팩 실행을 위한 NPM 스크립트를 추가해보자. package.json의 최종 모습은 다음과 같을 것이다. 특이한건 env 변수인데, 웹팩 설정 파일 내에서 개발/배포 모드를 구분하기 위함이다.</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"name\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"frontend\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"version\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"1.0.0\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"description\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"main\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"src/main/client/index.js\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"scripts\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"prod\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"webpack --env=production\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"dev\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"webpack-dev-server --env=development\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"start\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"npm run dev\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"author\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"license\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"ISC\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token property\" style=\"color:#36acaa\">\"devDependencies\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"babel-core\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^6.26.3\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"babel-loader\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^7.1.5\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"babel-preset-env\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^1.7.0\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"css-loader\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^1.0.0\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"file-loader\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^1.1.11\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"style-loader\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^0.22.1\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"url-loader\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^1.0.1\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"webpack\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^4.16.5\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"webpack-cli\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^3.1.0\"</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">\"webpack-dev-server\"</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">\"^3.1.5\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>나중에 자세히 설명하겠지만, 일단 NPM 스크립트를 기억하고 있자.</p>\n<blockquote>\n<p>개발할 때, npm run dev 또는 npm start<br>\n배포할 때, npm run prod</p>\n</blockquote>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"3-스프링부트-컨트롤러-만들기\">(3) 스프링부트 컨트롤러 만들기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#3-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%EB%A7%8C%EB%93%A4%EA%B8%B0\" class=\"hash-link\" aria-label=\"(3) 스프링부트 컨트롤러 만들기에 대한 직접 링크\" title=\"(3) 스프링부트 컨트롤러 만들기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>갑자기 스프링부트로 바뀌어서 당혹스럽겠지만 웹팩 설정을 하기에 앞서 간단하게 컨트롤러와 뷰를 만들어보자.</p>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">package com.example.frontend;</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">import org.springframework.stereotype.Controller;</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">import org.springframework.ui.Model;</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">import org.springframework.web.bind.annotation.RequestMapping;</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">@Controller</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">public class FrontendController {</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    @RequestMapping(\"/hello\")</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    public String home(Model model){</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        model.addAttribute(\"message\", \"Hello, World!!!\");</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        return \"index\";</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    }</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">}</span><br></div></code></pre></div></div>\n<p>다음은 홈 컨트롤러에서 받은 메시지 텍스트를 출력하는 템플릿 코드이다. 여기서 index.js를 로드하는데, 스프링부트는 src/main/resources/static 디렉토리를 정적 리소스 루트로 설정하기 때문에 index.js 파일은 여기에 두어야 한다.\n물론 해당 디렉토리는 개발자 임의로 변경할 수도 있다.</p>\n<div class=\"language-html codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-html codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token doctype punctuation\" style=\"color:#393A34;font-style:italic\">&lt;!</span><span class=\"token doctype doctype-tag\" style=\"color:#999988;font-style:italic\">DOCTYPE</span><span class=\"token doctype\" style=\"color:#999988;font-style:italic\"> </span><span class=\"token doctype name\" style=\"color:#999988;font-style:italic\">html</span><span class=\"token doctype punctuation\" style=\"color:#393A34;font-style:italic\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">html</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">xmlns:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">th</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">http://www.thymeleaf.org</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">meta</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">charset</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">utf-8</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/javascript</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/index.js</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/index.js}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token script\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">body</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">strong</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">text</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">${message}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">strong</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">body</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">html</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><br></div></code></pre></div></div>\n<p>스프링부트를 실행하고, <a href=\"http://127.0.0.1:8080/hello%EC%9C%BC%EB%A1%9C\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8080/hello으로</a> 이동하면 “Hello, World!!!” 메시지가 HTML 문서에 출력되고, 경고창에 “onload!!” 메시지가 보일 것이다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token dom variable\" style=\"color:#36acaa\">window</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">onload</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"onload!!\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"4-웹팩-기본-설정하기\">(4) 웹팩 기본 설정하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#4-%EC%9B%B9%ED%8C%A9-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(4) 웹팩 기본 설정하기에 대한 직접 링크\" title=\"(4) 웹팩 기본 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>웹팩은 진입점이라고 할 수 있는 엔트리 js 파일을 설정해야 한다. 엔트리 js 파일을 통해 각각의 모듈들을 로딩하고, 하나의 아웃풋 파일로 묶어(bundle)준다. 웹팩 개발 서버(webpack-dev-server)는 코드의 변경을 감지할 때마다 다시 번들링을 한다. 또한 아웃풋 파일이 적용된 화면을 실시간 리로딩(Live Reloading)하는 inline 옵션과 부분 모듈 리로딩(Hot Module Reloading)하는 hot 옵션을 제공한다.</p>\n<p>앞에서 개발한 스프링부트 뷰에서 사용하기 위해서는 아웃풋 파일이 최종적으로 src/main/resources/static 디렉토리에 위치해야 한다. 하지만 클라이언트 코드를 수정할 때마다 static 디렉토리에 아웃풋 파일이 반영되면 스프링부트 핫스왑 기능이 활성화 되어 불필요한 스프링 컨텍스트 리로드가 발생할 수 있다.</p>\n<p>그래서 필자는 클라이언트 아웃풋 파일을 별도의 디렉토리에 생성하게 하고, 해당 디렉토리를 웹팩 개발 서버의 루트(contentBase)로 설정할 것이다. 그렇다면 이미 실행 중인 스프링부트와 연계는 어떻게 할 수 있을까? 일단 웹팩 설정 파일부터 살펴보자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> path </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'path'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'out'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">mode</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">!</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'development'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> env</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">entry</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">index</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/index.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">output</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>일단 env 변수는 NPM 명령어 실행시 넘겨주는 값이다. 웹팩4부터는 mode에 development 또는 production을 명시해야 한다. 일단 배포 환경 구성은 현재 다루지 않으니 이 부분은 넘어가도록 하겠다.</p>\n<p>앞에서 생성한 스프링부트 프로젝트에서 클라이언트 개발 코드는 src/main/client 디렉토리에서 관리하기로 하고, 해당 디렉토리에 있는 index.js 파일을 엔트리 js 파일로 설정했다. 그리고 아웃풋 파일의 생성 디렉토리는 src/main/resources/static이 아닌 out으로 설정했다. 참고로 output.filename 옵션 값이 [name].js인데, 여기서 [name]은 entry 옵션의 key 이름으로 치환된다. 이 밖에도 [id], [hash] 같은 치환 문자열이 있다.</p>\n<p>다음은 웹팩 개발 서버 설정이다. 먼저 devServer.contentBase 옵션 값은 아웃풋 파일들이 생성되는 디렉토리와 맞춰야 하기 때문에 output.path와 동일하게 설정해야 한다. devServer.port는 스프링부트 포트와 다른 값을 설정하면 된다. 마지막으로 웹팩 개발 서버와 스프링부트를 연계하기 위해 devServer.proxy 옵션을 사용한다. key는 요청 URL이고, value는 프록시 대상이다.</p>\n<p><a href=\"http://127.0.0.1:8081/hello%EB%A1%9C\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8081/hello로</a> 접근하면 스프링부트 컨트롤러에서 넘긴 값으로 구현된 뷰에서 웹팩 개발 서버의 contentBase 옵션에 설정된 디렉토리 안에 있는 정적 파일들을 로드할 수 있게 된다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">devServer</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">contentBase</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">publicPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">host</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'0.0.0.0'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">port</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">8081</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">proxy</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:#36acaa\">'**'</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'http://127.0.0.1:8080'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">inline</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">hot</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">false</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>간단하게 프록시 설정이 잘되어 있는지 확인하기 위해 src/main/client 디렉토리에 index.js 파일을 추가하자. 아까 만든 index.js와 차이를 두기 위해 메시지를 “proxy onload!!”로 변경했다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token dom variable\" style=\"color:#36acaa\">window</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">onload</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">alert</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"proxy onload!!\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>그럼, 스프링부트와 웹팩 개발 서버를 실행해보자.</p>\n<div class=\"language-shell codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-shell codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">npm start</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">webpack-dev-server — env=development</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">ℹ ｢wds｣: Project is running at http://0.0.0.0:8081/</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">ℹ ｢wds｣: webpack output is served from /</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">ℹ ｢wds｣: Content not from webpack is served from /Users/alvin/Documents/Workspace/springboot/frontend/out</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">ℹ ｢wdm｣: Hash: 5d0bf01db3a4b9a400bf</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Version: webpack 4.16.5</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Time: 395ms</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Built at: 08/16/2018 7:25:02 PM</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Asset Size Chunks Chunk Names</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">index.js 338 KiB index [emitted] index</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Entrypoint index = index.js</span><br></div></code></pre></div></div>\n<p><a href=\"http://127.0.0.1:8080/hello%EB%A1%9C\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8080/hello로</a> 접속하면 경고창에 “onload!!” 메시지가 보일 것이고, <a href=\"http://127.0.0.1:8081/hello%EB%A1%9C\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8081/hello로</a> 접속해서 “proxy onload!!” 메시지가 보인다면 웹팩 기본 설정이 잘 완료된 것이다.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"5-웹팩-로더-설정하기\">(5) 웹팩 로더 설정하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#5-%EC%9B%B9%ED%8C%A9-%EB%A1%9C%EB%8D%94-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(5) 웹팩 로더 설정하기에 대한 직접 링크\" title=\"(5) 웹팩 로더 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>앞에서 엔트리와 아웃풋을 설정했다. 현재 설정으로는 오직 js 파일만 번들링 할 수 있다. 하지만 클라이언트 개발은 css 파일이나 이미지 파일들도 필요하기 때문에 관련된 웹팩 로더를 추가해줘야 한다.</p>\n<p>참고로 css 파일은 로드하더라도 js 파일로 번들링 되기 때문에 관련 플러그인을 추가로 설치하여 css 파일만 따로 분리할 것이다.</p>\n<blockquote>\n<p>npm install — save-dev mini-css-extract-plugin</p>\n</blockquote>\n<p>앞에서 style-loader에 대한 설명을 했는데, 본문에서는 다루지 않을 것이다. 개발 뿐만이 아니라 배포까지 생각하면 STYLE 태그에 스타일 코드가 들어가는 것보단 하나의 css 파일로 번들링되는 것이 바람직하다고 생각한다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> path </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'path'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MiniCssExtractPlugin</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'mini-css-extract-plugin'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\">\tmodule</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'out'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">module</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">rules</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">js</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'babel-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">presets</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'env'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">css</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MiniCssExtractPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">loader</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'css-loader'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">plugins</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">MiniCssExtractPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].css'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>웹팩 설정 파일에 추가된 module 옵션을 살펴보면 babel-loader를 통해 ES6 코드를 ES5로 변환할 수 있다. style-loader는 방금 설치한 MiniCssExtractPlugin.loader로 변경되었고, 엔트리 js 파일에서 css 파일을 로드하기 위해 css-loader도 함께 사용되었다.</p>\n<p>여기서 중요한 점은 plugins 옵션에 MiniCssExtractPlugin 객체가 추가되었다는 사실이다. 번들링 된 css 파일은 기존의 아웃풋 파일과 같은 디렉토리에 위치해야하므로 path 옵션 값은 output.path와 동일하다. 그리고 css 파일 이름은 entry 옵션에 설정된 key 이름으로 치환된다.</p>\n<p>이제 js 파일 뿐만이 아니라 css 파일까지 번들링 할 수 있게 되었는데, 뭔가 부족하다. 스타일에서 이미지를 사용하고 싶을 때는 어떻게 해야할까?</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"이미지-파일-사용하기\">이미지 파일 사용하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8C%8C%EC%9D%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"이미지 파일 사용하기에 대한 직접 링크\" title=\"이미지 파일 사용하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>답은 바로 url-loader와 file-loader를 사용하는 것이다. 필자는 정적 파일 관리가 귀찮아서 url-loader를 선호하는 편인데, 아무래도 번들링 된 css 파일이 엄청 커질 수 있기 때문에 크기가 작은 이미지만 사용하는게 좋다.</p>\n<p>본문에서는 두가지 로더를 모두 테스트해보기 위해 svg 파일은 file-loader를 사용하고, 나머지 이미지 파일은 url-loader를 사용하였다. 단순히 테스트 용도이므로 취향에 맞게 알아서 고쳐서 사용하면 된다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">module</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">rules</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">jpe</span><span class=\"token regex regex-source language-regex quantifier number\" style=\"color:#36acaa\">?</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">g</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">png</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">gif</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'url-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">limit</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1024</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 10kb</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">svg</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'file-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].[ext]'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">outputPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'images/'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<p>두개의 로더를 추가했다. 먼저 url-loader는 10KB 미만의 jpg, png, gif 파일을 문자열 형태의 데이터(Base64)로 변환한다. 그리고 svg 파일만 file-loader에서 가져오게 되는데, outputPath 옵션을 통해 가져온 svg 파일의 디렉토리를 설정한다. svg 파일 이름이 webpack.svg라면 <a href=\"http://127.0.0.1:8081/images/webpack.svg\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://127.0.0.1:8081/images/webpack.svg</a> 경로로 화면에 로드된다.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"프로젝트-코드-수정하기\">프로젝트 코드 수정하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%88%98%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"프로젝트 코드 수정하기에 대한 직접 링크\" title=\"프로젝트 코드 수정하기에 대한 직접 링크\" translate=\"no\">​</a></h3>\n<p>이제 웹팩 로더 설정도 끝났겠다. 앞에서 말한 내용들을 테스트해보기 위해 index.css와 index.html 파일을 수정해보자.</p>\n<div class=\"language-css codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-css codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token selector\" style=\"color:#00009f\">strong</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">color</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token color\">red</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token selector class\" style=\"color:#00009f\">.pattern</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">width</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">300</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">height</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">64</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">display</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> inline-block</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">background-image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token url function\" style=\"color:#d73a49\">url</span><span class=\"token url punctuation\" style=\"color:#393A34\">(</span><span class=\"token url string url\" style=\"color:#36acaa\">\"./images/globe.png\"</span><span class=\"token url punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">background-repeat</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> repeat-x</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token selector class\" style=\"color:#00009f\">.image</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">width</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">300</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">height</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">300</span><span class=\"token unit\">px</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">display</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> inline-block</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token property\" style=\"color:#36acaa\">background-image</span><span class=\"token punctuation\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token url function\" style=\"color:#d73a49\">url</span><span class=\"token url punctuation\" style=\"color:#393A34\">(</span><span class=\"token url string url\" style=\"color:#36acaa\">\"./images/webpack.svg\"</span><span class=\"token url punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<div class=\"language-html codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-html codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token doctype punctuation\" style=\"color:#393A34;font-style:italic\">&lt;!</span><span class=\"token doctype doctype-tag\" style=\"color:#999988;font-style:italic\">DOCTYPE</span><span class=\"token doctype\" style=\"color:#999988;font-style:italic\"> </span><span class=\"token doctype name\" style=\"color:#999988;font-style:italic\">html</span><span class=\"token doctype punctuation\" style=\"color:#393A34;font-style:italic\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">html</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">xmlns:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">th</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">http://www.thymeleaf.org</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">meta</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">charset</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">utf-8</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/javascript</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/index.js</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/index.js}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token script\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">link</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">rel</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">stylesheet</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/css</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">media</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">all</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">href</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/index.css</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">href</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/index.css}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">body</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">default</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">strong</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">text</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">${message}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">strong</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">br</span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">url-loader</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">class</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">pattern</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">br</span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\">file-loader</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">h1</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">class</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">image</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">div</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">body</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">html</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"6-청크chunk-관리하기\">(6) 청크(chunk) 관리하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#6-%EC%B2%AD%ED%81%ACchunk-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(6) 청크(chunk) 관리하기에 대한 직접 링크\" title=\"(6) 청크(chunk) 관리하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>클라이언트 개발을 하다보면 다양한 라이브러리들을 사용하게 된다. 현재 웹팩 설정으로 번들링하게 되면 아웃풋 파일의 크기가 엄청 커질 것이고, 초기 로딩 속도에도 악영향을 미칠 것이다. 그럼, 지금부터 아웃풋 파일을 현재 개발 중인 코드와 라이브러리로 분리해보자.</p>\n<blockquote>\n<p>npm install — save jquery moment</p>\n</blockquote>\n<p>테스트를 위해 jquery와 moment 라이브러리를 설치했다. 그리고 jquery와 moment를 사용하여 onload 시점에 현재 시간을 출력해주는 코드를 추가했다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports maybe-class-name\">Styles</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'./index.css'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports\">$</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword module\" style=\"color:#00009f\">import</span><span class=\"token plain\"> </span><span class=\"token imports\">moment</span><span class=\"token plain\"> </span><span class=\"token keyword module\" style=\"color:#00009f\">from</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token keyword\" style=\"color:#00009f\">function</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token function\" style=\"color:#d73a49\">$</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">\"strong &gt; div\"</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">html</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token function\" style=\"color:#d73a49\">moment</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">format</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><br></div></code></pre></div></div>\n<p>코드를 분리하지 않으면 다음과 같이 아웃풋 파일의 용량이 매우 커진다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/6-bad8f4e0c81e852d9e611c51b6ae5fb3.webp\" width=\"1400\" height=\"875\" class=\"img_ev3q\"></p>\n<p>그럼, 다시 웹팩 설정 파일을 수정해보자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">entry</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">vendors</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">index</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/index.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">output</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">optimization</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">splitChunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">chunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'all'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">cacheGroups</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">vendors</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">[</span><span class=\"token regex regex-source language-regex char-class special-escape escape\" style=\"color:#36acaa\">\\\\</span><span class=\"token regex regex-source language-regex char-class\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">]</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">node_modules</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">[</span><span class=\"token regex regex-source language-regex char-class special-escape escape\" style=\"color:#36acaa\">\\\\</span><span class=\"token regex regex-source language-regex char-class\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">]</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'vendors'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><br></div></code></pre></div></div>\n<p>entry 옵션에 vendors가 추가된 것을 확인할 수 있다. index와 달리 문자열 배열 값이 들어있는데, 실제로 사용한 라이브러리 이름을 명시하면 된다. 다음은 optimization.splitChunks 옵션이다. 여기서 중요한건 청크 대상을 node_modules 디렉토리 내로 제한한 것이다.</p>\n<p>청크 방법은 너무 다양해서 별도의 주제로 다루는 것이 좋을 것 같으니 본문에서는 이 정도로 설명을 마치겠다. 그리고 아웃풋 파일이 하나 더 생겼으니 index.html 파일도 변경하도록 하자.</p>\n<div class=\"language-html codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-html codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">meta</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">charset</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">utf-8</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/javascript</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/vendors.js</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/vendors.js}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token script\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/javascript</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/index.js</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">src</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/index.js}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token script\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">script</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;</span><span class=\"token tag\" style=\"color:#00009f\">link</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">rel</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">stylesheet</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">type</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">text/css</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">media</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">all</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name\" style=\"color:#00a4db\">href</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">/index.css</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag attr-name namespace\" style=\"color:#00a4db;opacity:0.7\">th:</span><span class=\"token tag attr-name\" style=\"color:#00a4db\">href</span><span class=\"token tag attr-value punctuation attr-equals\" style=\"color:#393A34\">=</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag attr-value\" style=\"color:#e3116c\">@{/index.css}</span><span class=\"token tag attr-value punctuation\" style=\"color:#393A34\">\"</span><span class=\"token tag\" style=\"color:#00009f\"> </span><span class=\"token tag punctuation\" style=\"color:#393A34\">/&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token tag punctuation\" style=\"color:#393A34\">&lt;/</span><span class=\"token tag\" style=\"color:#00009f\">head</span><span class=\"token tag punctuation\" style=\"color:#393A34\">&gt;</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"7-배포-환경-설정하기\">(7) 배포 환경 설정하기<a href=\"https://alvin.ing/blog/webpack-springboot-starter#7-%EB%B0%B0%ED%8F%AC-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0\" class=\"hash-link\" aria-label=\"(7) 배포 환경 설정하기에 대한 직접 링크\" title=\"(7) 배포 환경 설정하기에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>그동안 번들링 된 아웃풋 파일들을 웹팩 개발 서버의 contentBase 디렉토리에 두고 프록시를 통해 스프링부트 뷰에서 로드했었다. 배포 시점이 되면 아웃풋 파일들을 스프링부트의 정적 리소스 루트 디렉토리로 옮겨야 한다.</p>\n<p>배포를 위한 빌드 설정은 매우 간단하다. 웹팩 설정 파일에서 처음 정의한 outputPath 변수 값을 스프링부트의 정적 리소스 루트 디렉토리로 설정하면 된다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// Before</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'out'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// After</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'production'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/resources/static'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'out'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><br></div></code></pre></div></div>\n<p>수정이 완료되었으면 다음과 같이 NPM 스크립트를 실행한다.</p>\n<div class=\"language-shell codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-shell codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">npm run prod</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">&gt; frontend@1.0.0 prod /Users/alvin/Documents/Workspace/springboot/frontend</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">&gt; webpack — env=production</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Hash: 8d360cf3a938a8cf0cf7</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Version: webpack 4.16.5</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Time: 7262ms</span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">Built at: 08/17/2018 1:39:52 AM</span><br></div></code></pre></div></div>\n<p>이제는 스프링부트만 실행해도 클라이언트 코드가 잘 동작하는 것을 확인할 수 있을 것이다. 하지만 아직 뭔가 부족하다. 아무래도 배포되는 파일인데, 최적화를 해야할 것 같다.</p>\n<p>웹팩4에서 기본으로 배포되고 있는 uglify-webpack-plugin과 optimize-css-assets-webpack-plugin을 추가로 설치하여 배포 시점의 아웃풋 파일들을 최적화 해보자.</p>\n<blockquote>\n<p>npm install — save-dev optimize-css-assets-webpack-plugin</p>\n</blockquote>\n<p>드디어 마지막 단계이다. 배포 모드일 때, optimization.minimizer 옵션에 두 플러그인의 객체를 추가해주면 모든 웹팩 설정이 끝이난다.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> path </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'path'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MiniCssExtractPlugin</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'mini-css-extract-plugin'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">UglifyJsPlugin</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'uglifyjs-webpack-plugin'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">OptimizeCssAssetsPlugin</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'optimize-css-assets-webpack-plugin'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/client'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:#00009f\">let</span><span class=\"token plain\"> outputPath </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> path</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method function property-access\" style=\"color:#d73a49\">resolve</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">__dirname</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'production'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'src/main/resources/static'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'out'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">mode</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">!</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'development'</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> env</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">entry</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">vendors</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'jquery'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'moment'</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">index</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> clientPath </span><span class=\"token operator\" style=\"color:#393A34\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/index.js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">output</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].js'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">optimization</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">splitChunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">chunks</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'all'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">cacheGroups</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">vendors</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">[</span><span class=\"token regex regex-source language-regex char-class special-escape escape\" style=\"color:#36acaa\">\\\\</span><span class=\"token regex regex-source language-regex char-class\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">]</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">node_modules</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">[</span><span class=\"token regex regex-source language-regex char-class special-escape escape\" style=\"color:#36acaa\">\\\\</span><span class=\"token regex regex-source language-regex char-class\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex char-class char-class-punctuation punctuation\" style=\"color:#393A34\">]</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'vendors'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">minimizer</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token plain\">env </span><span class=\"token operator\" style=\"color:#393A34\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'production'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">?</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">UglifyJsPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">OptimizeCssAssetsPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">devServer</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">contentBase</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">publicPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'/'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">host</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'0.0.0.0'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">port</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">8081</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">proxy</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token string-property property\" style=\"color:#36acaa\">'**'</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'http://127.0.0.1:8080'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">inline</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">true</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">hot</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:#36acaa\">false</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">module</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token literal-property property\" style=\"color:#36acaa\">rules</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">js</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'babel-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">presets</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'env'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">css</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">MiniCssExtractPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access\">loader</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'css-loader'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">jpe</span><span class=\"token regex regex-source language-regex quantifier number\" style=\"color:#36acaa\">?</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">g</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">png</span><span class=\"token regex regex-source language-regex alternation keyword\" style=\"color:#00009f\">|</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">gif</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'url-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">limit</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">1024</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">*</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:#36acaa\">10</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:#999988;font-style:italic\">// 10kb</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">test</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-source language-regex special-escape escape\" style=\"color:#36acaa\">\\.</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">(</span><span class=\"token regex regex-source language-regex\" style=\"color:#36acaa\">svg</span><span class=\"token regex regex-source language-regex group punctuation\" style=\"color:#393A34\">)</span><span class=\"token regex regex-source language-regex anchor function\" style=\"color:#d73a49\">$</span><span class=\"token regex regex-delimiter\" style=\"color:#36acaa\">/</span><span class=\"token regex regex-flags\" style=\"color:#36acaa\">i</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">use</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">loader</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'file-loader'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token literal-property property\" style=\"color:#36acaa\">options</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">name</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].[ext]'</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">outputPath</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'images/'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">plugins</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">MiniCssExtractPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">path</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> outputPath</span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">                </span><span class=\"token literal-property property\" style=\"color:#36acaa\">filename</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:#e3116c\">'[name].css'</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"8-보너스\">(8) 보너스<a href=\"https://alvin.ing/blog/webpack-springboot-starter#8-%EB%B3%B4%EB%84%88%EC%8A%A4\" class=\"hash-link\" aria-label=\"(8) 보너스에 대한 직접 링크\" title=\"(8) 보너스에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>이렇게 강좌가 끝나면 아쉬워할것 같아서 개발할 때, 도움이 될 만한 플러그인을 추가로 소개할까한다. js 파일들이 하나의 아웃풋 파일로 번들링 될 때, 내부 구조가 궁금할 수 있다. 또한 청크 설정이 잘못되어 생각했던 것과 다르게 파일이 분리되는 경우도 있다.</p>\n<blockquote>\n<p>npm install — save-dev webpack-bundle-analyzer</p>\n</blockquote>\n<p>플러그인을 설치하고, 다음과 같이 웹팩 설정 파일을 수정하자.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#393A34;--prism-background-color:#f6f8fa\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#393A34;background-color:#f6f8fa\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:#00009f\">const</span><span class=\"token plain\"> </span><span class=\"token maybe-class-name\">BundleAnalyzerPlugin</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:#d73a49\">require</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token string\" style=\"color:#e3116c\">'webpack-bundle-analyzer'</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token property-access maybe-class-name\">BundleAnalyzerPlugin</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">module</span><span class=\"token punctuation\" style=\"color:#393A34\">.</span><span class=\"token method-variable function-variable method function property-access\" style=\"color:#d73a49\">exports</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:#393A34\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token parameter\">env</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:#393A34\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"color:#00009f\">return</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token literal-property property\" style=\"color:#36acaa\">plugins</span><span class=\"token operator\" style=\"color:#393A34\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:#393A34\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token spread operator\" style=\"color:#393A34\">...</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:#393A34\">,</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:#00009f\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\">BundleAnalyzerPlugin</span><span class=\"token punctuation\" style=\"color:#393A34\">(</span><span class=\"token punctuation\" style=\"color:#393A34\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:#393A34\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#393A34\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:#393A34\">}</span><br></div></code></pre></div></div>\n<p>웹팩 개발 서버가 실행되면 8888 포트로 웹 페이지가 하나 열리는데, 트리맵 형태로 js 파일들이 보여지며, 파일 용량이 클수록 트리 노드가 넓어진다.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Example banner\" src=\"https://alvin.ing/assets/images/7-1127b86e45d8e3abd46036aebd7bc273.webp\" width=\"1400\" height=\"875\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"9-프로젝트-다운로드\">(9) 프로젝트 다운로드<a href=\"https://alvin.ing/blog/webpack-springboot-starter#9-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C\" class=\"hash-link\" aria-label=\"(9) 프로젝트 다운로드에 대한 직접 링크\" title=\"(9) 프로젝트 다운로드에 대한 직접 링크\" translate=\"no\">​</a></h2>\n<p>본문에서 다룬 내용은 모두 GitHub 저장소에 올려놨으니 바로 테스트 해볼 수 있다. 다음 강좌를 위해서 계속 업데이트할 프로젝트이니 Watch나 Star를 누르면 최신 상태를 업데이트 받을 수 있을 것이다. ㅎㅎ</p>\n<blockquote>\n<p><a href=\"https://github.com/seogi1004/webpack-springboot-starter\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/seogi1004/webpack-springboot-starter</a></p>\n</blockquote>",
            "url": "https://alvin.ing/blog/webpack-springboot-starter",
            "title": "Webpack+SpringBoot 기반의 프론트엔드 개발환경 구축하기",
            "summary": "필자가 회사에서 개발 중인 제니퍼5의 수요가 크게 늘어남에 따라 고객의 기호에 맞게 화면에 대한 커스터마이징을 요구하는 경우가 많아졌다. 하지만 기존의 프로젝트에 커스터마이징 코드를 넣는 것은 바람직하지 않기 때문에 외부에서 구현하고, 플러그인처럼 추가하고 삭제할 수 있는 구조를 고민해야만 했다.",
            "date_modified": "2017-08-17T00:00:00.000Z",
            "author": {
                "name": "Alvin Hong",
                "url": "/about"
            },
            "tags": [
                "개발",
                "Webpack",
                "Spring Boot"
            ]
        }
    ]
}